LIBRARY IEEE; USE IEEE.std_logic_1164.ALL; -------------------------------------------- --Testbench for the actel design --supports hamming on serial transmission --no i2c and other options supported -------------------------------------------------------- entity top_tb is generic (sclk_period : Time := 100 ns; lclk_period : Time := 110 ns; use_hamming : Integer := 1); end top_tb; architecture sim of top_tb is component top is port ( --Local clock (for debugging) LCLK : in std_logic; --reset (used as power on reset) rst : in std_logic; -- mode selector to configure the chip -- mode_sel(0) is 1/0 for with/without hamming -- mode_sel(1) is 1/0 for divided/direct sclk for gating of the outputs -- mode_sel(2) is not used now -- mode_sel(3) is 1/0 for Dmode/toggle mode mode_sel : in std_logic_vector(3 downto 0); oddeven : in std_logic; SSTR : in std_logic; -- SSTR input for SPI or data back to --I2C master freq = 300Hz SDIN : in std_logic; -- data in in both cases freq = 10kHz SCLK : in std_logic; -- clock in both cases freq = 10kHz -- SPI out gives out the serial data, for debugging purposes SDOU : out std_logic; -- pin 10, routed to TP14 --serial data out SDOUT : out std_logic; -- output of the input shift register SDOUT2 : out std_logic; -- this is the feedback data line --3 spare signals for further use SOUT2 : out std_logic; --not s LED_out0 : out std_logic; LED_out1 : out std_logic; LED_out2 : out std_logic; LED_out3 : out std_logic; -- hamming state state_hm : out std_logic_vector( 1 downto 0); dummyout : out std_logic; spare : out std_logic_vector(5 downto 0); TDOp, TCKp, TDIp : out std_logic; TRSTp : out std_logic; TMSpup : out std_logic_vector(1 downto 0); --parallel data out (drives the rectifier channels) MOSgt : out std_logic_vector(30 downto 1) ); end component; component hamming_enc_32d is port ( din : in std_logic_vector (31 downto 0); -- data from the device dout : out std_logic_vector (38 downto 0) -- data to instr. memory ); end component; component hamming_dec_32d is port ( din : in std_logic_vector (38 downto 0); -- data from data memory dout : out std_logic_vector (31 downto 0); -- data to CPU state : out std_logic_vector ( 1 downto 0) ); end component; component shreg_parin is generic(N : Integer := 32); port( --inputs rst_n : in std_logic; PARIN : in std_logic_vector(N downto 1); CLK : in std_logic; EN : in std_logic; --outputs SDOUT : out std_logic; SSTR : out std_logic; sclk : out std_logic ); end component; component shreg2 is generic(N : Integer := 24); port( rst_n : in std_logic; SCLK : in std_logic; SDIN : in std_logic; SSTR : in std_logic; EN : in std_logic; SDOUT7s : out std_logic; SDOUT : out std_logic; PAROUTd : out std_logic_vector(N downto 1); PAROUT : out std_logic_vector(N downto 1) ); end component; --no hamming, serial interface, serial clock, toggle mode... signal mode_sel : std_logic_vector(3 downto 0) := "0000"; --signal definitions signal LCLK : std_logic; signal lclkd2 : std_logic := '0'; signal lclkd2d : std_logic; signal rst_n : std_logic := '0'; signal SSTR : std_logic; signal SSTR_i : std_logic; signal SDIN : std_logic; signal sdin_i : std_logic; signal sclk : std_logic; signal sclk_i : std_logic; signal sclkd2 : std_logic := '0'; signal sclkd2d : std_logic; signal nSCLK : std_logic; signal clock_enable : std_logic; signal strobe_enable : std_logic; signal SDOUT2 : std_logic; signal oddeven : std_logic; signal err_mos : std_logic; signal err_rec : std_logic; signal sdin_dcs : std_logic; signal sstr_dcs : std_logic; signal dcs : std_logic := '0'; signal MOSgt_c0 : std_logic_vector(30 downto 1); signal MOSgt_check : std_logic_vector(30 downto 1); signal MOSgt : std_logic_vector(30 downto 1); signal MOSgt_ref : std_logic_vector(30 downto 1); signal MOSgt_ref_old : std_logic_vector(30 downto 1); signal data2send : std_logic_vector(31+7 downto 0); signal data2send_hm : std_logic_vector(31+7 downto 0); signal hamm_err : std_logic_vector(31+7 downto 0); signal rec_regs : std_logic_vector(31+7 downto 0); signal rec_regp : std_logic_vector(31+7 downto 0); signal rec_regp_dcs : std_logic_vector(31+7 downto 0); signal rec_data_h : std_logic_vector(31 downto 0); signal rec_data : std_logic_vector(31 downto 0); signal data2send_i : std_logic_vector(31 downto 0); signal data2send_i1 : std_logic_vector(31 downto 0); signal data2send_i2 : std_logic_vector(31 downto 0); signal testdata : std_logic_vector(31 downto 0); signal LED_out : std_logic_vector( 3 downto 0); signal counter : Integer; signal cnt_max : Integer; signal cycles : Integer; signal state_hm : std_logic_vector(1 downto 0); signal state_hm_rec : std_logic_vector(1 downto 0); -- 00 = ok; 01 = parity error; 10 = 2-Bit error; 11 1-Bit error (corrected) signal rst : std_logic; signal SDIN_high : std_logic := '0'; signal SDIN_mask : std_logic := '1'; begin --simulates a power on reset rst_n <= '1' after 6.7*sclk_period, -- '0' after 800*sclk_period, '1' after 805*sclk_period; testdata <= x"01234567" after 6.7 * sclk_period; -- x"f00000ff" after 100 *sclk_period, -- x"000fff0f" after 2000 *sclk_period, -- x"fff0f000" after 3500 *sclk_period, -- x"00000000" after 4500 *sclk_period, -- x"ffffffff" after 5500 *sclk_period, -- x"000ff0ff" after 6000 *sclk_period; --hamming needs an reset before working properly -- mode_sel(0) is 1/0 for with/without hamming -- mode_sel(1) is 1/0 for divided/direct sclk for gating of the outputs -- mode_sel(2) is not used now -- mode_sel(3) is 1/0 for Dmode/toggle mode mode_sel(0) <= '1'; -- switches hamming on mode_sel(1) <= '1'; -- divided sclk for toggle mode_sel(3) <= '0'; -- toggle mode oddeven <= '1'; dcs <= '1'; clock_enable <= '1' after 1 * sclk_period, -- '0' after 6000 * sclk_period, '1' after 7000 * sclk_period; strobe_enable <= '1' after 1 * sclk_period, -- '0' after 3000 * sclk_period, '1' after 4000 * sclk_period; rst <= not rst_n; --generates a clock with the freq of 1/sclk_period and 1/lclk_period sclkd2 <= not sclkd2 after sclk_period; sclkd2d <= sclkd2 after sclk_period*0.6; sclk <= sclkd2 xor sclkd2d; sclk_i <= sclk and clock_enable; lclkd2 <= not lclkd2 after lclk_period; lclkd2d <= lclkd2 after lclk_period*0.6; lclk <= lclkd2 xor lclkd2d; --connects the hamming encoder (used in the testbench to encode the serial data --when the use hamming option is chosen henc: hamming_enc_32d port map( din => data2send_i, dout => data2send_hm ); --signal router for the different config options, especially for hamming --encoding hamm_err <= (5 => '1', others => '0'); -- hamm_err <= (others => '0'); data2send <= data2send_hm xor hamm_err when mode_sel(0) = '1' else "0000000" & data2send_i; --controls the length of the input data cnt_max <= 31 when mode_sel(0)='0' else 38; send2: process(sclk, rst_n) begin --if reset, set everything to 0 if rst_n = '0' then counter <= 0; cycles <= 0; SDIN <= '0'; SSTR <= '0'; elsif sclk'event and sclk = '0' then --falling edge... if mode_sel(0)='1' then SDIN <= data2send(31+7-counter); else SDIN <= data2send(31 -counter); end if; if counter = cnt_max then --when max is reached, set back to 0; counter <= 0; cycles <= cycles + 1; else counter <= counter + 1; --increment counter end if; if counter = 0 then SSTR <= '1'; data2send_i <= testdata; data2send_i1 <= data2send_i; data2send_i2 <= data2send_i1; MOSgt_ref <= testdata(29 downto 0); MOSgt_ref_old <= MOSgt_ref; else SSTR <= '0'; end if; end if; end process; nSCLK <= not SCLK; send_dcs: shreg_parin generic map(N => 39) port map( --inputs rst_n => rst_n, PARIN => data2send, CLK => nSCLK, EN => '1', --outputs SDOUT => sdin_dcs, SSTR => sstr_dcs, sclk => open ); sstr_i <= sstr and strobe_enable when dcs='0' else sstr_dcs and strobe_enable; sdin_i <= (SDIN or SDIN_high) and SDIN_mask when dcs='0' else (sdin_dcs or SDIN_high) and SDIN_mask; --connecting the top component itop: top port map( LCLK => LCLK, rst => rst, mode_sel => mode_sel, oddeven => oddeven, SSTR => SSTR_i, SDIN => SDIN_i, SCLK => SCLK_i, SDOU => open, SDOUT2 => SDOUT2, SDOUT => open, --3 spare signals for further use SOUT2 => open, dummyout => open, LED_out0 => LED_out(0), LED_out1 => LED_out(1), LED_out2 => LED_out(2), LED_out3 => LED_out(3), state_hm => state_hm, MOSgt => MOSgt ); -- create check output, eliminating the toggles, for the two possible clocks process(sclk) begin if sclk'event and sclk='0' then MOSgt_c0 <= MOSgt; MOSgt_check <= MOSgt xor MOSgt_c0; end if; end process; err_mos <= '1' when MOSgt_check /= MOSgt_ref_old else '0'; -- receiver process(sclk) begin if sclk'event and sclk='0' then rec_regs <= rec_regs(rec_regs'high-1 downto 0) & SDOUT2; if sstr_i='1' then rec_regp <= rec_regs; end if; end if; end process; dcs_rec: shreg2 generic map(N => 39) port map( rst_n => rst_n, SCLK => nSCLK, SDIN => SDOUT2, SSTR => SSTR_i, EN => '1', SDOUT7s => open, SDOUT => open, PAROUTd => open, PAROUT => rec_regp_dcs ); hdec: hamming_dec_32d port map( din => rec_regp_dcs, dout => rec_data_h, state => state_hm_rec ); rec_data <= rec_data_h when mode_sel(0)='1' else rec_regp(rec_data'range); err_rec <= '1' when rec_data /= data2send_i2 else '0'; end;