|
|
@ -97,7 +97,7 @@ architecture sim of SpiT is |
|
|
|
subtype t_spi_mode is natural range 0 to 3; |
|
|
|
|
|
|
|
--+ test done array with entry for each test |
|
|
|
signal s_test_done : boolean_vector(t_spi_mode'low to 2*t_spi_mode'high+1) := (others => false); |
|
|
|
signal s_test_done : boolean_vector(t_spi_mode'low to 4*t_spi_mode'high+3) := (others => false); |
|
|
|
|
|
|
|
|
|
|
|
begin |
|
|
@ -109,278 +109,286 @@ begin |
|
|
|
s_reset_n <= '1' after 100 ns; |
|
|
|
|
|
|
|
|
|
|
|
--+ SpiMasterE tests for all 4 modes |
|
|
|
SpiMastersG : for mode in t_spi_mode'low to t_spi_mode'high generate |
|
|
|
|
|
|
|
--* Generate tests for both direction |
|
|
|
DataDirectionG : for direction in 0 to 1 generate |
|
|
|
|
|
|
|
signal s_sclk : std_logic; |
|
|
|
signal s_ste : std_logic; |
|
|
|
signal s_mosi : std_logic; |
|
|
|
signal s_miso : std_logic; |
|
|
|
|
|
|
|
signal s_din : std_logic_vector(C_DATA_WIDTH-1 downto 0); |
|
|
|
signal s_din_valid : std_logic; |
|
|
|
signal s_din_accept : std_logic; |
|
|
|
signal s_dout : std_logic_vector(C_DATA_WIDTH-1 downto 0); |
|
|
|
signal s_dout_valid : std_logic; |
|
|
|
signal s_dout_accept : std_logic; |
|
|
|
--* Generate SpiMasterE tests for all 4 modes |
|
|
|
SpiMastersG : for mode in t_spi_mode'low to t_spi_mode'high generate |
|
|
|
|
|
|
|
shared variable sv_mosi_queue : t_list_queue; |
|
|
|
shared variable sv_miso_queue : t_list_queue; |
|
|
|
|
|
|
|
signal s_sclk : std_logic; |
|
|
|
signal s_ste : std_logic; |
|
|
|
signal s_mosi : std_logic; |
|
|
|
signal s_miso : std_logic; |
|
|
|
|
|
|
|
begin |
|
|
|
signal s_din : std_logic_vector(C_DATA_WIDTH-1 downto 0); |
|
|
|
signal s_din_valid : std_logic; |
|
|
|
signal s_din_accept : std_logic; |
|
|
|
signal s_dout : std_logic_vector(C_DATA_WIDTH-1 downto 0); |
|
|
|
signal s_dout_valid : std_logic; |
|
|
|
signal s_dout_accept : std_logic; |
|
|
|
|
|
|
|
shared variable sv_mosi_queue : t_list_queue; |
|
|
|
shared variable sv_miso_queue : t_list_queue; |
|
|
|
|
|
|
|
--* Stimuli generator and BFM for the valid-accept interface |
|
|
|
--* on the local data input of the DUT |
|
|
|
--* |
|
|
|
--* Generates random stimuli and serves it to the |
|
|
|
--* valid-accept interface at the input of the DUT |
|
|
|
--* |
|
|
|
--* The stimuli data is also pushed into the mosi queue |
|
|
|
--* which serves as simple abstract reference model |
|
|
|
--* of the SPI transmit (master -> slave) channel |
|
|
|
SpiMasterStimP : process is |
|
|
|
variable v_random : RandomPType; |
|
|
|
begin |
|
|
|
v_random.InitSeed(v_random'instance_name); |
|
|
|
s_din_valid <= '0'; |
|
|
|
s_din <= (others => '0'); |
|
|
|
wait until s_reset_n = '1'; |
|
|
|
for i in 0 to integer'(2**C_DATA_WIDTH-1) loop |
|
|
|
s_din <= v_random.RandSlv(C_DATA_WIDTH); |
|
|
|
s_din_valid <= '1'; |
|
|
|
wait until rising_edge(s_clk) and s_din_accept = '1'; |
|
|
|
s_din_valid <= '0'; |
|
|
|
sv_mosi_queue.push(s_din); |
|
|
|
wait until rising_edge(s_clk); |
|
|
|
end loop; |
|
|
|
wait; |
|
|
|
end process SpiMasterStimP; |
|
|
|
|
|
|
|
|
|
|
|
--* DUT: SpiMasterE component |
|
|
|
i_SpiMasterE : SpiMasterE |
|
|
|
generic map ( |
|
|
|
G_DATA_WIDTH => C_DATA_WIDTH, |
|
|
|
G_DATA_DIR => 1, |
|
|
|
G_SPI_CPOL => mode / 2, |
|
|
|
G_SPI_CPHA => mode mod 2, |
|
|
|
G_SCLK_DIVIDER => 10 |
|
|
|
) |
|
|
|
port map ( |
|
|
|
--+ system if |
|
|
|
Reset_n_i => s_reset_n, |
|
|
|
Clk_i => s_clk, |
|
|
|
--+ SPI slave if |
|
|
|
SpiSclk_o => s_sclk, |
|
|
|
SpiSte_o => s_ste, |
|
|
|
SpiMosi_o => s_mosi, |
|
|
|
SpiMiso_i => s_miso, |
|
|
|
--+ local VAI if |
|
|
|
Data_i => s_din, |
|
|
|
DataValid_i => s_din_valid, |
|
|
|
DataAccept_o => s_din_accept, |
|
|
|
Data_o => s_dout, |
|
|
|
DataValid_o => s_dout_valid, |
|
|
|
DataAccept_i => s_dout_accept |
|
|
|
); |
|
|
|
|
|
|
|
|
|
|
|
--* Checker and BFM for the valid-accept interface |
|
|
|
--* on the local data output of the DUT |
|
|
|
--* |
|
|
|
--* Reads the output of the DUT and compares it to |
|
|
|
--* data popped from the miso queue which serves as |
|
|
|
--* simple abstract reference model of the SPI receive |
|
|
|
--* (slave -> master) channel |
|
|
|
SpiMasterCheckP : process is |
|
|
|
variable v_queue_data : std_logic_vector(C_DATA_WIDTH-1 downto 0) := (others => '0'); |
|
|
|
begin |
|
|
|
s_dout_accept <= '0'; |
|
|
|
wait until s_reset_n = '1'; |
|
|
|
for i in 0 to integer'(2**C_DATA_WIDTH-1) loop |
|
|
|
wait until rising_edge(s_clk) and s_dout_valid = '1'; |
|
|
|
s_dout_accept <= '1'; |
|
|
|
sv_miso_queue.pop(v_queue_data); |
|
|
|
assert_equal(s_dout, v_queue_data); |
|
|
|
wait until rising_edge(s_clk); |
|
|
|
s_dout_accept <= '0'; |
|
|
|
end loop; |
|
|
|
report "INFO: SpiMaster (mode=" & to_string(mode) & ") test successfully"; |
|
|
|
s_test_done(mode) <= true; |
|
|
|
wait; |
|
|
|
end process SpiMasterCheckP; |
|
|
|
|
|
|
|
|
|
|
|
--* Stimuli generator and BFM for the SPI slave |
|
|
|
--* interface on the SPI miso input of the DUT |
|
|
|
--* |
|
|
|
--* Generates random stimuli and serves it to the |
|
|
|
--* SPI interface at the input of the DUT |
|
|
|
--* |
|
|
|
--* The stimuli data is also pushed into the miso queue |
|
|
|
--* which serves as simple abstract reference model |
|
|
|
--* of the SPI receive (slave -> master) channel |
|
|
|
--* |
|
|
|
--* Furthermore the data received by the SPI slave BFM |
|
|
|
--* is checked against data popped from the mosi queue |
|
|
|
--* which serves as simple abstract reference model of |
|
|
|
--* the SPI receive (master -> slave) channel |
|
|
|
SpiSlaveP : process is |
|
|
|
variable v_send_data : std_logic_vector(C_DATA_WIDTH-1 downto 0) := (others => '0'); |
|
|
|
variable v_receive_data : std_logic_vector(C_DATA_WIDTH-1 downto 0) := (others => '0'); |
|
|
|
variable v_queue_data : std_logic_vector(C_DATA_WIDTH-1 downto 0) := (others => '0'); |
|
|
|
variable v_random : RandomPType; |
|
|
|
begin |
|
|
|
v_random.InitSeed(v_random'instance_name); |
|
|
|
wait until s_reset_n = '1'; |
|
|
|
for i in 0 to integer'(2**C_DATA_WIDTH-1) loop |
|
|
|
v_send_data := v_random.RandSlv(C_DATA_WIDTH); |
|
|
|
sv_miso_queue.push(v_send_data); |
|
|
|
spi_slave (data_in => v_send_data, |
|
|
|
data_out => v_receive_data, |
|
|
|
sclk => s_sclk, |
|
|
|
ste => s_ste, |
|
|
|
mosi => s_mosi, |
|
|
|
miso => s_miso, |
|
|
|
cpol => mode / 2, |
|
|
|
cpha => mode mod 2 |
|
|
|
); |
|
|
|
sv_mosi_queue.pop(v_queue_data); |
|
|
|
assert_equal(v_receive_data, v_queue_data); |
|
|
|
end loop; |
|
|
|
wait; |
|
|
|
end process SpiSlaveP; |
|
|
|
|
|
|
|
|
|
|
|
end generate SpiMastersG; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
--+ SpiSlaveE tests for all 4 modes |
|
|
|
SpiSlavesG : for mode in t_spi_mode'low to t_spi_mode'high generate |
|
|
|
|
|
|
|
|
|
|
|
signal s_sclk : std_logic; |
|
|
|
signal s_ste : std_logic; |
|
|
|
signal s_mosi : std_logic; |
|
|
|
signal s_miso : std_logic; |
|
|
|
|
|
|
|
signal s_din : std_logic_vector(C_DATA_WIDTH-1 downto 0); |
|
|
|
signal s_din_valid : std_logic; |
|
|
|
signal s_din_accept : std_logic; |
|
|
|
signal s_dout : std_logic_vector(C_DATA_WIDTH-1 downto 0); |
|
|
|
signal s_dout_valid : std_logic; |
|
|
|
signal s_dout_accept : std_logic; |
|
|
|
|
|
|
|
shared variable sv_mosi_queue : t_list_queue; |
|
|
|
shared variable sv_miso_queue : t_list_queue; |
|
|
|
|
|
|
|
|
|
|
|
begin |
|
|
|
--* Stimuli generator and BFM for the valid-accept interface |
|
|
|
--* on the local data input of the DUT |
|
|
|
--* |
|
|
|
--* Generates random stimuli and serves it to the |
|
|
|
--* valid-accept interface at the input of the DUT |
|
|
|
--* |
|
|
|
--* The stimuli data is also pushed into the mosi queue |
|
|
|
--* which serves as simple abstract reference model |
|
|
|
--* of the SPI transmit (master -> slave) channel |
|
|
|
SpiMasterStimP : process is |
|
|
|
variable v_random : RandomPType; |
|
|
|
begin |
|
|
|
v_random.InitSeed(v_random'instance_name); |
|
|
|
s_din_valid <= '0'; |
|
|
|
s_din <= (others => '0'); |
|
|
|
wait until s_reset_n = '1'; |
|
|
|
for i in 0 to integer'(2**C_DATA_WIDTH-1) loop |
|
|
|
s_din <= v_random.RandSlv(C_DATA_WIDTH); |
|
|
|
s_din_valid <= '1'; |
|
|
|
wait until rising_edge(s_clk) and s_din_accept = '1'; |
|
|
|
s_din_valid <= '0'; |
|
|
|
sv_mosi_queue.push(s_din); |
|
|
|
wait until rising_edge(s_clk); |
|
|
|
end loop; |
|
|
|
wait; |
|
|
|
end process SpiMasterStimP; |
|
|
|
|
|
|
|
|
|
|
|
--* DUT: SpiMasterE component |
|
|
|
i_SpiMasterE : SpiMasterE |
|
|
|
generic map ( |
|
|
|
G_DATA_WIDTH => C_DATA_WIDTH, |
|
|
|
G_DATA_DIR => direction, |
|
|
|
G_SPI_CPOL => mode / 2, |
|
|
|
G_SPI_CPHA => mode mod 2, |
|
|
|
G_SCLK_DIVIDER => 10 |
|
|
|
) |
|
|
|
port map ( |
|
|
|
--+ system if |
|
|
|
Reset_n_i => s_reset_n, |
|
|
|
Clk_i => s_clk, |
|
|
|
--+ SPI slave if |
|
|
|
SpiSclk_o => s_sclk, |
|
|
|
SpiSte_o => s_ste, |
|
|
|
SpiMosi_o => s_mosi, |
|
|
|
SpiMiso_i => s_miso, |
|
|
|
--+ local VAI if |
|
|
|
Data_i => s_din, |
|
|
|
DataValid_i => s_din_valid, |
|
|
|
DataAccept_o => s_din_accept, |
|
|
|
Data_o => s_dout, |
|
|
|
DataValid_o => s_dout_valid, |
|
|
|
DataAccept_i => s_dout_accept |
|
|
|
); |
|
|
|
|
|
|
|
|
|
|
|
--* Checker and BFM for the valid-accept interface |
|
|
|
--* on the local data output of the DUT |
|
|
|
--* |
|
|
|
--* Reads the output of the DUT and compares it to |
|
|
|
--* data popped from the miso queue which serves as |
|
|
|
--* simple abstract reference model of the SPI receive |
|
|
|
--* (slave -> master) channel |
|
|
|
SpiMasterCheckP : process is |
|
|
|
variable v_queue_data : std_logic_vector(C_DATA_WIDTH-1 downto 0) := (others => '0'); |
|
|
|
begin |
|
|
|
s_dout_accept <= '0'; |
|
|
|
wait until s_reset_n = '1'; |
|
|
|
for i in 0 to integer'(2**C_DATA_WIDTH-1) loop |
|
|
|
wait until rising_edge(s_clk) and s_dout_valid = '1'; |
|
|
|
s_dout_accept <= '1'; |
|
|
|
sv_miso_queue.pop(v_queue_data); |
|
|
|
assert_equal(s_dout, v_queue_data); |
|
|
|
wait until rising_edge(s_clk); |
|
|
|
s_dout_accept <= '0'; |
|
|
|
end loop; |
|
|
|
report "INFO: SpiMaster (direction=" & to_string(direction) & ", mode=" & to_string(mode) & ") test successfully"; |
|
|
|
s_test_done(mode+direction*4) <= true; |
|
|
|
wait; |
|
|
|
end process SpiMasterCheckP; |
|
|
|
|
|
|
|
|
|
|
|
--* Stimuli generator and BFM for the SPI slave |
|
|
|
--* interface on the SPI miso input of the DUT |
|
|
|
--* |
|
|
|
--* Generates random stimuli and serves it to the |
|
|
|
--* SPI interface at the input of the DUT |
|
|
|
--* |
|
|
|
--* The stimuli data is also pushed into the miso queue |
|
|
|
--* which serves as simple abstract reference model |
|
|
|
--* of the SPI receive (slave -> master) channel |
|
|
|
--* |
|
|
|
--* Furthermore the data received by the SPI slave BFM |
|
|
|
--* is checked against data popped from the mosi queue |
|
|
|
--* which serves as simple abstract reference model of |
|
|
|
--* the SPI receive (master -> slave) channel |
|
|
|
SpiSlaveP : process is |
|
|
|
variable v_send_data : std_logic_vector(C_DATA_WIDTH-1 downto 0) := (others => '0'); |
|
|
|
variable v_receive_data : std_logic_vector(C_DATA_WIDTH-1 downto 0) := (others => '0'); |
|
|
|
variable v_queue_data : std_logic_vector(C_DATA_WIDTH-1 downto 0) := (others => '0'); |
|
|
|
variable v_random : RandomPType; |
|
|
|
begin |
|
|
|
v_random.InitSeed(v_random'instance_name); |
|
|
|
wait until s_reset_n = '1'; |
|
|
|
for i in 0 to integer'(2**C_DATA_WIDTH-1) loop |
|
|
|
v_send_data := v_random.RandSlv(C_DATA_WIDTH); |
|
|
|
sv_miso_queue.push(v_send_data); |
|
|
|
spi_slave (data_in => v_send_data, |
|
|
|
data_out => v_receive_data, |
|
|
|
sclk => s_sclk, |
|
|
|
ste => s_ste, |
|
|
|
mosi => s_mosi, |
|
|
|
miso => s_miso, |
|
|
|
dir => direction, |
|
|
|
cpol => mode / 2, |
|
|
|
cpha => mode mod 2 |
|
|
|
); |
|
|
|
sv_mosi_queue.pop(v_queue_data); |
|
|
|
assert_equal(v_receive_data, v_queue_data); |
|
|
|
end loop; |
|
|
|
wait; |
|
|
|
end process SpiSlaveP; |
|
|
|
|
|
|
|
|
|
|
|
end generate SpiMastersG; |
|
|
|
|
|
|
|
|
|
|
|
--* Generate SpiMasterE tests for all 4 modes |
|
|
|
SpiSlavesG : for mode in t_spi_mode'low to t_spi_mode'high generate |
|
|
|
|
|
|
|
|
|
|
|
signal s_sclk : std_logic; |
|
|
|
signal s_ste : std_logic; |
|
|
|
signal s_mosi : std_logic; |
|
|
|
signal s_miso : std_logic; |
|
|
|
|
|
|
|
signal s_din : std_logic_vector(C_DATA_WIDTH-1 downto 0); |
|
|
|
signal s_din_valid : std_logic; |
|
|
|
signal s_din_accept : std_logic; |
|
|
|
signal s_dout : std_logic_vector(C_DATA_WIDTH-1 downto 0); |
|
|
|
signal s_dout_valid : std_logic; |
|
|
|
signal s_dout_accept : std_logic; |
|
|
|
|
|
|
|
shared variable sv_mosi_queue : t_list_queue; |
|
|
|
shared variable sv_miso_queue : t_list_queue; |
|
|
|
|
|
|
|
|
|
|
|
--* Unit test of spi master procedure, checks all combinations |
|
|
|
--* of cpol & cpha against spi slave procedure |
|
|
|
SpiMasterP : process is |
|
|
|
variable v_send_data : std_logic_vector(C_DATA_WIDTH-1 downto 0) := (others => '0'); |
|
|
|
variable v_receive_data : std_logic_vector(C_DATA_WIDTH-1 downto 0) := (others => '0'); |
|
|
|
variable v_queue_data : std_logic_vector(C_DATA_WIDTH-1 downto 0) := (others => '0'); |
|
|
|
variable v_random : RandomPType; |
|
|
|
begin |
|
|
|
v_random.InitSeed(v_random'instance_name); |
|
|
|
s_sclk <= '1'; |
|
|
|
s_ste <= '1'; |
|
|
|
s_mosi <= '1'; |
|
|
|
wait until s_reset_n = '1'; |
|
|
|
for i in 0 to integer'(2**C_DATA_WIDTH-1) loop |
|
|
|
v_send_data := v_random.RandSlv(C_DATA_WIDTH); |
|
|
|
sv_mosi_queue.push(v_send_data); |
|
|
|
spi_master (data_in => v_send_data, |
|
|
|
data_out => v_receive_data, |
|
|
|
sclk => s_sclk, |
|
|
|
ste => s_ste, |
|
|
|
mosi => s_mosi, |
|
|
|
miso => s_miso, |
|
|
|
cpol => mode / 2, |
|
|
|
cpha => mode mod 2, |
|
|
|
period => 100 ns |
|
|
|
); |
|
|
|
sv_miso_queue.pop(v_queue_data); |
|
|
|
assert_equal(v_receive_data, v_queue_data); |
|
|
|
end loop; |
|
|
|
report "INFO: SpiSlave (mode=" & to_string(mode) & ") test successfully"; |
|
|
|
s_test_done(mode+4) <= true; |
|
|
|
wait; |
|
|
|
end process SpiMasterP; |
|
|
|
|
|
|
|
|
|
|
|
SpiSlaveStimP : process is |
|
|
|
variable v_random : RandomPType; |
|
|
|
begin |
|
|
|
v_random.InitSeed(v_random'instance_name); |
|
|
|
s_din_valid <= '0'; |
|
|
|
s_din <= (others => '0'); |
|
|
|
wait until s_reset_n = '1'; |
|
|
|
for i in 0 to integer'(2**C_DATA_WIDTH-1) loop |
|
|
|
s_din <= v_random.RandSlv(C_DATA_WIDTH); |
|
|
|
s_din_valid <= '1'; |
|
|
|
wait until rising_edge(s_clk) and s_din_accept = '1'; |
|
|
|
s_din_valid <= '0'; |
|
|
|
sv_miso_queue.push(s_din); |
|
|
|
wait until rising_edge(s_clk) and s_dout_valid = '1'; |
|
|
|
end loop; |
|
|
|
wait; |
|
|
|
end process SpiSlaveStimP; |
|
|
|
|
|
|
|
|
|
|
|
i_SpiSlaveE : SpiSlaveE |
|
|
|
generic map ( |
|
|
|
G_DATA_WIDTH => C_DATA_WIDTH, |
|
|
|
G_DATA_DIR => 1, |
|
|
|
G_SPI_CPOL => mode / 2, |
|
|
|
G_SPI_CPHA => mode mod 2 |
|
|
|
) |
|
|
|
port map ( |
|
|
|
--+ system if |
|
|
|
Reset_n_i => s_reset_n, |
|
|
|
Clk_i => s_clk, |
|
|
|
--+ SPI slave if |
|
|
|
SpiSclk_i => s_sclk, |
|
|
|
SpiSte_i => s_ste, |
|
|
|
SpiMosi_i => s_mosi, |
|
|
|
SpiMiso_o => s_miso, |
|
|
|
--+ local VAI if |
|
|
|
Data_i => s_din, |
|
|
|
DataValid_i => s_din_valid, |
|
|
|
DataAccept_o => s_din_accept, |
|
|
|
Data_o => s_dout, |
|
|
|
DataValid_o => s_dout_valid, |
|
|
|
DataAccept_i => s_dout_accept |
|
|
|
); |
|
|
|
|
|
|
|
|
|
|
|
SpiSlaveCheckP : process is |
|
|
|
variable v_queue_data : std_logic_vector(C_DATA_WIDTH-1 downto 0) := (others => '0'); |
|
|
|
begin |
|
|
|
s_dout_accept <= '0'; |
|
|
|
wait until s_reset_n = '1'; |
|
|
|
for i in 0 to integer'(2**C_DATA_WIDTH-1) loop |
|
|
|
wait until rising_edge(s_clk) and s_dout_valid = '1'; |
|
|
|
s_dout_accept <= '1'; |
|
|
|
sv_mosi_queue.pop(v_queue_data); |
|
|
|
assert_equal(s_dout, v_queue_data); |
|
|
|
wait until rising_edge(s_clk); |
|
|
|
--* Unit test of spi master procedure, checks all combinations |
|
|
|
--* of cpol & cpha against spi slave procedure |
|
|
|
SpiMasterP : process is |
|
|
|
variable v_send_data : std_logic_vector(C_DATA_WIDTH-1 downto 0) := (others => '0'); |
|
|
|
variable v_receive_data : std_logic_vector(C_DATA_WIDTH-1 downto 0) := (others => '0'); |
|
|
|
variable v_queue_data : std_logic_vector(C_DATA_WIDTH-1 downto 0) := (others => '0'); |
|
|
|
variable v_random : RandomPType; |
|
|
|
begin |
|
|
|
v_random.InitSeed(v_random'instance_name); |
|
|
|
s_sclk <= '1'; |
|
|
|
s_ste <= '1'; |
|
|
|
s_mosi <= '1'; |
|
|
|
wait until s_reset_n = '1'; |
|
|
|
for i in 0 to integer'(2**C_DATA_WIDTH-1) loop |
|
|
|
v_send_data := v_random.RandSlv(C_DATA_WIDTH); |
|
|
|
sv_mosi_queue.push(v_send_data); |
|
|
|
spi_master (data_in => v_send_data, |
|
|
|
data_out => v_receive_data, |
|
|
|
sclk => s_sclk, |
|
|
|
ste => s_ste, |
|
|
|
mosi => s_mosi, |
|
|
|
miso => s_miso, |
|
|
|
dir => direction, |
|
|
|
cpol => mode / 2, |
|
|
|
cpha => mode mod 2, |
|
|
|
period => C_PERIOD * 10 |
|
|
|
); |
|
|
|
sv_miso_queue.pop(v_queue_data); |
|
|
|
assert_equal(v_receive_data, v_queue_data); |
|
|
|
end loop; |
|
|
|
report "INFO: SpiSlave (direction=" & to_string(direction) & ", mode=" & to_string(mode) & ") test successfully"; |
|
|
|
s_test_done(mode+8+direction*4) <= true; |
|
|
|
wait; |
|
|
|
end process SpiMasterP; |
|
|
|
|
|
|
|
|
|
|
|
SpiSlaveStimP : process is |
|
|
|
variable v_random : RandomPType; |
|
|
|
begin |
|
|
|
v_random.InitSeed(v_random'instance_name); |
|
|
|
s_din_valid <= '0'; |
|
|
|
s_din <= (others => '0'); |
|
|
|
wait until s_reset_n = '1'; |
|
|
|
for i in 0 to integer'(2**C_DATA_WIDTH-1) loop |
|
|
|
s_din <= v_random.RandSlv(C_DATA_WIDTH); |
|
|
|
s_din_valid <= '1'; |
|
|
|
wait until rising_edge(s_clk) and s_din_accept = '1'; |
|
|
|
s_din_valid <= '0'; |
|
|
|
sv_miso_queue.push(s_din); |
|
|
|
wait until rising_edge(s_clk) and s_dout_valid = '1'; |
|
|
|
end loop; |
|
|
|
wait; |
|
|
|
end process SpiSlaveStimP; |
|
|
|
|
|
|
|
|
|
|
|
i_SpiSlaveE : SpiSlaveE |
|
|
|
generic map ( |
|
|
|
G_DATA_WIDTH => C_DATA_WIDTH, |
|
|
|
G_DATA_DIR => direction, |
|
|
|
G_SPI_CPOL => mode / 2, |
|
|
|
G_SPI_CPHA => mode mod 2 |
|
|
|
) |
|
|
|
port map ( |
|
|
|
--+ system if |
|
|
|
Reset_n_i => s_reset_n, |
|
|
|
Clk_i => s_clk, |
|
|
|
--+ SPI slave if |
|
|
|
SpiSclk_i => s_sclk, |
|
|
|
SpiSte_i => s_ste, |
|
|
|
SpiMosi_i => s_mosi, |
|
|
|
SpiMiso_o => s_miso, |
|
|
|
--+ local VAI if |
|
|
|
Data_i => s_din, |
|
|
|
DataValid_i => s_din_valid, |
|
|
|
DataAccept_o => s_din_accept, |
|
|
|
Data_o => s_dout, |
|
|
|
DataValid_o => s_dout_valid, |
|
|
|
DataAccept_i => s_dout_accept |
|
|
|
); |
|
|
|
|
|
|
|
|
|
|
|
SpiSlaveCheckP : process is |
|
|
|
variable v_queue_data : std_logic_vector(C_DATA_WIDTH-1 downto 0) := (others => '0'); |
|
|
|
begin |
|
|
|
s_dout_accept <= '0'; |
|
|
|
end loop; |
|
|
|
wait; |
|
|
|
end process SpiSlaveCheckP; |
|
|
|
wait until s_reset_n = '1'; |
|
|
|
for i in 0 to integer'(2**C_DATA_WIDTH-1) loop |
|
|
|
wait until rising_edge(s_clk) and s_dout_valid = '1'; |
|
|
|
s_dout_accept <= '1'; |
|
|
|
sv_mosi_queue.pop(v_queue_data); |
|
|
|
assert_equal(s_dout, v_queue_data); |
|
|
|
wait until rising_edge(s_clk); |
|
|
|
s_dout_accept <= '0'; |
|
|
|
end loop; |
|
|
|
wait; |
|
|
|
end process SpiSlaveCheckP; |
|
|
|
|
|
|
|
|
|
|
|
end generate SpiSlavesG; |
|
|
|
|
|
|
|
end generate SpiSlavesG; |
|
|
|
|
|
|
|
end generate DataDirectionG; |
|
|
|
|
|
|
|
|
|
|
|
end architecture sim; |