diff --git a/LAB2/sim/tb_bram_writer.vhd b/LAB2/sim/tb_bram_writer.vhd index a013bf3..828d2b9 100644 --- a/LAB2/sim/tb_bram_writer.vhd +++ b/LAB2/sim/tb_bram_writer.vhd @@ -8,7 +8,7 @@ -- Project Name: -- Target Devices: -- Tool Versions: --- Description: Testbench for bram_writer, stimulus and timing inspired by tb_img_conv.vhd +-- Description: Testbench for bram_writer, rewritten in the style of tb_packetizer.vhd -- -- Dependencies: -- @@ -23,13 +23,36 @@ USE ieee.std_logic_1164.ALL; USE ieee.numeric_std.ALL; ENTITY tb_bram_writer IS -END ENTITY; +END tb_bram_writer; ARCHITECTURE sim OF tb_bram_writer IS -- Testbench constants CONSTANT ADDR_WIDTH : POSITIVE := 4; - CONSTANT IMG_SIZE : POSITIVE := 2; -- Small size for quick simulation + CONSTANT IMG_SIZE : POSITIVE := 4; -- Increased size for more memory + + -- Component declaration for bram_writer + COMPONENT bram_writer IS + GENERIC ( + ADDR_WIDTH : POSITIVE; + IMG_SIZE : POSITIVE + ); + PORT ( + clk : IN STD_LOGIC; + aresetn : IN STD_LOGIC; + s_axis_tdata : IN STD_LOGIC_VECTOR(7 DOWNTO 0); + s_axis_tvalid : IN STD_LOGIC; + s_axis_tready : OUT STD_LOGIC; + s_axis_tlast : IN STD_LOGIC; + conv_addr : IN STD_LOGIC_VECTOR(ADDR_WIDTH-1 DOWNTO 0); + conv_data : OUT STD_LOGIC_VECTOR(6 DOWNTO 0); + start_conv : OUT STD_LOGIC; + done_conv : IN STD_LOGIC; + write_ok : OUT STD_LOGIC; + overflow : OUT STD_LOGIC; + underflow : OUT STD_LOGIC + ); + END COMPONENT; -- Signals for DUT SIGNAL clk : STD_LOGIC := '0'; @@ -46,36 +69,34 @@ ARCHITECTURE sim OF tb_bram_writer IS SIGNAL overflow : STD_LOGIC; SIGNAL underflow : STD_LOGIC; - -- Instantiate DUT - COMPONENT bram_writer IS - GENERIC ( - ADDR_WIDTH : POSITIVE := 4; - IMG_SIZE : POSITIVE := 2 - ); - PORT ( - clk : IN STD_LOGIC; - aresetn : IN STD_LOGIC; - s_axis_tdata : IN STD_LOGIC_VECTOR(7 DOWNTO 0); - s_axis_tvalid : IN STD_LOGIC; - s_axis_tready : OUT STD_LOGIC; - s_axis_tlast : IN STD_LOGIC; - conv_addr : IN STD_LOGIC_VECTOR(ADDR_WIDTH-1 DOWNTO 0); - conv_data : OUT STD_LOGIC_VECTOR(6 DOWNTO 0); - start_conv : OUT STD_LOGIC; - done_conv : IN STD_LOGIC; - write_ok : OUT STD_LOGIC; - overflow : OUT STD_LOGIC; - underflow : OUT STD_LOGIC - ); - END COMPONENT; + -- Stimulus memory for input data + TYPE mem_type IS ARRAY(0 TO (IMG_SIZE*IMG_SIZE)-1) OF STD_LOGIC_VECTOR(7 DOWNTO 0); + SIGNAL mem : mem_type := ( + 0 => x"3A", + 1 => x"7F", + 2 => x"12", + 3 => x"9C", + 4 => x"55", + 5 => x"2B", + 6 => x"81", + 7 => x"04", + 8 => x"6E", + 9 => x"F2", + 10 => x"1D", + 11 => x"C7", + 12 => x"99", + 13 => x"0A", + 14 => x"B3", + 15 => x"5D" + ); BEGIN -- Clock generation - clk <= not clk after 5 ns; + clk <= NOT clk AFTER 5 ns; - -- Instantiate DUT - bram_writer_inst: bram_writer + -- DUT instantiation + uut: bram_writer GENERIC MAP ( ADDR_WIDTH => ADDR_WIDTH, IMG_SIZE => IMG_SIZE @@ -97,51 +118,46 @@ BEGIN ); -- Stimulus process - stimulus : process - begin - -- Initial reset + stimulus : PROCESS + BEGIN + -- Reset aresetn <= '0'; - wait for 10 ns; + WAIT FOR 20 ns; aresetn <= '1'; - wait until rising_edge(clk); + WAIT UNTIL rising_edge(clk); -- Send IMG_SIZE*IMG_SIZE data words - for i in 0 to IMG_SIZE*IMG_SIZE-1 loop - s_axis_tdata <= std_logic_vector(to_unsigned(i, 8)); + FOR i IN 0 TO IMG_SIZE*IMG_SIZE-1 LOOP + s_axis_tdata <= mem(i); s_axis_tvalid <= '1'; - if i = IMG_SIZE*IMG_SIZE-1 then + IF i = IMG_SIZE*IMG_SIZE-1 THEN s_axis_tlast <= '1'; - else + ELSE s_axis_tlast <= '0'; - end if; - wait until rising_edge(clk); - -- Wait for ready - while s_axis_tready /= '1' loop - wait until rising_edge(clk); - end loop; - end loop; - s_axis_tvalid <= '0'; - s_axis_tlast <= '0'; + END IF; + -- Wait for handshake + WAIT UNTIL s_axis_tvalid = '1' AND s_axis_tready = '1' AND rising_edge(clk); + s_axis_tvalid <= '0'; + END LOOP; + s_axis_tlast <= '0'; -- Wait for write_ok and start_conv - wait until write_ok = '1'; - wait until rising_edge(clk); + WAIT UNTIL write_ok = '1'; + WAIT UNTIL rising_edge(clk); - -- Require data - for i in 0 to IMG_SIZE*IMG_SIZE-1 loop + -- Read out data using conv_addr + FOR i IN 0 TO IMG_SIZE*IMG_SIZE-1 LOOP conv_addr <= std_logic_vector(to_unsigned(i, ADDR_WIDTH)); - wait until rising_edge(clk); - end loop; + WAIT UNTIL rising_edge(clk); + END LOOP; -- Simulate convolution done done_conv <= '1'; - wait until rising_edge(clk); + WAIT UNTIL rising_edge(clk); done_conv <= '0'; -- Wait and finish - wait for 20 ns; - assert false report "Simulation finished." severity note; - wait; - end process; + WAIT; + END PROCESS; -END ARCHITECTURE; \ No newline at end of file +END sim; \ No newline at end of file diff --git a/LAB2/sim/tb_rgb2gray.vhd b/LAB2/sim/tb_rgb2gray.vhd index 3fe2e51..38b1350 100644 --- a/LAB2/sim/tb_rgb2gray.vhd +++ b/LAB2/sim/tb_rgb2gray.vhd @@ -56,11 +56,9 @@ ARCHITECTURE Behavioral OF rgb2gray_tb IS SIGNAL tready_block_req : STD_LOGIC := '0'; - CONSTANT clk_period : TIME := 10 ns; - BEGIN - clk <= NOT clk AFTER clk_period / 2; -- Clock generation + clk <= NOT clk AFTER 5 ns; -- Clock generation -- Asynchronous tready block process (simulate downstream backpressure) PROCESS (clk) @@ -123,12 +121,12 @@ BEGIN FOR j IN 0 TO 2 LOOP s_axis_tdata <= rgb_mem(i, j); s_axis_tvalid <= '1'; - IF i = 2 AND j = 2 THEN + -- Assert tlast at the end of the first group (i=2, j=2) + IF (i = 2 AND j = 2) THEN s_axis_tlast <= '1'; ELSE s_axis_tlast <= '0'; END IF; - -- Wait for handshake WAIT UNTIL s_axis_tvalid = '1' AND s_axis_tready = '1' AND rising_edge(clk); s_axis_tvalid <= '0'; END LOOP; @@ -141,7 +139,8 @@ BEGIN FOR j IN 0 TO 2 LOOP s_axis_tdata <= rgb_mem(i, j); s_axis_tvalid <= '1'; - IF i = 4 AND j = 2 THEN + -- Assert tlast at the end of this group (i=4, j=2) + IF (i = 4 AND j = 2) THEN s_axis_tlast <= '1'; ELSE s_axis_tlast <= '0'; @@ -164,7 +163,8 @@ BEGIN FOR j IN 0 TO 2 LOOP s_axis_tdata <= rgb_mem(i, j); s_axis_tvalid <= '1'; - IF i = 6 AND j = 2 THEN + -- Assert tlast at the end of this group (i=6, j=2) + IF (i = 6 AND j = 2) THEN s_axis_tlast <= '1'; ELSE s_axis_tlast <= '0'; @@ -180,7 +180,8 @@ BEGIN FOR j IN 0 TO 2 LOOP s_axis_tdata <= rgb_mem(i, j); s_axis_tvalid <= '1'; - IF i = 8 AND j = 2 THEN + -- Assert tlast at the very end (i=8, j=2) + IF (i = 8 AND j = 2) THEN s_axis_tlast <= '1'; ELSE s_axis_tlast <= '0'; diff --git a/LAB2/src/rgb2gray.vhd b/LAB2/src/rgb2gray.vhd index b859636..f610e2c 100644 --- a/LAB2/src/rgb2gray.vhd +++ b/LAB2/src/rgb2gray.vhd @@ -37,18 +37,17 @@ ARCHITECTURE Behavioral OF rgb2gray IS SIGNAL r_val, g_val : UNSIGNED(7 DOWNTO 0); SIGNAL sum : UNSIGNED(8 DOWNTO 0); SIGNAL gray : UNSIGNED(6 DOWNTO 0); - SIGNAL send_data : STD_LOGIC := '0'; SIGNAL m_axis_tvalid_int : STD_LOGIC := '0'; - SIGNAL m_axis_tdata_int : STD_LOGIC_VECTOR(7 DOWNTO 0) := (OTHERS => '0'); - SIGNAL s_axis_tready_int : STD_LOGIC := '1'; + SIGNAL s_axis_tready_int : STD_LOGIC := '0'; + + SIGNAL trigger : STD_LOGIC := '0'; + SIGNAL last_seen : STD_LOGIC := '0'; BEGIN - -- Port mappings - m_axis_tvalid <= m_axis_tvalid_int; - m_axis_tdata <= m_axis_tdata_int; s_axis_tready <= s_axis_tready_int; + m_axis_tvalid <= m_axis_tvalid_int; -- Divider instance DIVIDER : divider_by_3 @@ -66,56 +65,69 @@ BEGIN IF resetn = '0' THEN -- Reset all signals state <= WAIT_R; - s_axis_tready_int <= '1'; + + s_axis_tready_int <= '0'; m_axis_tvalid_int <= '0'; + + m_axis_tdata <= (OTHERS => '0'); m_axis_tlast <= '0'; - m_axis_tdata_int <= (OTHERS => '0'); + r_val <= (OTHERS => '0'); g_val <= (OTHERS => '0'); + sum <= (OTHERS => '0'); - send_data <= '0'; + + trigger <= '0'; ELSE - -- Propagate TLAST - m_axis_tlast <= s_axis_tlast; - -- Clear valid once data has been accepted - IF m_axis_tvalid_int = '1' AND m_axis_tready = '1' THEN + -- Input data - slave + s_axis_tready_int <= m_axis_tready; + + IF s_axis_tlast = '1' THEN + last_seen <= '1'; + ELSE + m_axis_tlast <= '0'; + END IF; + + -- Output data - master + IF m_axis_tready = '1' THEN m_axis_tvalid_int <= '0'; END IF; - -- Issue new output only when back?pressure is released - IF send_data = '1' AND m_axis_tready = '1' THEN - m_axis_tdata_int <= '0' & STD_LOGIC_VECTOR(gray); -- MSB zero + 7?bit gray + IF trigger = '1' AND (m_axis_tvalid_int = '0' OR m_axis_tready = '1') THEN m_axis_tvalid_int <= '1'; - send_data <= '0'; + m_axis_tdata <= '0' & STD_LOGIC_VECTOR(gray); -- MSB zero + 7bit gray + + IF last_seen = '1' THEN + m_axis_tlast <= '1'; + last_seen <= '0'; + END IF; + + trigger <= '0'; END IF; - -- Back?pressure: blocca ingresso finché non hai trasmesso - IF send_data = '1' OR (m_axis_tvalid_int = '1' AND m_axis_tready = '0') THEN - s_axis_tready_int <= '0'; - ELSE - s_axis_tready_int <= '1'; - END IF; - - -- FSM per ricezione R, G, B + -- State machine for R, G, B values buffering CASE state IS WHEN WAIT_R => IF s_axis_tvalid = '1' AND s_axis_tready_int = '1' THEN r_val <= unsigned(s_axis_tdata); + state <= WAIT_G; END IF; WHEN WAIT_G => IF s_axis_tvalid = '1' AND s_axis_tready_int = '1' THEN g_val <= unsigned(s_axis_tdata); + state <= WAIT_B; END IF; WHEN WAIT_B => IF s_axis_tvalid = '1' AND s_axis_tready_int = '1' THEN - sum <= RESIZE(r_val + g_val + unsigned(s_axis_tdata), 9); - send_data <= '1'; + sum <= RESIZE(r_val + g_val + unsigned(s_axis_tdata), sum'length); + trigger <= '1'; + state <= WAIT_R; END IF; END CASE; diff --git a/LAB2/vivado/bram_writer_test/bram_writer_test.xpr b/LAB2/vivado/bram_writer_test/bram_writer_test.xpr index 0be1831..05617d0 100644 --- a/LAB2/vivado/bram_writer_test/bram_writer_test.xpr +++ b/LAB2/vivado/bram_writer_test/bram_writer_test.xpr @@ -47,7 +47,7 @@