Add mem_ctrl Level 0 Test 1
mem_ctrl fixed and testbench implemented
This commit is contained in:
parent
7244fffacd
commit
52bd4053d1
51
sim/L0_mem_ctrl_test1.do
Normal file
51
sim/L0_mem_ctrl_test1.do
Normal file
@ -0,0 +1,51 @@
|
||||
onerror {resume}
|
||||
quietly WaveActivateNextPane {} 0
|
||||
add wave -noupdate -divider SYSTEM
|
||||
add wave -noupdate /l0_mem_ctrl_test1/uut/clk
|
||||
add wave -noupdate /l0_mem_ctrl_test1/uut/reset
|
||||
add wave -noupdate -divider INPUT
|
||||
add wave -noupdate /l0_mem_ctrl_test1/uut/ready_in
|
||||
add wave -noupdate /l0_mem_ctrl_test1/uut/valid_in
|
||||
add wave -noupdate -radix unsigned /l0_mem_ctrl_test1/uut/addr
|
||||
add wave -noupdate -radix hexadecimal /l0_mem_ctrl_test1/uut/data_in
|
||||
add wave -noupdate /l0_mem_ctrl_test1/uut/read
|
||||
add wave -noupdate -divider MEMORY
|
||||
add wave -noupdate -expand -group MEMORY -radix unsigned /l0_mem_ctrl_test1/uut/ram_inst/addr
|
||||
add wave -noupdate -expand -group MEMORY -radix hexadecimal /l0_mem_ctrl_test1/uut/ram_inst/rd_data
|
||||
add wave -noupdate -expand -group MEMORY /l0_mem_ctrl_test1/uut/ram_inst/ren
|
||||
add wave -noupdate -expand -group MEMORY /l0_mem_ctrl_test1/uut/ram_inst/wen
|
||||
add wave -noupdate -expand -group MEMORY -radix hexadecimal /l0_mem_ctrl_test1/uut/ram_inst/wr_data
|
||||
add wave -noupdate -divider OUTPUT
|
||||
add wave -noupdate /l0_mem_ctrl_test1/uut/ready_out
|
||||
add wave -noupdate -radix hexadecimal /l0_mem_ctrl_test1/uut/data_out
|
||||
add wave -noupdate /l0_mem_ctrl_test1/uut/valid_out
|
||||
add wave -noupdate -divider MISC
|
||||
add wave -noupdate /l0_mem_ctrl_test1/uut/delay_line
|
||||
add wave -noupdate -radix unsigned /l0_mem_ctrl_test1/uut/delay_cnt
|
||||
add wave -noupdate /l0_mem_ctrl_test1/uut/burst_fifo_inst/free
|
||||
add wave -noupdate -divider FIFO
|
||||
add wave -noupdate -group FIFO -radix hexadecimal /l0_mem_ctrl_test1/uut/burst_fifo_inst/data_in
|
||||
add wave -noupdate -group FIFO /l0_mem_ctrl_test1/uut/burst_fifo_inst/read
|
||||
add wave -noupdate -group FIFO /l0_mem_ctrl_test1/uut/burst_fifo_inst/write
|
||||
add wave -noupdate -group FIFO -radix hexadecimal /l0_mem_ctrl_test1/uut/burst_fifo_inst/data_out
|
||||
add wave -noupdate -group FIFO /l0_mem_ctrl_test1/uut/burst_fifo_inst/empty
|
||||
add wave -noupdate -group FIFO /l0_mem_ctrl_test1/uut/burst_fifo_inst/free
|
||||
add wave -noupdate -group FIFO /l0_mem_ctrl_test1/uut/burst_fifo_inst/full
|
||||
TreeUpdate [SetDefaultTree]
|
||||
WaveRestoreCursors {{Cursor 1} {574535 ps} 0}
|
||||
quietly wave cursor active 1
|
||||
configure wave -namecolwidth 149
|
||||
configure wave -valuecolwidth 144
|
||||
configure wave -justifyvalue left
|
||||
configure wave -signalnamewidth 1
|
||||
configure wave -snapdistance 10
|
||||
configure wave -datasetprefix 0
|
||||
configure wave -rowmargin 4
|
||||
configure wave -childrowmargin 2
|
||||
configure wave -gridoffset 0
|
||||
configure wave -gridperiod 1
|
||||
configure wave -griddelta 40
|
||||
configure wave -timeline 0
|
||||
configure wave -timelineunits ps
|
||||
update
|
||||
WaveRestoreZoom {0 ps} {1148342 ps}
|
||||
233
src/Tests/Level_0/L0_mem_ctrl_test1.vhd
Normal file
233
src/Tests/Level_0/L0_mem_ctrl_test1.vhd
Normal file
@ -0,0 +1,233 @@
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
use ieee.numeric_std.all;
|
||||
|
||||
library osvvm; -- Utility Library
|
||||
context osvvm.OsvvmContext;
|
||||
|
||||
use work.rtps_test_package.all;
|
||||
|
||||
entity L0_mem_ctrl_test1 is
|
||||
end entity;
|
||||
|
||||
architecture testbench of L0_mem_ctrl_test1 is
|
||||
|
||||
-- *CONSTANT DECLARATION*
|
||||
constant WORD_WIDTH : natural := 32;
|
||||
constant ADDR_WIDTH : natural := 3;
|
||||
constant MEMORY_DEPTH : natural := 2**ADDR_WIDTH;
|
||||
constant BURST_LENGTH : natural := MEMORY_DEPTH;
|
||||
|
||||
-- *TYPE DECLARATION*
|
||||
type TEST_ARRAY_TYPE is array (0 to MEMORY_DEPTH-1) of std_logic_vector(WORD_WIDTH-1 downto 0);
|
||||
|
||||
-- *SIGNAL DECLARATION*
|
||||
signal clk, read, ready_in, valid_in, ready_out, valid_out : std_logic := '0';
|
||||
signal data_in, data_out : std_logic_vector(WORD_WIDTH-1 downto 0) := (others => '0');
|
||||
signal addr : std_logic_vector(ADDR_WIDTH-1 downto 0) := (others => '0');
|
||||
signal reset : std_logic := '1';
|
||||
shared variable SB : osvvm.ScoreBoardPkg_slv.ScoreBoardPType;
|
||||
|
||||
begin
|
||||
|
||||
|
||||
-- Unit Under Test
|
||||
uut : entity work.mem_ctrl(arch)
|
||||
generic map (
|
||||
ADDR_WIDTH => ADDR_WIDTH,
|
||||
DATA_WIDTH => WORD_WIDTH,
|
||||
MEMORY_DEPTH => MEMORY_DEPTH,
|
||||
MAX_BURST_LENGTH => BURST_LENGTH
|
||||
)
|
||||
port map (
|
||||
clk => clk,
|
||||
reset => reset,
|
||||
addr => addr,
|
||||
read => read,
|
||||
ready_in => ready_in,
|
||||
valid_in => valid_in,
|
||||
data_in => data_in,
|
||||
ready_out => ready_out,
|
||||
valid_out => valid_out,
|
||||
data_out => data_out
|
||||
);
|
||||
|
||||
stimulus_prc : process
|
||||
variable RV : RandomPType;
|
||||
variable test_array : TEST_ARRAY_TYPE := (others => (others => '0'));
|
||||
variable tmp : std_logic_vector(WORD_WIDTH-1 downto 0) := (others => '0');
|
||||
begin
|
||||
SetAlertLogName("mem_ctrl - Level 0 - Generic");
|
||||
SetAlertEnable(FAILURE, TRUE);
|
||||
SetAlertEnable(ERROR, TRUE);
|
||||
SetAlertEnable(WARNING, TRUE);
|
||||
SetLogEnable(DEBUG, FALSE);
|
||||
SetLogEnable(PASSED, FALSE);
|
||||
SetLogEnable(INFO, TRUE);
|
||||
RV.InitSeed(RV'instance_name);
|
||||
|
||||
Log("Initiating Test", INFO);
|
||||
valid_in <= '0';
|
||||
data_in <= (others => '0');
|
||||
reset <= '1';
|
||||
wait until rising_edge(clk);
|
||||
wait until rising_edge(clk);
|
||||
reset <= '0';
|
||||
|
||||
|
||||
Log("Test Write Burst", INFO);
|
||||
AffirmIf(valid_out = '0', "Read output without Read request");
|
||||
-- Write entire Memory with random data
|
||||
for i in 0 to MEMORY_DEPTH-1 loop
|
||||
valid_in <= '1';
|
||||
addr <= std_logic_vector(to_unsigned(i, ADDR_WIDTH));
|
||||
tmp := RV.RandSlv(WORD_WIDTH);
|
||||
test_array(i) := tmp;
|
||||
data_in <= tmp;
|
||||
if (ready_in = '0') then
|
||||
wait until ready_in = '1';
|
||||
end if;
|
||||
wait until rising_edge(clk);
|
||||
end loop;
|
||||
valid_in <= '0';
|
||||
addr <= (others => '0');
|
||||
data_in <= (others => '0');
|
||||
wait until rising_edge(clk);
|
||||
|
||||
|
||||
Log("Test Single Read", INFO);
|
||||
-- Read one element from memory
|
||||
AffirmIf(valid_out = '0', "Read output without Read request");
|
||||
valid_in <= '1';
|
||||
addr <= std_logic_vector(to_unsigned(0, ADDR_WIDTH));
|
||||
read <= '1';
|
||||
SB.Push(test_array(0));
|
||||
wait until rising_edge(clk);
|
||||
valid_in <= '0';
|
||||
addr <= (others => '0');
|
||||
read <= '0';
|
||||
wait until rising_edge(clk);
|
||||
wait until rising_edge(clk);
|
||||
|
||||
|
||||
Log("Test Read Burst", INFO);
|
||||
-- Fill Read Burst
|
||||
for i in MEMORY_DEPTH-1 downto 0 loop
|
||||
valid_in <= '1';
|
||||
addr <= std_logic_vector(to_unsigned(i, ADDR_WIDTH));
|
||||
read <= '1';
|
||||
SB.Push(test_array(i));
|
||||
if (ready_in = '0') then
|
||||
wait until ready_in = '1';
|
||||
end if;
|
||||
wait until rising_edge(clk);
|
||||
end loop;
|
||||
valid_in <= '0';
|
||||
addr <= (others => '0');
|
||||
read <= '0';
|
||||
wait until rising_edge(clk);
|
||||
wait until rising_edge(clk);
|
||||
|
||||
|
||||
Log("Test Concurrent Request/Read Operation", INFO);
|
||||
-- Request
|
||||
valid_in <= '1';
|
||||
addr <= std_logic_vector(to_unsigned(0, ADDR_WIDTH));
|
||||
read <= '1';
|
||||
SB.Push(test_array(0));
|
||||
if (ready_in = '0') then
|
||||
wait until ready_in = '1';
|
||||
end if;
|
||||
wait until rising_edge(clk);
|
||||
valid_in <= '0';
|
||||
addr <= (others => '0');
|
||||
read <= '0';
|
||||
-- Read and Request
|
||||
if (valid_out /= '1') then
|
||||
wait until valid_out = '1';
|
||||
end if;
|
||||
valid_in <= '1';
|
||||
addr <= std_logic_vector(to_unsigned(1, ADDR_WIDTH));
|
||||
read <= '1';
|
||||
SB.Push(test_array(1));
|
||||
AlertIf(ready_in /= '1', "Precondition for concurrent operation not met");
|
||||
wait until rising_edge(clk);
|
||||
valid_in <= '0';
|
||||
addr <= (others => '0');
|
||||
read <= '0';
|
||||
-- Read
|
||||
wait until rising_edge(clk);
|
||||
wait until rising_edge(clk);
|
||||
|
||||
|
||||
Log("Test Operation Order", INFO);
|
||||
-- Request Address 0
|
||||
valid_in <= '1';
|
||||
addr <= std_logic_vector(to_unsigned(0, ADDR_WIDTH));
|
||||
read <= '1';
|
||||
SB.Push(test_array(0));
|
||||
if (ready_in = '0') then
|
||||
wait until ready_in = '1';
|
||||
end if;
|
||||
wait until rising_edge(clk);
|
||||
-- Write Address 0
|
||||
read <= '0';
|
||||
data_in <= test_array(MEMORY_DEPTH-1);
|
||||
if (ready_in = '0') then
|
||||
wait until ready_in = '1';
|
||||
end if;
|
||||
wait until rising_edge(clk);
|
||||
-- Request Address 0
|
||||
read <= '1';
|
||||
SB.Push(test_array(7));
|
||||
data_in <= (others => '0');
|
||||
if (ready_in = '0') then
|
||||
wait until ready_in = '1';
|
||||
end if;
|
||||
wait until rising_edge(clk);
|
||||
valid_in <= '0';
|
||||
addr <= (others => '0');
|
||||
read <= '0';
|
||||
wait until rising_edge(clk);
|
||||
wait until rising_edge(clk);
|
||||
|
||||
-- Wait until test Completion
|
||||
if (not SB.empty) then
|
||||
wait until SB.empty;
|
||||
end if;
|
||||
TranscriptOpen(RESULTS_FILE, APPEND_MODE);
|
||||
SetTranscriptMirror;
|
||||
ReportAlerts;
|
||||
TranscriptClose;
|
||||
std.env.stop;
|
||||
wait;
|
||||
end process;
|
||||
|
||||
output_check_prc : process(all)
|
||||
begin
|
||||
if falling_edge(clk) then
|
||||
if (valid_out = '1') then
|
||||
ready_out <= '1';
|
||||
SB.Check(data_out);
|
||||
else
|
||||
ready_out <= '0';
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
clock_prc : process
|
||||
begin
|
||||
clk <= '0';
|
||||
wait for 25 ns;
|
||||
clk <= '1';
|
||||
wait for 25 ns;
|
||||
end process;
|
||||
|
||||
watchdog : process
|
||||
begin
|
||||
wait for 1 ms;
|
||||
Alert("Test timeout", FAILURE);
|
||||
std.env.stop;
|
||||
end process;
|
||||
|
||||
end architecture;
|
||||
@ -32,10 +32,11 @@ architecture arch of mem_ctrl is
|
||||
|
||||
-- *SIGNAL DECLARATION*
|
||||
signal mem_read_data : std_logic_vector(DATA_WIDTH-1 downto 0);
|
||||
signal delay_line : std_logic_vector(READ_LATENCY downto 0) := (others => '0');
|
||||
signal delay_line : std_logic_vector(READ_LATENCY-1 downto 0) := (others => '0');
|
||||
signal fifo_empty : std_logic := '0';
|
||||
signal fifo_cnt : natural 0 to MAX_BURST_LENGTH := 0;
|
||||
signal delay_cnt : natural 0 to READ_LATENCY := 0;
|
||||
signal fifo_cnt : natural range 0 to MAX_BURST_LENGTH := 0;
|
||||
signal delay_cnt : natural range 0 to READ_LATENCY := 0;
|
||||
signal ready_in_sig, valid_out_sig : std_logic := '0';
|
||||
|
||||
begin
|
||||
|
||||
@ -49,27 +50,43 @@ begin
|
||||
port map (
|
||||
clk => clk,
|
||||
addr => addr,
|
||||
wen => not read,
|
||||
ren => read,
|
||||
wen => ready_in_sig and valid_in and (not read),
|
||||
ren => ready_in_sig and valid_in and read,
|
||||
wr_data => data_in,
|
||||
rd_data => mem_read_data
|
||||
);
|
||||
|
||||
|
||||
ready_in_sig <= '0' when (fifo_cnt - delay_cnt = 0) else '1';
|
||||
ready_in <= ready_in_sig;
|
||||
valid_out_sig <= not fifo_empty;
|
||||
valid_out <= valid_out_sig;
|
||||
|
||||
delay_line_prc : process(clk)
|
||||
begin
|
||||
if rising_edge(clk) then
|
||||
if (reset = '1') then
|
||||
delay_line <= (others => '0');
|
||||
delay_cnt <= 0;
|
||||
delay_line <= (others => '0');
|
||||
delay_cnt <= 0;
|
||||
else
|
||||
-- Shift Right
|
||||
delay_line(READ_LATENCY-1 downto 0) <= delay_line(READ_LATENCY downto 1);
|
||||
delay_line(READ_LATENCY) <= read;
|
||||
|
||||
if (read = '1' and delay_line(1) = '0') then
|
||||
delay_cnt <= delay_cnt + 1;
|
||||
elsif (read = '0' and delay_line(1) = '1') then
|
||||
delay_cnt <= delay_cnt - 1;
|
||||
if (READ_LATENCY > 1) then
|
||||
delay_line(READ_LATENCY-2 downto 0) <= delay_line(READ_LATENCY-1 downto 1);
|
||||
delay_line(READ_LATENCY-1) <= ready_in_sig and valid_in and read;
|
||||
|
||||
if ((ready_in_sig and valid_in and read) = '1' and delay_line(1) = '0') then
|
||||
delay_cnt <= delay_cnt + 1;
|
||||
elsif ((ready_in_sig and valid_in and read) = '0' and delay_line(1) = '1') then
|
||||
delay_cnt <= delay_cnt - 1;
|
||||
end if;
|
||||
else
|
||||
delay_line(0) <= ready_in_sig and valid_in and read;
|
||||
|
||||
if ((ready_in_sig and valid_in and read) = '1' and delay_line(0) = '0') then
|
||||
delay_cnt <= delay_cnt + 1;
|
||||
elsif ((ready_in_sig and valid_in and read) = '0' and delay_line(0) = '1') then
|
||||
delay_cnt <= delay_cnt - 1;
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
@ -85,14 +102,10 @@ begin
|
||||
reset => reset,
|
||||
data_in => mem_read_data,
|
||||
write => delay_line(0),
|
||||
read => ready_out,
|
||||
read => ready_out and valid_out_sig,
|
||||
data_out => data_out,
|
||||
empty => fifo_empty,
|
||||
full => open,
|
||||
free => fifo_cnt,
|
||||
free => fifo_cnt
|
||||
);
|
||||
|
||||
ready_in <= '0' when (fifo_cnt + delay_cnt = MAX_BURST_LENGTH) else '1';
|
||||
valid_out <= not fifo_empty;
|
||||
|
||||
end architecture;
|
||||
Loading…
Reference in New Issue
Block a user