diff --git a/LAB2/sim/tb_rgb2gray.vhd b/LAB2/sim/tb_rgb2gray.vhd
index f742af1..e1806f6 100644
--- a/LAB2/sim/tb_rgb2gray.vhd
+++ b/LAB2/sim/tb_rgb2gray.vhd
@@ -45,35 +45,89 @@ ARCHITECTURE Behavioral OF rgb2gray_tb IS
BEGIN
- m_axis_tready<='1';
-
- clk <= not clk AFTER clk_period / 2; -- Clock generation
+ clk <= NOT clk AFTER clk_period / 2; -- Clock generation
-- Instantiate the Device Under Test (DUT)
- DUT: rgb2gray
- PORT MAP (
- clk => clk,
- resetn => resetn,
- m_axis_tvalid => m_axis_tvalid,
- m_axis_tdata => m_axis_tdata,
- m_axis_tready => m_axis_tready,
- m_axis_tlast => m_axis_tlast,
- s_axis_tvalid => s_axis_tvalid,
- s_axis_tdata => s_axis_tdata,
- s_axis_tready => s_axis_tready,
- s_axis_tlast => s_axis_tlast
- );
+ DUT : rgb2gray
+ PORT MAP(
+ clk => clk,
+ resetn => resetn,
+ m_axis_tvalid => m_axis_tvalid,
+ m_axis_tdata => m_axis_tdata,
+ m_axis_tready => m_axis_tready,
+ m_axis_tlast => m_axis_tlast,
+ s_axis_tvalid => s_axis_tvalid,
+ s_axis_tdata => s_axis_tdata,
+ s_axis_tready => s_axis_tready,
+ s_axis_tlast => s_axis_tlast
+ );
-- Stimulus process
stimulus_process : PROCESS
VARIABLE pixel_value : INTEGER := 1; -- Variable to increment pixel values
BEGIN
- wait for 10 ns;
- resetn<='1';
+ WAIT FOR 10 ns;
+ resetn <= '1';
s_axis_tvalid <= '1';
-- Send multiple RGB pixels with incrementing values
- FOR i IN 0 TO 10 LOOP -- Send 10 pixels
+ FOR i IN 0 TO 5 LOOP -- Send 10 pixels
+ -- R component
+ s_axis_tdata <= STD_LOGIC_VECTOR(TO_UNSIGNED(pixel_value, 8));
+ WAIT FOR clk_period;
+
+ -- G component
+ pixel_value := pixel_value + 5;
+ s_axis_tdata <= STD_LOGIC_VECTOR(TO_UNSIGNED(pixel_value, 8));
+ WAIT FOR clk_period;
+
+ -- B component
+ pixel_value := pixel_value + 1;
+ s_axis_tdata <= STD_LOGIC_VECTOR(TO_UNSIGNED(pixel_value, 8));
+ WAIT FOR clk_period;
+
+ -- Reset last signal
+ pixel_value := pixel_value + 1;
+ END LOOP;
+
+ m_axis_tready <= '0';
+
+ -- R component
+ s_axis_tdata <= STD_LOGIC_VECTOR(TO_UNSIGNED(pixel_value, 8));
+ WAIT FOR clk_period;
+
+ -- G component
+ pixel_value := pixel_value + 5;
+ s_axis_tdata <= STD_LOGIC_VECTOR(TO_UNSIGNED(pixel_value, 8));
+ WAIT FOR clk_period;
+
+ -- B component
+ pixel_value := pixel_value + 1;
+ s_axis_tdata <= STD_LOGIC_VECTOR(TO_UNSIGNED(pixel_value, 8));
+ WAIT FOR clk_period;
+
+ FOR i IN 0 TO 3 LOOP -- Send 10 pixels
+ -- R component
+ s_axis_tdata <= STD_LOGIC_VECTOR(TO_UNSIGNED(pixel_value, 8));
+ WAIT FOR clk_period;
+
+ -- G component
+ pixel_value := pixel_value + 5;
+ s_axis_tdata <= STD_LOGIC_VECTOR(TO_UNSIGNED(pixel_value, 8));
+ WAIT FOR clk_period;
+
+ -- B component
+ pixel_value := pixel_value + 1;
+ s_axis_tdata <= STD_LOGIC_VECTOR(TO_UNSIGNED(pixel_value, 8));
+ WAIT FOR clk_period;
+
+ -- Reset last signal
+ pixel_value := pixel_value + 1;
+ END LOOP;
+
+ m_axis_tready <= '1';
+
+ FOR i IN 0 TO 3 LOOP -- Send 10 pixels
-- R component
s_axis_tdata <= STD_LOGIC_VECTOR(TO_UNSIGNED(pixel_value, 8));
WAIT FOR clk_period;
diff --git a/LAB2/src/depacketizer.vhd b/LAB2/src/depacketizer.vhd
index 2816982..d1437ef 100644
--- a/LAB2/src/depacketizer.vhd
+++ b/LAB2/src/depacketizer.vhd
@@ -1,99 +1,94 @@
-library ieee;
-use ieee.std_logic_1164.all;
-use ieee.numeric_std.all;
-
-
-entity depacketizer is
- generic (
- HEADER: INTEGER :=16#FF#;
- FOOTER: INTEGER :=16#F1#
+LIBRARY ieee;
+USE ieee.std_logic_1164.ALL;
+USE ieee.numeric_std.ALL;
+ENTITY depacketizer IS
+ GENERIC (
+ HEADER : INTEGER := 16#FF#;
+ FOOTER : INTEGER := 16#F1#
);
- port (
- clk : in std_logic;
- aresetn : in std_logic;
+ 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_tdata : IN STD_LOGIC_VECTOR(7 DOWNTO 0);
+ s_axis_tvalid : IN STD_LOGIC;
+ s_axis_tready : OUT STD_LOGIC;
- m_axis_tdata : out std_logic_vector(7 downto 0);
- m_axis_tvalid : out std_logic;
- m_axis_tready : in std_logic;
- m_axis_tlast : out std_logic
+ m_axis_tdata : OUT STD_LOGIC_VECTOR(7 DOWNTO 0);
+ m_axis_tvalid : OUT STD_LOGIC;
+ m_axis_tready : IN STD_LOGIC;
+ m_axis_tlast : OUT STD_LOGIC
);
-end entity depacketizer;
+END ENTITY depacketizer;
-architecture rtl of depacketizer is
+ARCHITECTURE rtl OF depacketizer IS
-- Enumeration for the state machine
-- IDLE: Waiting for the start of a new packet
-- STREAMING: Actively processing and forwarding packet data
- type state_type is (IDLE, STREAMING);
- signal state : state_type := IDLE;
+ TYPE state_type IS (IDLE, STREAMING);
+ SIGNAL state : state_type := IDLE;
-- Buffer to handle backpressure
- signal buffer_in : std_logic_vector(7 downto 0) := (others => '0');
- signal buffer_valid : std_logic := '0'; -- Indicates if buffer_in contains valid data
-begin
+ SIGNAL buffer_in : STD_LOGIC_VECTOR(7 DOWNTO 0) := (OTHERS => '0');
+ SIGNAL buffer_valid : STD_LOGIC := '0'; -- Indicates if buffer_in contains valid data
+BEGIN
- depacketizer_fsm: process(clk)
- begin
- if rising_edge(clk) then
- if aresetn = '0' then
+ depacketizer_fsm : PROCESS (clk)
+ BEGIN
+ IF rising_edge(clk) THEN
+ IF aresetn = '0' THEN
-- Reset: back to idle and clear everything
- state <= IDLE;
+ state <= IDLE;
s_axis_tready <= '0';
m_axis_tvalid <= '0';
- m_axis_tlast <= '0';
- m_axis_tdata <= (others => '0');
- buffer_in <= (others => '0');
- buffer_valid <= '0';
+ m_axis_tlast <= '0';
+ m_axis_tdata <= (OTHERS => '0');
+ buffer_in <= (OTHERS => '0');
+ buffer_valid <= '0';
- else
+ ELSE
-- Defaults for each clock cycle
s_axis_tready <= '1';
m_axis_tvalid <= '0';
- m_axis_tlast <= '0';
+ m_axis_tlast <= '0';
- case state is
+ CASE state IS
- when IDLE =>
+ WHEN IDLE =>
-- Wait for start of a new packet
- if s_axis_tvalid = '1' then
- if s_axis_tdata = std_logic_vector(to_unsigned(HEADER, 8)) then
+ IF s_axis_tvalid = '1' THEN
+ m_axis_tvalid <= '0';
+ IF s_axis_tdata = STD_LOGIC_VECTOR(to_unsigned(HEADER, 8)) THEN
state <= STREAMING;
- end if;
- end if;
+ END IF;
+ END IF;
+
+ WHEN STREAMING =>
+ IF s_axis_tvalid = '1' THEN
- when STREAMING =>
- if s_axis_tvalid = '1' then
-- End of packet detected
- if s_axis_tdata = std_logic_vector(to_unsigned(FOOTER, 8)) then
- state <= IDLE;
- m_axis_tlast <= '1'; -- Let receiver know packet ends
- else
+ IF s_axis_tdata = STD_LOGIC_VECTOR(to_unsigned(FOOTER, 8)) THEN
+ -- Send the last data and transition to IDLE
+ m_axis_tdata <= buffer_in; -- Send the last buffered data
+ state <= IDLE;
+ m_axis_tlast <= '1'; -- Let receiver know packet ends
+ ELSE
-- Valid payload: send to output
- if buffer_valid = '1' then
- if m_axis_tready = '1' then
- m_axis_tdata <= buffer_in;
- m_axis_tvalid <= '1';
- buffer_valid <= '0'; -- Clear the buffer
- end if;
- else
- if m_axis_tready = '1' then
- m_axis_tdata <= s_axis_tdata;
- m_axis_tvalid <= '1';
- else
- buffer_in <= s_axis_tdata;
- buffer_valid <= '1'; -- Mark buffer as valid
- end if;
- end if;
- end if;
- end if;
+ IF buffer_valid = '1' AND m_axis_tready = '1' THEN
+ m_axis_tdata <= buffer_in;
+ m_axis_tvalid <= '1';
+ buffer_valid <= '0'; -- Clear the buffer
+ END IF;
- end case;
- end if;
- end if;
- end process;
+ buffer_in <= s_axis_tdata;
+ buffer_valid <= '1';
+ END IF;
+ END IF;
-end architecture;
+ END CASE;
+ END IF;
+ END IF;
+ END PROCESS;
+
+END ARCHITECTURE;
\ No newline at end of file
diff --git a/LAB2/src/divider_by_3.vhd b/LAB2/src/divider_by_3.vhd
index 27a37eb..b96076e 100644
--- a/LAB2/src/divider_by_3.vhd
+++ b/LAB2/src/divider_by_3.vhd
@@ -7,11 +7,11 @@ USE IEEE.MATH_REAL.ALL;
ENTITY divider_by_3 IS
GENERIC (
- BIT_DEPTH : INTEGER := 8
+ BIT_DEPTH : INTEGER := 7
);
PORT (
dividend : IN UNSIGNED(BIT_DEPTH + 1 DOWNTO 0);
- gray : OUT UNSIGNED(BIT_DEPTH - 1 DOWNTO 0)
+ result : OUT UNSIGNED(BIT_DEPTH - 1 DOWNTO 0)
);
END divider_by_3;
@@ -20,12 +20,11 @@ ARCHITECTURE Behavioral OF divider_by_3 IS
CONSTANT DIVISION_MULTIPLIER : INTEGER := INTEGER(floor(real(2 ** (BIT_DEPTH + 2)) / 3.0));
-- Constant to calculate the length of the result signal
- CONSTANT RESULT_WIDTH : INTEGER := (2 * BIT_DEPTH) + 2;
+ CONSTANT RESULT_WIDTH : INTEGER := (2 * BIT_DEPTH) + 2; -- 16 bit
-- Signals to hold the sum of the RGB channels and the intermediate results
- SIGNAL rgb_sum_extended : UNSIGNED(BIT_DEPTH + 1 DOWNTO 0) := (OTHERS => '0');
- SIGNAL scaled_result : UNSIGNED(RESULT_WIDTH DOWNTO 0) := (OTHERS => '0');
- SIGNAL grayscale_value : UNSIGNED(BIT_DEPTH - 1 DOWNTO 0) := (OTHERS => '0');
+ SIGNAL sum_extended : UNSIGNED(BIT_DEPTH + 1 DOWNTO 0) := (OTHERS => '0');
+ SIGNAL scaled_result : UNSIGNED(RESULT_WIDTH - 1 DOWNTO 0) := (OTHERS => '0');
BEGIN
-- Explanation of how the division by 3 is performed:
@@ -37,15 +36,12 @@ BEGIN
-- 4. The final grayscale value is extracted from the result and converted back to a std_logic_vector.
-- Calculate the sum of the RGB channels
- rgb_sum_extended <= dividend + TO_UNSIGNED(2, BIT_DEPTH + 2);
+ sum_extended <= dividend + TO_UNSIGNED(2, BIT_DEPTH + 2);
-- Multiply the sum by the precomputed multiplier
- scaled_result <= rgb_sum_extended * TO_UNSIGNED(DIVISION_MULTIPLIER, BIT_DEPTH + 1);
+ scaled_result <= RESIZE(sum_extended * TO_UNSIGNED(DIVISION_MULTIPLIER, BIT_DEPTH + 1), RESULT_WIDTH);
-- Extract the grayscale value from the scaled result by right-shifting
- grayscale_value <= scaled_result(RESULT_WIDTH - 1 DOWNTO RESULT_WIDTH - BIT_DEPTH);
-
- -- Assign the grayscale value to the output
- gray <= grayscale_value;
+ result <= scaled_result(RESULT_WIDTH - 1 DOWNTO RESULT_WIDTH - BIT_DEPTH);
END Behavioral;
\ No newline at end of file
diff --git a/LAB2/src/img_conv.vhd b/LAB2/src/img_conv.vhd
index 731c637..2a8ff72 100644
--- a/LAB2/src/img_conv.vhd
+++ b/LAB2/src/img_conv.vhd
@@ -1,41 +1,177 @@
-library ieee;
-use ieee.std_logic_1164.all;
-use ieee.numeric_std.all;
+LIBRARY ieee;
+USE ieee.std_logic_1164.ALL;
+USE ieee.numeric_std.ALL;
-entity img_conv is
- generic(
- LOG2_N_COLS: POSITIVE :=8;
- LOG2_N_ROWS: POSITIVE :=8
+ENTITY img_conv IS
+ GENERIC (
+ LOG2_N_COLS : POSITIVE := 8;
+ LOG2_N_ROWS : POSITIVE := 8
);
- port (
+ PORT (
- clk : in std_logic;
- aresetn : in std_logic;
+ clk : IN STD_LOGIC;
+ aresetn : IN STD_LOGIC;
- m_axis_tdata : out std_logic_vector(7 downto 0);
- m_axis_tvalid : out std_logic;
- m_axis_tready : in std_logic;
- m_axis_tlast : out std_logic;
-
- conv_addr: out std_logic_vector(LOG2_N_COLS+LOG2_N_ROWS-1 downto 0);
- conv_data: in std_logic_vector(6 downto 0);
+ m_axis_tdata : OUT STD_LOGIC_VECTOR(7 DOWNTO 0);
+ m_axis_tvalid : OUT STD_LOGIC;
+ m_axis_tready : IN STD_LOGIC;
+ m_axis_tlast : OUT STD_LOGIC;
+
+ conv_addr : OUT STD_LOGIC_VECTOR(LOG2_N_COLS + LOG2_N_ROWS - 1 DOWNTO 0);
+ conv_data : IN STD_LOGIC_VECTOR(6 DOWNTO 0);
+
+ start_conv : IN STD_LOGIC;
+ done_conv : OUT STD_LOGIC
- start_conv: in std_logic;
- done_conv: out std_logic
-
);
-end entity img_conv;
+END ENTITY img_conv;
-architecture rtl of img_conv is
+ARCHITECTURE rtl OF img_conv IS
+ TYPE conv_mat_type IS ARRAY(0 TO 2, 0 TO 2) OF INTEGER;
+ CONSTANT conv_mat : conv_mat_type := ((-1, -1, -1),(-1, 8, -1),(-1, -1, -1));
- type conv_mat_type is array(0 to 2, 0 to 2) of integer;
- constant conv_mat : conv_mat_type := ((-1,-1,-1),(-1,8,-1),(-1,-1,-1));
+ -- Definizione della finestra 3x3; ogni pixel è rappresentato da 8 bit
+ TYPE window_array IS ARRAY(0 TO 2, 0 TO 2) OF STD_LOGIC_VECTOR(7 DOWNTO 0);
+ SIGNAL window : window_array := (OTHERS => (OTHERS => (OTHERS => '0')));
-
+ -- Parametri immagine
+ CONSTANT IMG_WIDTH : INTEGER := 2 ** LOG2_N_COLS; -- Larghezza dell'immagine
+ CONSTANT IMG_HEIGHT : INTEGER := 2 ** LOG2_N_ROWS; -- Altezza dell'immagine
-begin
+ -- Indirizzo corrente per la lettura dei pixel
+ SIGNAL current_addr : STD_LOGIC_VECTOR(LOG2_N_COLS + LOG2_N_ROWS - 1 DOWNTO 0);
+ -- Variabili per il calcolo della convoluzione
+ SIGNAL conv_sum : INTEGER := 0; -- Somma dei prodotti
+ SIGNAL conv_out : STD_LOGIC_VECTOR(7 DOWNTO 0); -- Risultato della convoluzione
+ -- Stato della macchina a stati
+ TYPE state_type IS (IDLE, LOAD_PIXEL, COMPUTE, OUTPUT);
+ SIGNAL state : state_type := IDLE;
-end architecture;
+ -- Contatori per riga e colonna
+ SIGNAL row, col : INTEGER RANGE 0 TO IMG_HEIGHT - 1 := 0;
+
+BEGIN
+
+ -- Aggiornamento dell'indirizzo di lettura (mapping riga-colonna)
+ conv_addr <= STD_LOGIC_VECTOR(to_unsigned(row * IMG_WIDTH + col, conv_addr'length));
+
+ -- Processo principale: macchina a stati per la gestione della convoluzione
+ PROCESS (clk, aresetn)
+ BEGIN
+ IF aresetn = '0' THEN
+ -- Reset asincrono: inizializza tutti i segnali
+ state <= IDLE;
+ row <= 0;
+ col <= 0;
+ window <= (OTHERS => (OTHERS => (OTHERS => '0')));
+ conv_sum <= 0;
+ conv_out <= (OTHERS => '0');
+ m_axis_tdata <= (OTHERS => '0');
+ m_axis_tvalid <= '0';
+ m_axis_tlast <= '0';
+ done_conv <= '0';
+ current_addr <= (OTHERS => '0');
+ ELSIF rising_edge(clk) THEN
+ CASE state IS
+
+ -- Stato IDLE: attende il segnale di start per iniziare la convoluzione
+ WHEN IDLE =>
+ m_axis_tvalid <= '0';
+ m_axis_tlast <= '0';
+ IF start_conv = '1' THEN
+ row <= 0;
+ col <= 0;
+ done_conv <= '0';
+ -- Inizializza la finestra a zero per gestire il padding superiore
+ window <= (OTHERS => (OTHERS => (OTHERS => '0')));
+ state <= LOAD_PIXEL;
+ END IF;
+
+ -- Stato LOAD_PIXEL: carica un nuovo pixel e aggiorna la finestra
+ WHEN LOAD_PIXEL =>
+ -- Aggiorna la finestra con il nuovo pixel (conv_data)
+ -- Lo shifting viene realizzato per spostare i dati verso sinistra
+ IF col = 0 THEN
+ -- Per ogni riga della finestra si forza la colonna sinistra a zero
+ FOR i IN 0 TO 2 LOOP
+ window(i)(0) <= (OTHERS => '0');
+ END LOOP;
+ ELSE
+ FOR i IN 0 TO 2 LOOP
+ window(i)(0) <= window(i)(1);
+ window(i)(1) <= window(i)(2);
+ END LOOP;
+ END IF;
+
+ -- Aggiorna la colonna destra della finestra con il nuovo pixel
+ FOR i IN 0 TO 2 LOOP
+ window(i)(2) <= conv_data;
+ END LOOP;
+
+ -- Aggiorna i contatori per scorrere l'immagine
+ IF col = IMG_WIDTH - 1 THEN
+ col <= 0;
+ IF row = IMG_HEIGHT - 1 THEN
+ state <= COMPUTE;
+ ELSE
+ row <= row + 1;
+ END IF;
+ ELSE
+ col <= col + 1;
+ END IF;
+
+ state <= COMPUTE;
+
+ -- Stato COMPUTE: esegue il calcolo della convoluzione
+ WHEN COMPUTE =>
+ -- Gestione dei bordi: imposta il risultato a zero se la finestra non è completa
+ IF (row = 0) OR (row = IMG_HEIGHT - 1) OR (col = 0) OR (col = IMG_WIDTH - 1) THEN
+ conv_sum <= 0;
+ ELSE
+ conv_sum <= 0;
+ -- Moltiplica cella per cella e somma i prodotti
+ FOR i IN 0 TO 2 LOOP
+ FOR j IN 0 TO 2 LOOP
+ conv_sum <= conv_sum + conv_mat(i, j) * to_integer(unsigned(window(i)(j)));
+ END LOOP;
+ END LOOP;
+ END IF;
+
+ -- Saturazione del risultato
+ IF conv_sum < 0 THEN
+ conv_out <= STD_LOGIC_VECTOR(to_unsigned(0, 8));
+ ELSIF conv_sum >= 256 THEN
+ conv_out <= STD_LOGIC_VECTOR(to_unsigned(255, 8));
+ ELSE
+ conv_out <= STD_LOGIC_VECTOR(to_unsigned(conv_sum, 8));
+ END IF;
+
+ state <= OUTPUT;
+
+ -- Stato OUTPUT: invia il risultato tramite l'interfaccia AXIS
+ WHEN OUTPUT =>
+ IF m_axis_tready = '1' THEN
+ m_axis_tdata <= conv_out;
+ m_axis_tvalid <= '1';
+ -- Se siamo sull'ultimo pixel dell'immagine, segnaliamo TLAST e il completamento
+ IF (row = IMG_HEIGHT - 1) AND (col = IMG_WIDTH - 1) THEN
+ m_axis_tlast <= '1';
+ done_conv <= '1';
+ state <= IDLE;
+ ELSE
+ m_axis_tlast <= '0';
+ state <= LOAD_PIXEL;
+ END IF;
+ END IF;
+
+ -- Stato di default: ritorna a IDLE
+ WHEN OTHERS =>
+ state <= IDLE;
+ END CASE;
+ END IF;
+ END PROCESS;
+
+END ARCHITECTURE;
\ No newline at end of file
diff --git a/LAB2/src/rgb2gray.vhd b/LAB2/src/rgb2gray.vhd
index 19718ec..c148ac6 100644
--- a/LAB2/src/rgb2gray.vhd
+++ b/LAB2/src/rgb2gray.vhd
@@ -30,29 +30,30 @@ ARCHITECTURE Behavioral OF rgb2gray IS
COMPONENT divider_by_3
GENERIC (
- BIT_DEPTH : INTEGER := 8
+ BIT_DEPTH : INTEGER := 7
);
PORT (
dividend : IN UNSIGNED(BIT_DEPTH + 1 DOWNTO 0);
- gray : OUT UNSIGNED(BIT_DEPTH - 1 DOWNTO 0));
+ result : OUT UNSIGNED(BIT_DEPTH - 1 DOWNTO 0));
END COMPONENT divider_by_3;
TYPE state_type IS (WAIT_R, WAIT_G, WAIT_B);
SIGNAL state : state_type := WAIT_R;
SIGNAL r_val, g_val : unsigned(7 DOWNTO 0);
- SIGNAL sum : unsigned(9 DOWNTO 0);
- SIGNAL gray : UNSIGNED(7 DOWNTO 0);
+ SIGNAL sum : unsigned(8 DOWNTO 0);
+ SIGNAL gray : UNSIGNED(6 DOWNTO 0);
+ SIGNAL send_data : STD_LOGIC := '0';
BEGIN
DIVIDER : divider_by_3
GENERIC MAP(
- BIT_DEPTH => 8
+ BIT_DEPTH => 7
)
PORT MAP(
dividend => sum,
- gray => gray
+ result => gray
);
PROCESS (clk)
@@ -70,32 +71,43 @@ BEGIN
sum <= (OTHERS => '0');
ELSE
-- Default control signals
- s_axis_tready <= '1';
- m_axis_tlast <= '0';
+ m_axis_tlast <= s_axis_tlast;
+ m_axis_tvalid <= '0';
-- If downstream is ready, send the grayscale pixel
- IF m_axis_tready = '1' THEN
- m_axis_tdata <= STD_LOGIC_VECTOR(gray);
- m_axis_tlast <= s_axis_tlast;
+ IF m_axis_tready = '1' AND send_data = '1' THEN
+ m_axis_tdata <= STD_LOGIC_VECTOR('0' & gray);
+ m_axis_tvalid <= '1';
+ send_data <= '0';
END IF;
CASE state IS
WHEN WAIT_R =>
IF s_axis_tvalid = '1' THEN
r_val <= unsigned(s_axis_tdata);
+
+ IF m_axis_tready = '0' THEN
+ s_axis_tready <= '0';
+ END IF;
+
state <= WAIT_G;
END IF;
WHEN WAIT_G =>
IF s_axis_tvalid = '1' THEN
g_val <= unsigned(s_axis_tdata);
- state <= WAIT_B;
+
+ IF m_axis_tready = '1' THEN
+ s_axis_tready <= '1';
+ state <= WAIT_B;
+ END IF;
END IF;
WHEN WAIT_B =>
IF s_axis_tvalid = '1' THEN
- sum <= ('0' & '0' & r_val) + ('0' & '0' & g_val) + ('0' & '0' & unsigned(s_axis_tdata));
- m_axis_tvalid <= '1';
+ sum <= RESIZE(r_val + g_val + unsigned(s_axis_tdata), 9);
+ send_data <= '1';
+
state <= WAIT_R;
END IF;
diff --git a/LAB2/vivado/rgb2grey_test/rgb2grey_test.xpr b/LAB2/vivado/rgb2grey_test/rgb2grey_test.xpr
index 5326766..a338ead 100644
--- a/LAB2/vivado/rgb2grey_test/rgb2grey_test.xpr
+++ b/LAB2/vivado/rgb2grey_test/rgb2grey_test.xpr
@@ -47,7 +47,7 @@
-
+