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 @@
-
+
diff --git a/LAB2/vivado/rgb2grey_test/rgb2grey_test.xpr b/LAB2/vivado/rgb2grey_test/rgb2grey_test.xpr
index 2d62815..ccae72d 100644
--- a/LAB2/vivado/rgb2grey_test/rgb2grey_test.xpr
+++ b/LAB2/vivado/rgb2grey_test/rgb2grey_test.xpr
@@ -47,7 +47,7 @@
-
+