This repository has been archived on 2022-02-18. You can view files and clone it, but cannot push or open issues or pull requests.
osmo-sdr/fpga/hw-v2/src/testbench/tb_usbrx.vhd

357 lines
8.8 KiB
VHDL

---------------------------------------------------------------------------------------------------
-- 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 <http://www.gnu.org/licenses/>. --
-----------------------------------------------------------------------------------
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;