Hi everyone, I'm writing a code to simulate a 12-bit dac. The behavior is quite simple: A serial digital input receive datas ( 32-bits word with the 12 bits to convert + don't care bits + command) and the 12 bits word is converted every 32 clk. My first try was to create a signal data_input: std_logic_vector (31 downto 0) and convert only the 12 bits I want. But this not exactly the right thing. I thought a clk counter is necessary and others things but can't find out... Can you give me some advice to get over it please?
Basically you will need two clocks since the left side domain is totally analog and independent from the sampling domain. Practically you will work with ps resoultion in order to feed your DAC with data. Furthermore you will need a kind of anti aliasing filter for the incoming data stream to simulate aliasing which will occur in reality. Next steps are non linearity and noise.
angelo wrote: > I'm writing a code to simulate a 12-bit dac. > ... > and the 12 bits word is converted every 32 clk. Into what? > signal data_input: std_logic_vector (31 downto 0) a 32-bit input doesn't match > A serial digital input What input do you have? What output do you need? What is the actual problem?
I wrote this code in a first time:
1 | library IEEE; |
2 | use IEEE.std_logic_1164.all; |
3 | use ieee.numeric_std.all; |
4 | |
5 | entity dac is |
6 | |
7 | generic (data_width : integer; |
8 | SDI_width : integer |
9 | --REF : real
|
10 | );
|
11 | |
12 | port( REF : in real; |
13 | SDI : in std_logic_vector (SDI_width - 1 downto 0); |
14 | SDO : out std_logic_vector(SDI_width - 1 downto 0); |
15 | SCK : in std_logic; |
16 | CLR : in std_logic; -- low level active |
17 | CS_LD : in std_logic; -- '0': CS / '1': LD |
18 | LDAC : in std_logic; -- low level active (always '1' here) |
19 | Vout : out real |
20 | );
|
21 | |
22 | end dac; |
23 | |
24 | architecture archi of dac is |
25 | |
26 | signal data : std_logic_vector(11 downto 0); |
27 | signal data_real : real; |
28 | |
29 | begin
|
30 | |
31 | data <= SDI(15 downto 4); |
32 | |
33 | P1: process(SCK, data) |
34 | |
35 | constant Tclk : time := 10 ns; |
36 | |
37 | begin
|
38 | |
39 | data_real <= (real(to_integer(signed(data)))); |
40 | |
41 | SDO <= transport SDI after Tclk*32; |
42 | |
43 | if (CLR = '0' or CS_LD = '0') then |
44 | |
45 | Vout <= 0.0; |
46 | |
47 | elsif (SCK'event and SCK = '1') then |
48 | |
49 | Vout <= data_real/(2.0**data_width) * REF; |
50 | |
51 | end if; |
52 | |
53 | end process; |
54 | |
55 | end archi; |
The problem is I have to connect the signal SDI to an 1 bit signal. Which is not possible if SDI is a std_logic_vector.
:
Edited by Moderator
angelo wrote: > Which is not possible if SDI is a std_logic_vector. SDI is not a vector at all! It is a simple 1 bit std_logic input. And together with LD it is very clear what has to happen here: 1. LD is set to '0' 2. with SCLK bits from SDI are shifted into a 32 bit register in the DAC 3. with LD set to '1' the register is evaluated So it may look like this:
1 | SDI : in std_logic; |
2 | ...
|
3 | SCK : in std_logic; |
4 | ...
|
5 | CS_LD : in std_logic; -- '0': CS / '1': LD |
6 | |
7 | :
|
8 | :
|
9 | |
10 | signal inreg : std_logic_vector (31 downto 0); |
11 | |
12 | :
|
13 | :
|
14 | |
15 | inreg <= inreg(30 downto 0) & SDI when rising_edge(SCLK) and CS = '0'; -- shift data in, assuming MSB first |
16 | data <= inreg(15 downto 4) when rising_edge(CS_LD); -- transfer interesting part of vector to analog processing |
Got the idea?
:
Edited by Moderator
Please log in before posting. Registration is free and takes only a minute.
Existing account
Do you have a Google/GoogleMail account? No registration required!
Log in with Google account
Log in with Google account
No account? Register here.