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 DECLARATION*
|
||||||
signal mem_read_data : std_logic_vector(DATA_WIDTH-1 downto 0);
|
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_empty : std_logic := '0';
|
||||||
signal fifo_cnt : natural 0 to MAX_BURST_LENGTH := 0;
|
signal fifo_cnt : natural range 0 to MAX_BURST_LENGTH := 0;
|
||||||
signal delay_cnt : natural 0 to READ_LATENCY := 0;
|
signal delay_cnt : natural range 0 to READ_LATENCY := 0;
|
||||||
|
signal ready_in_sig, valid_out_sig : std_logic := '0';
|
||||||
|
|
||||||
begin
|
begin
|
||||||
|
|
||||||
@ -49,27 +50,43 @@ begin
|
|||||||
port map (
|
port map (
|
||||||
clk => clk,
|
clk => clk,
|
||||||
addr => addr,
|
addr => addr,
|
||||||
wen => not read,
|
wen => ready_in_sig and valid_in and (not read),
|
||||||
ren => read,
|
ren => ready_in_sig and valid_in and read,
|
||||||
wr_data => data_in,
|
wr_data => data_in,
|
||||||
rd_data => mem_read_data
|
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)
|
delay_line_prc : process(clk)
|
||||||
begin
|
begin
|
||||||
if rising_edge(clk) then
|
if rising_edge(clk) then
|
||||||
if (reset = '1') then
|
if (reset = '1') then
|
||||||
delay_line <= (others => '0');
|
delay_line <= (others => '0');
|
||||||
delay_cnt <= 0;
|
delay_cnt <= 0;
|
||||||
else
|
else
|
||||||
-- Shift Right
|
-- Shift Right
|
||||||
delay_line(READ_LATENCY-1 downto 0) <= delay_line(READ_LATENCY downto 1);
|
if (READ_LATENCY > 1) then
|
||||||
delay_line(READ_LATENCY) <= read;
|
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 (read = '1' and delay_line(1) = '0') then
|
if ((ready_in_sig and valid_in and read) = '1' and delay_line(1) = '0') then
|
||||||
delay_cnt <= delay_cnt + 1;
|
delay_cnt <= delay_cnt + 1;
|
||||||
elsif (read = '0' and delay_line(1) = '1') then
|
elsif ((ready_in_sig and valid_in and read) = '0' and delay_line(1) = '1') then
|
||||||
delay_cnt <= delay_cnt - 1;
|
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;
|
end if;
|
||||||
end if;
|
end if;
|
||||||
@ -85,14 +102,10 @@ begin
|
|||||||
reset => reset,
|
reset => reset,
|
||||||
data_in => mem_read_data,
|
data_in => mem_read_data,
|
||||||
write => delay_line(0),
|
write => delay_line(0),
|
||||||
read => ready_out,
|
read => ready_out and valid_out_sig,
|
||||||
data_out => data_out,
|
data_out => data_out,
|
||||||
empty => fifo_empty,
|
empty => fifo_empty,
|
||||||
full => open,
|
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;
|
end architecture;
|
||||||
Loading…
Reference in New Issue
Block a user