1 | LIBRARY ieee;
|
2 | USE ieee.std_logic_1164.ALL;
|
3 | USE ieee.numeric_std.ALL;
|
4 | USE std.textio.ALL;
|
5 |
|
6 | LIBRARY work;
|
7 | USE work.MyStuff.ALL;
|
8 |
|
9 | ENTITY testbench IS
|
10 | END testbench;
|
11 |
|
12 | ARCHITECTURE behavior OF testbench IS
|
13 | TYPE CHAR_VECTOR IS ARRAY (NATURAL range <>) OF CHARACTER;
|
14 | TYPE StepData IS RECORD
|
15 | chn_A : INTEGER;
|
16 | chn_B : INTEGER;
|
17 | FRC : INTEGER;
|
18 | END RECORD StepData;
|
19 | TYPE TestData IS ARRAY (NATURAL range <>) OF StepData;
|
20 | CONSTANT MyAdrSize : INTEGER := 20;
|
21 | COMPONENT LTC1407
|
22 | Port ( clk50 : in STD_LOGIC;
|
23 | cs : in STD_LOGIC; -- chip-select: ADC starts with setting cs high
|
24 | frc : in STD_LOGIC; -- free running conversion (high) or single shot (low)
|
25 | sck : out STD_LOGIC;
|
26 | conv : out STD_LOGIC;
|
27 | sdo : in STD_LOGIC;
|
28 | nWE : out STD_LOGIC; -- negated write enable (memory)
|
29 | oChA : out STD_LOGIC_VECTOR (15 downto 0); -- channel A result data from ADC
|
30 | oChB : out STD_LOGIC_VECTOR (15 downto 0); -- channel B result data from ADC
|
31 | oaddr : out STD_LOGIC_VECTOR (19 downto 0)); -- self incrementing memory address in free running mode
|
32 | END COMPONENT;
|
33 | COMPONENT fake_adc is
|
34 | Port ( channel_A : in STD_LOGIC_VECTOR (15 downto 0);
|
35 | channel_B : in STD_LOGIC_VECTOR (15 downto 0);
|
36 | clock : in STD_LOGIC;
|
37 | aConv : in STD_LOGIC; -- trigger to start conversion
|
38 | aData : out STD_LOGIC; -- serial data from ADC
|
39 | sample : out STD_LOGIC);
|
40 | END COMPONENT;
|
41 |
|
42 | -- Inputs
|
43 | SIGNAL ADC_enable : STD_LOGIC := '0';
|
44 | SIGNAL ADC_frc : STD_LOGIC := '0';
|
45 | SIGNAL i_clock : STD_LOGIC := '0';
|
46 | SIGNAL iChA : STD_LOGIC_VECTOR(15 downto 0);
|
47 | SIGNAL iChB : STD_LOGIC_VECTOR(15 downto 0);
|
48 |
|
49 | -- connect
|
50 | SIGNAL ADC_data : STD_LOGIC;
|
51 | SIGNAL ADC_start : STD_LOGIC;
|
52 | SIGNAL ADC_clock : STD_LOGIC;
|
53 | SIGNAL ADC_sample : STD_LOGIC;
|
54 |
|
55 | -- Outputs
|
56 | SIGNAL nWrite : STD_LOGIC := '0';
|
57 | SIGNAL odChA : STD_LOGIC_VECTOR(15 downto 0);
|
58 | SIGNAL odChB : STD_LOGIC_VECTOR(15 downto 0);
|
59 | SIGNAL oAddr : STD_LOGIC_VECTOR((MyAdrSize-1) downto 0);
|
60 |
|
61 | -- Internal
|
62 | SIGNAL doClock : STD_LOGIC := '0';
|
63 | SIGNAL myTestData : TestData(0 to 10) := (others => (others => 13));
|
64 | BEGIN
|
65 | uut: LTC1407 PORT MAP( cs => ADC_enable,
|
66 | frc => ADC_frc,
|
67 | clk50 => i_clock,
|
68 | sdo => ADC_data,
|
69 | sck => ADC_clock,
|
70 | conv => ADC_start,
|
71 | nWE => nWrite,
|
72 | oChA => odChA,
|
73 | oChB => odChB,
|
74 | oAddr => oAddr );
|
75 | adc: fake_adc PORT MAP( channel_A => iChA,
|
76 | channel_B => iChB,
|
77 | clock => ADC_clock,
|
78 | aConv => ADC_start,
|
79 | aData => ADC_data,
|
80 | sample => ADC_sample);
|
81 |
|
82 | clock_generation : PROCESS BEGIN
|
83 | WAIT UNTIL rising_edge(doClock);
|
84 | LOOP
|
85 | i_clock <= NOT i_clock;
|
86 | WAIT FOR 10 ns;
|
87 | END LOOP;
|
88 | END PROCESS;
|
89 |
|
90 | testDat_setup : PROCESS
|
91 | file flTestDat : TEXT open read_mode is "s:\test.dat";
|
92 | VARIABLE row : INTEGER := 0;
|
93 | VARIABLE scratch : LINE;
|
94 | VARIABLE tdChA : INTEGER := 0;
|
95 | VARIABLE tdChB : INTEGER := 0;
|
96 | VARIABLE tdFRC : INTEGER := 1;
|
97 | BEGIN
|
98 | iChA <= (others=>'0');
|
99 | iChB <= (others=>'0');
|
100 | write(scratch, STRING'("start reading test data from file ..."));
|
101 | writeline(output, scratch);
|
102 |
|
103 | WHILE NOT (endfile(flTestDat)) LOOP
|
104 | readline(flTestDat, scratch);
|
105 | parse(scratch, tdChA);
|
106 | parse(scratch, tdChB);
|
107 | parse(scratch, tdFRC);
|
108 |
|
109 | writeline(output, scratch);
|
110 | write(scratch, STRING'("got row #")); write(scratch, row);
|
111 | write(scratch, STRING'(" of test data as ch-A: ")); write(scratch, tdChA);
|
112 | write(scratch, STRING'(", ch-B: ")); write(scratch, tdChB);
|
113 | write(scratch, STRING'(", FRC: ")); write(scratch, tdFRC);
|
114 | writeline(output, scratch);
|
115 |
|
116 | myTestData(row).chn_A <= tdChA;
|
117 | myTestData(row).chn_B <= tdChB;
|
118 | myTestData(row).FRC <= tdFRC;
|
119 | if (row < myTestData'length) then
|
120 | row := row + 1;
|
121 | end if;
|
122 | END LOOP;
|
123 | file_close(flTestDat);
|
124 | write(scratch, STRING'("DONE reading test data!"));
|
125 | writeline(output, scratch);
|
126 |
|
127 | row := 0;
|
128 | ADC_enable <= '0';
|
129 | iChA <= std_logic_vector(to_unsigned(myTestData(row).chn_A, 16));
|
130 | iChB <= std_logic_vector(to_unsigned(myTestData(row).chn_B, 16));
|
131 | if (myTestData(row).FRC = 1) then
|
132 | ADC_frc <= '1';
|
133 | else
|
134 | ADC_frc <= '0';
|
135 | end if;
|
136 | write(scratch, STRING'("activated test data of row #")); write(scratch, row);
|
137 | writeline(output, scratch);
|
138 |
|
139 | WAIT FOR 30 ns;
|
140 |
|
141 | write(scratch, STRING'("test data on lines - A:")); write(scratch, iChA);
|
142 | write(scratch, STRING'(", B:")); write(scratch, iChB);
|
143 | writeline(output, scratch);
|
144 |
|
145 | doClock <= '1'; -- now really start simulation
|
146 | WAIT FOR 25 ns;
|
147 | ADC_enable <= '1';
|
148 |
|
149 | WAIT;
|
150 | END PROCESS;
|
151 |
|
152 | testDat_processing: PROCESS
|
153 | VARIABLE first : boolean := true;
|
154 | VARIABLE row : INTEGER := 1;
|
155 | VARIABLE scratch : LINE;
|
156 | BEGIN
|
157 | WAIT UNTIL falling_edge(ADC_start);
|
158 | WAIT UNTIL rising_edge(i_clock);
|
159 |
|
160 | iChA <= std_logic_vector(to_unsigned(myTestData(row).chn_A, 16));
|
161 | iChB <= std_logic_vector(to_unsigned(myTestData(row).chn_B, 16));
|
162 | if (myTestData(row).FRC = 1) then
|
163 | ADC_frc <= '1';
|
164 | else
|
165 | ADC_frc <= '0';
|
166 | end if;
|
167 | write(scratch, STRING'("activated test data of row #")); write(scratch, row);
|
168 | writeline(output, scratch);
|
169 |
|
170 | write(scratch, STRING'("test data should be - A:")); write(scratch, std_logic_vector(to_unsigned(myTestData(row).chn_A, 16)));
|
171 | write(scratch, STRING'(", B:")); write(scratch, std_logic_vector(to_unsigned(myTestData(row).chn_B, 16)));
|
172 | writeline(output, scratch);
|
173 | write(scratch, STRING'("test data on lines - A:")); write(scratch, iChA);
|
174 | write(scratch, STRING'(", B:")); write(scratch, iChB);
|
175 | writeline(output, scratch);
|
176 |
|
177 | if (row < myTestData'length) then row := row + 1; else WAIT; end if;
|
178 | END PROCESS;
|
179 |
|
180 |
|
181 | tell_Data: PROCESS
|
182 | VARIABLE scratch : LINE;
|
183 | BEGIN
|
184 | WAIT UNTIL rising_edge(nWrite);
|
185 |
|
186 | write(scratch, STRING'(" >>> wrote channel-A with: "));
|
187 | write(scratch, to_integer(unsigned(odChA)));
|
188 | write(scratch, STRING'(", channel-B with: "));
|
189 | write(scratch, to_integer(unsigned(odChB)));
|
190 | write(scratch, STRING'(", to address: "));
|
191 | write(scratch, to_integer(unsigned(oaddr)));
|
192 | writeline(output, scratch);
|
193 | END PROCESS;
|
194 | END;
|