--------------------------------------------------------------------------------------------------- -- Filename : usbrx_toplevel.vhd -- Project : OsmoSDR FPGA Firmware Testbench -- Purpose : Toplevel Stimulus --------------------------------------------------------------------------------------------------- ----------------------------------------------------------------------------------- -- Copyright (C) 2012 maintech GmbH, Otto-Hahn-Str. 15, 97204 Hoechberg, Germany -- -- written by Matthias Kleffel -- -- -- -- This program is free software; you can redistribute it and/or modify -- -- it under the terms of the GNU General Public License as published by -- -- the Free Software Foundation as version 3 of the License, or -- -- -- -- This program is distributed in the hope that it will be useful, -- -- but WITHOUT ANY WARRANTY; without even the implied warranty of -- -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -- -- GNU General Public License V3 for more details. -- -- -- -- You should have received a copy of the GNU General Public License -- -- along with this program. If not, see . -- ----------------------------------------------------------------------------------- library ieee; use ieee.std_logic_1164.all; use ieee.std_logic_misc.all; use ieee.numeric_std.all; library work; use work.all; use work.mt_toolbox.all; entity tb_usbrx is end tb_usbrx; architecture rtl of tb_usbrx is -- common signal clk_in_pclk : std_logic := '1'; -- special control signal dings : std_logic; signal dingsrst : std_logic; -- ADC interface signal adc_cs : std_logic; signal adc_sck : std_logic; signal adc_sd1 : std_logic; signal adc_sd2 : std_logic; -- control SPI signal ctl_int : std_logic; signal ctl_cs : std_logic; signal ctl_sck : std_logic; signal ctl_mosi : std_logic; signal ctl_miso : std_logic; -- data SPIs signal rx_clk : std_logic; signal rx_syn : std_logic; signal rx_dat : std_logic; -- data SPIs signal tx_clk : std_logic := '1'; signal tx_syn : std_logic; signal tx_dat : std_logic; -- gain PWMs signal gain0 : std_logic; signal gain1 : std_logic; -- GPS signal gps_1pps : std_logic; signal gps_10k : std_logic; -- gpios signal gpio : std_logic_vector(9 downto 0); -- virtual GNDs/VCCs signal vgnd : std_logic_vector(11 downto 0); signal vcc33 : std_logic_vector(11 downto 0); signal vcc12 : std_logic_vector(4 downto 0); begin -- generate clocks clk_in_pclk <= not clk_in_pclk after 500 ns / 30.0; tx_clk <= '0'; --not tx_clk after 500 ns / 24.0; -- special control dings <= '0'; dingsrst <= '1'; --, '0' after 100 us, '1' after 200 us; -- data SPIs tx_syn <= '0'; tx_dat <= '0'; -- GPS gps_1pps <= '0'; gps_10k <= '0'; -- gpios gpio <= (others=>'H'); -- dummy ADC model process -- constant word1 : unsigned(15 downto 0) := "0010000000000001"; -- constant word2 : unsigned(15 downto 0) := "0001111111111110"; -- constant word1 : unsigned(15 downto 0) := "0001111111111111"; -- constant word2 : unsigned(15 downto 0) := "0001111111111111"; variable word1 : unsigned(15 downto 0) := "0011010111001101"; variable word2 : unsigned(15 downto 0) := "0001001111000101"; variable sreg1 : unsigned(15 downto 0); variable sreg2 : unsigned(15 downto 0); variable cnt : natural; begin adc_sd1 <= 'Z'; adc_sd2 <= 'Z'; cnt := 0; loop wait until falling_edge(adc_cs); word1 := to_unsigned(8192 + cnt, 16); word2 := to_unsigned(8192 - cnt, 16); cnt := (cnt + 1) mod 8192; sreg1 := word1; sreg2 := word2; adc_sd1 <= transport 'X', sreg1(15) after 5ns; adc_sd2 <= transport 'X', sreg2(15) after 5ns; sreg1 := shift_left(sreg1,1); sreg2 := shift_left(sreg2,1); il: loop wait until rising_edge(adc_cs) or falling_edge(adc_sck); exit when rising_edge(adc_cs); adc_sd1 <= transport 'X', sreg1(15) after 11.0ns; adc_sd2 <= transport 'X', sreg2(15) after 11.0ns; sreg1 := shift_left(sreg1,1); sreg2 := shift_left(sreg2,1); end loop; adc_sd1 <= transport 'X', 'Z' after 9.5ns; adc_sd2 <= transport 'X', 'Z' after 9.5ns; end loop; end process; -- SPI interface process -- write cycle procedure spi_write(addr: in integer; data: in slv32_t) is variable sreg : std_logic_vector(39 downto 0); begin -- assemble message sreg(39) := '0'; sreg(38 downto 32) := std_logic_vector(to_unsigned(addr,7)); sreg(31 downto 0) := data; -- assert CS ctl_sck <= '1'; ctl_mosi <= '1'; ctl_cs <= '0'; wait for 250ns; -- clock out data for i in 39 downto 0 loop ctl_sck <= '0'; ctl_mosi <= sreg(i); wait for 250ns; ctl_sck <= '1'; wait for 250ns; end loop; -- deassert CS wait for 250ns; ctl_cs <= '1'; wait for 250ns; end procedure spi_write; -- write cycle procedure spi_writem(addr,count: in integer; data: in slv32_array_t) is variable sreg : std_logic_vector(31 downto 0); begin -- assert CS ctl_sck <= '1'; ctl_mosi <= '1'; ctl_cs <= '0'; wait for 250ns; -- write command sreg(7) := '0'; sreg(6 downto 0) := std_logic_vector(to_unsigned(addr,7)); for i in 7 downto 0 loop ctl_sck <= '0'; ctl_mosi <= sreg(i); wait for 250ns; ctl_sck <= '1'; wait for 250ns; end loop; --write data for j in 0 to count-1 loop sreg := data(j); for i in 31 downto 0 loop ctl_sck <= '0'; ctl_mosi <= sreg(i); wait for 250ns; ctl_sck <= '1'; wait for 250ns; end loop; end loop; -- deassert CS wait for 250ns; ctl_cs <= '1'; wait for 250ns; end procedure spi_writem; -- read cycle procedure spi_read(addr,count: in integer; data: out slv32_array_t) is variable sreg : std_logic_vector(7 downto 0); begin -- assemble message sreg(7) := '1'; sreg(6 downto 0) := std_logic_vector(to_unsigned(addr,7)); -- assert CS ctl_sck <= '1'; ctl_mosi <= '1'; ctl_cs <= '0'; wait for 250ns; -- clock out command for i in 7 downto 0 loop ctl_sck <= '0'; ctl_mosi <= sreg(i); wait for 250ns; ctl_sck <= '1'; wait for 250ns; end loop; wait for 50us; -- read data for j in 0 to count-1 loop for i in 31 downto 0 loop ctl_sck <= '0'; wait for 250ns; data(j)(i) := ctl_miso; ctl_sck <= '1'; wait for 250ns; if i=24 or i=16 or i=8 then wait for 50us; end if; end loop; end loop; -- deassert CS wait for 250ns; ctl_cs <= '1'; wait for 250ns; end procedure spi_read; variable temp : slv32_array_t(0 to 5); begin ctl_cs <= '1'; ctl_sck <= '1'; ctl_mosi <= '1'; wait for 30us; -- spi_write(4,x"00000001"); -- spi_read(0,1,temp); -- spi_read(0,1,temp); -- wait; -- -- temp(0) := x"00000000"; -- temp(1) := x"12345678"; -- temp(2) := x"9ABCDEF0"; -- temp(3) := x"11233435"; -- temp(4) := x"23652662"; -- temp(5) := x"98735773"; -- spi_writem(0,6,temp); -- -- temp := (others=>x"00000000"); -- spi_read(0,6,temp); wait; end process; -- unit under test uut: entity usbrx_toplevel port map ( -- common clk_in_pclk => clk_in_pclk, -- special control dings => dings, dingsrst => dingsrst, -- ADC interface adc_cs => adc_cs, adc_sck => adc_sck, adc_sd1 => adc_sd1, adc_sd2 => adc_sd2, -- control SPI ctl_int => ctl_int, ctl_cs => ctl_cs, ctl_sck => ctl_sck, ctl_mosi => ctl_mosi, ctl_miso => ctl_miso, -- data SPIs rx_clk => rx_clk, rx_syn => rx_syn, rx_dat => rx_dat, -- data SPIs tx_clk => tx_clk, tx_syn => tx_syn, tx_dat => tx_dat, -- gain PWMs gain0 => gain0, gain1 => gain1, -- GPS gps_1pps => gps_1pps, gps_10k => gps_10k, -- gpios gpio => gpio, -- virtual GNDs/VCCs vgnd => vgnd, vcc33 => vcc33, vcc12 => vcc12 ); end rtl;