LIBRARY ieee; USE ieee.std_logic_1164.ALL; USE ieee.numeric_std.ALL; USE std.textio.ALL; LIBRARY work; USE work.MyStuff.ALL; ENTITY testbench IS END testbench; ARCHITECTURE behavior OF testbench IS TYPE CHAR_VECTOR IS ARRAY (NATURAL range <>) OF CHARACTER; TYPE StepData IS RECORD chn_A : INTEGER; chn_B : INTEGER; FRC : INTEGER; END RECORD StepData; TYPE TestData IS ARRAY (NATURAL range <>) OF StepData; CONSTANT MyAdrSize : INTEGER := 20; COMPONENT LTC1407 Port ( clk50 : in STD_LOGIC; cs : in STD_LOGIC; -- chip-select: ADC starts with setting cs high frc : in STD_LOGIC; -- free running conversion (high) or single shot (low) sck : out STD_LOGIC; conv : out STD_LOGIC; sdo : in STD_LOGIC; nWE : out STD_LOGIC; -- negated write enable (memory) oChA : out STD_LOGIC_VECTOR (15 downto 0); -- channel A result data from ADC oChB : out STD_LOGIC_VECTOR (15 downto 0); -- channel B result data from ADC oaddr : out STD_LOGIC_VECTOR (19 downto 0)); -- self incrementing memory address in free running mode END COMPONENT; COMPONENT fake_adc is Port ( channel_A : in STD_LOGIC_VECTOR (15 downto 0); channel_B : in STD_LOGIC_VECTOR (15 downto 0); clock : in STD_LOGIC; aConv : in STD_LOGIC; -- trigger to start conversion aData : out STD_LOGIC; -- serial data from ADC sample : out STD_LOGIC); END COMPONENT; -- Inputs SIGNAL ADC_enable : STD_LOGIC := '0'; SIGNAL ADC_frc : STD_LOGIC := '0'; SIGNAL i_clock : STD_LOGIC := '0'; SIGNAL iChA : STD_LOGIC_VECTOR(15 downto 0); SIGNAL iChB : STD_LOGIC_VECTOR(15 downto 0); -- connect SIGNAL ADC_data : STD_LOGIC; SIGNAL ADC_start : STD_LOGIC; SIGNAL ADC_clock : STD_LOGIC; SIGNAL ADC_sample : STD_LOGIC; -- Outputs SIGNAL nWrite : STD_LOGIC := '0'; SIGNAL odChA : STD_LOGIC_VECTOR(15 downto 0); SIGNAL odChB : STD_LOGIC_VECTOR(15 downto 0); SIGNAL oAddr : STD_LOGIC_VECTOR((MyAdrSize-1) downto 0); -- Internal SIGNAL doClock : STD_LOGIC := '0'; SIGNAL myTestData : TestData(0 to 10) := (others => (others => 13)); BEGIN uut: LTC1407 PORT MAP( cs => ADC_enable, frc => ADC_frc, clk50 => i_clock, sdo => ADC_data, sck => ADC_clock, conv => ADC_start, nWE => nWrite, oChA => odChA, oChB => odChB, oAddr => oAddr ); adc: fake_adc PORT MAP( channel_A => iChA, channel_B => iChB, clock => ADC_clock, aConv => ADC_start, aData => ADC_data, sample => ADC_sample); clock_generation : PROCESS BEGIN WAIT UNTIL rising_edge(doClock); LOOP i_clock <= NOT i_clock; WAIT FOR 10 ns; END LOOP; END PROCESS; testDat_setup : PROCESS file flTestDat : TEXT open read_mode is "s:\test.dat"; VARIABLE row : INTEGER := 0; VARIABLE scratch : LINE; VARIABLE tdChA : INTEGER := 0; VARIABLE tdChB : INTEGER := 0; VARIABLE tdFRC : INTEGER := 1; BEGIN iChA <= (others=>'0'); iChB <= (others=>'0'); write(scratch, STRING'("start reading test data from file ...")); writeline(output, scratch); WHILE NOT (endfile(flTestDat)) LOOP readline(flTestDat, scratch); parse(scratch, tdChA); parse(scratch, tdChB); parse(scratch, tdFRC); writeline(output, scratch); write(scratch, STRING'("got row #")); write(scratch, row); write(scratch, STRING'(" of test data as ch-A: ")); write(scratch, tdChA); write(scratch, STRING'(", ch-B: ")); write(scratch, tdChB); write(scratch, STRING'(", FRC: ")); write(scratch, tdFRC); writeline(output, scratch); myTestData(row).chn_A <= tdChA; myTestData(row).chn_B <= tdChB; myTestData(row).FRC <= tdFRC; if (row < myTestData'length) then row := row + 1; end if; END LOOP; file_close(flTestDat); write(scratch, STRING'("DONE reading test data!")); writeline(output, scratch); row := 0; ADC_enable <= '0'; iChA <= std_logic_vector(to_unsigned(myTestData(row).chn_A, 16)); iChB <= std_logic_vector(to_unsigned(myTestData(row).chn_B, 16)); if (myTestData(row).FRC = 1) then ADC_frc <= '1'; else ADC_frc <= '0'; end if; write(scratch, STRING'("activated test data of row #")); write(scratch, row); writeline(output, scratch); WAIT FOR 30 ns; write(scratch, STRING'("test data on lines - A:")); write(scratch, iChA); write(scratch, STRING'(", B:")); write(scratch, iChB); writeline(output, scratch); doClock <= '1'; -- now really start simulation WAIT FOR 25 ns; ADC_enable <= '1'; WAIT; END PROCESS; testDat_processing: PROCESS VARIABLE first : boolean := true; VARIABLE row : INTEGER := 1; VARIABLE scratch : LINE; BEGIN WAIT UNTIL falling_edge(ADC_start); WAIT UNTIL rising_edge(i_clock); iChA <= std_logic_vector(to_unsigned(myTestData(row).chn_A, 16)); iChB <= std_logic_vector(to_unsigned(myTestData(row).chn_B, 16)); if (myTestData(row).FRC = 1) then ADC_frc <= '1'; else ADC_frc <= '0'; end if; write(scratch, STRING'("activated test data of row #")); write(scratch, row); writeline(output, scratch); write(scratch, STRING'("test data should be - A:")); write(scratch, std_logic_vector(to_unsigned(myTestData(row).chn_A, 16))); write(scratch, STRING'(", B:")); write(scratch, std_logic_vector(to_unsigned(myTestData(row).chn_B, 16))); writeline(output, scratch); write(scratch, STRING'("test data on lines - A:")); write(scratch, iChA); write(scratch, STRING'(", B:")); write(scratch, iChB); writeline(output, scratch); if (row < myTestData'length) then row := row + 1; else WAIT; end if; END PROCESS; tell_Data: PROCESS VARIABLE scratch : LINE; BEGIN WAIT UNTIL rising_edge(nWrite); write(scratch, STRING'(" >>> wrote channel-A with: ")); write(scratch, to_integer(unsigned(odChA))); write(scratch, STRING'(", channel-B with: ")); write(scratch, to_integer(unsigned(odChB))); write(scratch, STRING'(", to address: ")); write(scratch, to_integer(unsigned(oaddr))); writeline(output, scratch); END PROCESS; END;