Refactor and update various components in LAB2 design
- Updated node connections in lab_2.bda and pak_depak.bda to correct source and target references. - Modified pak_depak_wrapper.vhd to reflect the correct timestamp. - Rearranged the order of components in pak_depak.bd for clarity and consistency. - Adjusted BRAM writer logic in bram_writer.vhd for improved data handling and comments for clarity. - Enhanced depacketizer.vhd with additional comments and logic adjustments for better data reception. - Refined divider_by_3.vhd to optimize division calculations and improve clarity in comments. - Improved img_conv.vhd with better state management and comments for the convolution process. - Updated led_blinker.vhd to enhance readability and maintainability with clearer comments. - Enhanced packetizer.vhd to improve data handling and added comments for better understanding. - Adjusted rgb2gray.vhd to include standard library comments for consistency. - Updated test.py to improve image processing logic and added visualization for differences. - Added new binary files for test_nopath.exe and archived project files for lab2 and pak_depak. - Updated Vivado project files to ensure correct paths and settings for synthesis and implementation.
This commit is contained in:
@@ -1,6 +1,8 @@
|
||||
---------- DEFAULT LIBRARIES -------
|
||||
LIBRARY ieee;
|
||||
USE ieee.std_logic_1164.ALL;
|
||||
USE ieee.numeric_std.ALL;
|
||||
------------------------------------
|
||||
|
||||
ENTITY bram_writer IS
|
||||
GENERIC (
|
||||
@@ -79,7 +81,7 @@ BEGIN
|
||||
-- Assign AXIS ready signal
|
||||
s_axis_tready <= s_axis_tready_int;
|
||||
|
||||
-- Binding BRAM data to output
|
||||
-- Output only the lower 7 bits of BRAM data
|
||||
conv_data <= bram_data_out(6 DOWNTO 0);
|
||||
|
||||
-- Select BRAM address based on state
|
||||
@@ -116,9 +118,8 @@ BEGIN
|
||||
-- State machine for data handling
|
||||
CASE state IS
|
||||
WHEN IDLE =>
|
||||
-- Wait for valid input data
|
||||
-- Wait for valid input data to start writing
|
||||
IF s_axis_tvalid = '1' AND s_axis_tready_int = '1' THEN
|
||||
-- valid data received, start receiving
|
||||
wr_addr <= (OTHERS => '0');
|
||||
bram_we <= '1'; -- Enable write to BRAM
|
||||
bram_data_in <= s_axis_tdata; -- Write data to BRAM
|
||||
@@ -145,7 +146,7 @@ BEGIN
|
||||
END IF;
|
||||
|
||||
WHEN CHECK_DATA =>
|
||||
-- Check for overflow/underflow
|
||||
-- Check for overflow/underflow after data reception
|
||||
IF overflow_flag = '1' THEN
|
||||
overflow <= '1';
|
||||
overflow_flag <= '0';
|
||||
@@ -156,7 +157,6 @@ BEGIN
|
||||
ELSE
|
||||
-- Data reception complete, start convolution
|
||||
write_ok <= '1';
|
||||
|
||||
s_axis_tready_int <= '0';
|
||||
start_conv <= '1';
|
||||
state <= CONVOLUTION;
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
---------- DEFAULT LIBRARIES -------
|
||||
LIBRARY ieee;
|
||||
USE ieee.std_logic_1164.ALL;
|
||||
USE ieee.numeric_std.ALL;
|
||||
------------------------------------
|
||||
|
||||
ENTITY depacketizer IS
|
||||
|
||||
@@ -21,7 +23,7 @@ ENTITY depacketizer IS
|
||||
m_axis_tready : IN STD_LOGIC;
|
||||
m_axis_tlast : OUT STD_LOGIC
|
||||
);
|
||||
|
||||
|
||||
END ENTITY depacketizer;
|
||||
|
||||
ARCHITECTURE rtl OF depacketizer IS
|
||||
@@ -51,7 +53,7 @@ BEGIN
|
||||
state <= WAITING_HEADER;
|
||||
m_axis_tdata_int <= (OTHERS => '0');
|
||||
m_axis_tlast_int <= '0';
|
||||
s_axis_tready_int <= '1';
|
||||
s_axis_tready_int <= '0';
|
||||
m_axis_tvalid_int <= '0';
|
||||
data_buffer <= (OTHERS => '0');
|
||||
data_ready <= '0';
|
||||
@@ -63,6 +65,7 @@ BEGIN
|
||||
s_axis_tready_int <= '1';
|
||||
m_axis_tvalid_int <= '0';
|
||||
data_ready <= '0';
|
||||
-- Wait for header value to start receiving data
|
||||
IF s_axis_tvalid = '1' AND s_axis_tready_int = '1' THEN
|
||||
IF s_axis_tdata = STD_LOGIC_VECTOR(to_unsigned(HEADER, 8)) THEN
|
||||
state <= RECEIVING;
|
||||
@@ -75,6 +78,7 @@ BEGIN
|
||||
m_axis_tdata_int <= data_buffer;
|
||||
m_axis_tvalid_int <= '1';
|
||||
|
||||
-- Check for footer value to signal end of packet
|
||||
IF s_axis_tdata = STD_LOGIC_VECTOR(to_unsigned(FOOTER, 8)) THEN
|
||||
m_axis_tlast_int <= '1';
|
||||
state <= WAITING_HEADER;
|
||||
|
||||
@@ -16,35 +16,22 @@ ENTITY divider_by_3 IS
|
||||
END divider_by_3;
|
||||
|
||||
ARCHITECTURE Behavioral OF divider_by_3 IS
|
||||
-- Constant to calculate the multiplier for approximating division by 3
|
||||
CONSTANT DIVISION_MULTIPLIER : INTEGER := INTEGER(floor(real(2 ** (BIT_DEPTH + 2)) / 3.0));
|
||||
CONSTANT N : INTEGER := BIT_DEPTH + 3;
|
||||
CONSTANT DIVISION_MULTIPLIER : INTEGER := INTEGER(round(real(2 ** N) / 3.0));
|
||||
CONSTANT OFFSET : INTEGER := 2 ** (N - 1);
|
||||
|
||||
-- Constant to calculate the length of the result signal
|
||||
CONSTANT RESULT_WIDTH : INTEGER := (2 * BIT_DEPTH) + 2; -- 16 bit
|
||||
CONSTANT MULT_WIDTH : INTEGER := BIT_DEPTH + 1 + N;
|
||||
|
||||
-- Signals to hold the sum of the RGB channels and the intermediate results
|
||||
SIGNAL sum_extended : UNSIGNED(BIT_DEPTH + 1 DOWNTO 0) := (OTHERS => '0');
|
||||
SIGNAL scaled_result : UNSIGNED(RESULT_WIDTH - 1 DOWNTO 0) := (OTHERS => '0');
|
||||
SIGNAL mult_result : UNSIGNED(MULT_WIDTH - 1 DOWNTO 0);
|
||||
SIGNAL sum_with_offset : UNSIGNED(MULT_WIDTH - 1 DOWNTO 0);
|
||||
BEGIN
|
||||
-- Moltiplicazione senza perdita di bit
|
||||
mult_result <= dividend * TO_UNSIGNED(DIVISION_MULTIPLIER, N - 1);
|
||||
|
||||
-- Explanation of how the division by 3 is performed:
|
||||
-- 1. The sum of the RGB channels (R + G + B) is calculated and extended to avoid overflow.
|
||||
-- 2. The sum is multiplied by a precomputed constant (DIVISION_MULTIPLIER), which is approximately equal to (2^(BIT_DEPTH + 2)) / 3.
|
||||
-- This scales the value up to prepare for the division.
|
||||
-- 3. The result of the multiplication is then right-shifted by a specific number of bits.
|
||||
-- This operation effectively scales the value back down, approximating the division by 3.
|
||||
-- 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
|
||||
-- The addition of 2 is used to implement rounding when dividing by 3.
|
||||
-- This is a common technique: adding half of the divisor (3/2 ? 2) before division
|
||||
-- ensures that the result is rounded to the nearest integer instead of truncated.
|
||||
sum_extended <= dividend + TO_UNSIGNED(2, BIT_DEPTH + 2);
|
||||
|
||||
-- Multiply the sum by the precomputed multiplier
|
||||
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
|
||||
result <= scaled_result(RESULT_WIDTH - 1 DOWNTO RESULT_WIDTH - BIT_DEPTH);
|
||||
-- Somma con offset senza perdita di bit
|
||||
sum_with_offset <= mult_result + TO_UNSIGNED(OFFSET, MULT_WIDTH);
|
||||
|
||||
-- Estrazione risultato arrotondato
|
||||
result <= sum_with_offset(MULT_WIDTH - 2 DOWNTO MULT_WIDTH - BIT_DEPTH -1);
|
||||
|
||||
END Behavioral;
|
||||
@@ -1,6 +1,8 @@
|
||||
---------- DEFAULT LIBRARIES -------
|
||||
LIBRARY ieee;
|
||||
USE ieee.std_logic_1164.ALL;
|
||||
USE ieee.numeric_std.ALL;
|
||||
------------------------------------
|
||||
|
||||
ENTITY img_conv IS
|
||||
GENERIC (
|
||||
@@ -27,18 +29,23 @@ ENTITY img_conv IS
|
||||
END ENTITY img_conv;
|
||||
|
||||
ARCHITECTURE rtl OF img_conv IS
|
||||
-- 3x3 convolution matrix (kernel)
|
||||
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));
|
||||
|
||||
-- Offset arrays for kernel position relative to current pixel
|
||||
TYPE offset_array IS ARRAY(0 TO 2) OF INTEGER;
|
||||
CONSTANT offset : offset_array := (-1, 0, 1);
|
||||
|
||||
-- State machine for convolution process
|
||||
TYPE state_type IS (IDLE, START_CONVOLUTING, CONVOLUTING, WAIT_READY);
|
||||
SIGNAL state : state_type := IDLE;
|
||||
|
||||
-- Current column and row in the image
|
||||
SIGNAL col : UNSIGNED(LOG2_N_COLS - 1 DOWNTO 0) := (OTHERS => '0');
|
||||
SIGNAL row : UNSIGNED(LOG2_N_ROWS - 1 DOWNTO 0) := (OTHERS => '0');
|
||||
|
||||
-- Indices for kernel matrix position (previous, current, next)
|
||||
SIGNAL col_mat_idx_prv : INTEGER := 0;
|
||||
SIGNAL row_mat_idx_prv : INTEGER := 0;
|
||||
|
||||
@@ -48,10 +55,12 @@ ARCHITECTURE rtl OF img_conv IS
|
||||
SIGNAL col_mat_idx_nxt : INTEGER := 0;
|
||||
SIGNAL row_mat_idx_nxt : INTEGER := 0;
|
||||
|
||||
-- Accumulators for convolution result
|
||||
SIGNAL conv_data_out, conv_data_int, conv_data_mul : SIGNED(10 DOWNTO 0) := (OTHERS => '0');
|
||||
|
||||
SIGNAL m_axis_tvalid_int : STD_LOGIC;
|
||||
|
||||
-- Control signals for data flow and pipelining
|
||||
SIGNAL trigger, prepare_data, ready_data, send_data : STD_LOGIC := '0';
|
||||
SIGNAL tlast : STD_LOGIC := '0';
|
||||
SIGNAL save_data : STD_LOGIC := '0';
|
||||
@@ -65,7 +74,7 @@ BEGIN
|
||||
IF rising_edge(clk) THEN
|
||||
IF aresetn = '0' THEN
|
||||
|
||||
-- Reset all signals
|
||||
-- Reset all signals and state
|
||||
state <= IDLE;
|
||||
|
||||
col <= (OTHERS => '0');
|
||||
@@ -100,13 +109,13 @@ BEGIN
|
||||
conv_addr <= (OTHERS => '0');
|
||||
|
||||
ELSE
|
||||
-- Default values for signals
|
||||
-- Default values for signals at each clock
|
||||
done_conv <= '0';
|
||||
m_axis_tlast <= '0';
|
||||
|
||||
CASE state IS
|
||||
WHEN IDLE =>
|
||||
-- Default values in IDLE
|
||||
-- Wait for start_conv signal to begin convolution
|
||||
done_conv <= '0';
|
||||
m_axis_tlast <= '0';
|
||||
m_axis_tvalid_int <= '0';
|
||||
@@ -125,7 +134,7 @@ BEGIN
|
||||
IF start_conv = '1' THEN
|
||||
state <= START_CONVOLUTING;
|
||||
|
||||
-- Reset the convolution matrix position
|
||||
-- Reset image pointers
|
||||
row <= (OTHERS => '0');
|
||||
col <= (OTHERS => '0');
|
||||
|
||||
@@ -156,6 +165,7 @@ BEGIN
|
||||
END IF;
|
||||
|
||||
WHEN START_CONVOLUTING =>
|
||||
-- Start the convolution process or resume from the previous state
|
||||
conv_addr <= STD_LOGIC_VECTOR(
|
||||
TO_UNSIGNED(
|
||||
(TO_INTEGER(col) + offset(col_mat_idx_nxt)) +
|
||||
@@ -167,7 +177,7 @@ BEGIN
|
||||
state <= CONVOLUTING;
|
||||
|
||||
WHEN CONVOLUTING =>
|
||||
-- Convolution operation: accumulate the result of current pixel and kernel coefficient
|
||||
-- Perform convolution: multiply input by kernel coefficient and accumulate
|
||||
conv_addr <= STD_LOGIC_VECTOR(
|
||||
TO_UNSIGNED(
|
||||
(TO_INTEGER(col) + offset(col_mat_idx_nxt)) +
|
||||
@@ -191,7 +201,7 @@ BEGIN
|
||||
trigger <= '0';
|
||||
|
||||
WHEN WAIT_READY =>
|
||||
-- Wait for m_axis_tready signal to be asserted before sending data and continue convolution
|
||||
-- Wait for m_axis_tready signal before sending data and continuing
|
||||
IF m_axis_tready = '1' THEN
|
||||
conv_addr <= STD_LOGIC_VECTOR(
|
||||
TO_UNSIGNED(
|
||||
@@ -205,6 +215,7 @@ BEGIN
|
||||
state <= CONVOLUTING;
|
||||
END IF;
|
||||
|
||||
-- Save convolution result only once per WAIT_READY state
|
||||
IF save_data = '0' THEN
|
||||
conv_data_mul <= RESIZE(
|
||||
SIGNED('0' & conv_data) * TO_SIGNED(conv_mat(col_mat_idx_prv, row_mat_idx_prv), 5),
|
||||
@@ -228,11 +239,12 @@ BEGIN
|
||||
m_axis_tvalid_int <= '0';
|
||||
END IF;
|
||||
|
||||
-- Wait for m_axis_tready signal to be asserted before continuing convolution
|
||||
-- If output not ready, wait before continuing
|
||||
IF m_axis_tready = '0' AND m_axis_tvalid_int = '1' THEN
|
||||
state <= WAIT_READY;
|
||||
END IF;
|
||||
|
||||
-- Send data when ready and output interface is available
|
||||
IF send_data = '1' AND (m_axis_tvalid_int = '0' OR m_axis_tready = '1') THEN
|
||||
m_axis_tvalid_int <= '1';
|
||||
|
||||
@@ -243,6 +255,7 @@ BEGIN
|
||||
tlast <= '0';
|
||||
END IF;
|
||||
|
||||
-- Clamp output to 0..127 range
|
||||
IF conv_data_out < 0 THEN
|
||||
m_axis_tdata <= STD_LOGIC_VECTOR(TO_UNSIGNED(0, m_axis_tdata'length));
|
||||
ELSIF conv_data_out > 127 THEN
|
||||
@@ -256,8 +269,9 @@ BEGIN
|
||||
send_data <= '0';
|
||||
END IF;
|
||||
|
||||
-- Main kernel/image sweep logic
|
||||
IF state = CONVOLUTING OR state = START_CONVOLUTING OR (state = WAIT_READY AND m_axis_tready = '1') THEN
|
||||
-- Update convolution matrix position, image position and check for zero padding
|
||||
-- Update kernel and image indices, handle zero padding and end conditions
|
||||
IF col_mat_idx_nxt = 1 AND col = (2 ** LOG2_N_COLS - 1) THEN
|
||||
IF row_mat_idx_nxt = 1 AND row = (2 ** LOG2_N_ROWS - 1) THEN
|
||||
-- Last pixel and last kernel position: finish convolution
|
||||
@@ -323,10 +337,12 @@ BEGIN
|
||||
|
||||
END IF;
|
||||
|
||||
prepare_data <= trigger; -- Pipeline trigger for data output waiting for last data
|
||||
-- Pipeline control for output data
|
||||
prepare_data <= trigger;
|
||||
ready_data <= prepare_data;
|
||||
send_data <= ready_data;
|
||||
|
||||
-- Update previous and current kernel indices
|
||||
row_mat_idx_prv <= row_mat_idx;
|
||||
col_mat_idx_prv <= col_mat_idx;
|
||||
|
||||
|
||||
@@ -1,78 +1,86 @@
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
use ieee.numeric_std.all;
|
||||
use ieee.math_real.all;
|
||||
---------- DEFAULT LIBRARIES -------
|
||||
LIBRARY ieee;
|
||||
USE ieee.std_logic_1164.ALL;
|
||||
USE ieee.numeric_std.ALL;
|
||||
USE ieee.math_real.ALL;
|
||||
------------------------------------
|
||||
|
||||
entity led_blinker is
|
||||
generic (
|
||||
CLK_PERIOD_NS : positive := 10;
|
||||
BLINK_PERIOD_MS : positive := 1000;
|
||||
N_BLINKS : positive := 4
|
||||
ENTITY led_blinker IS
|
||||
GENERIC (
|
||||
CLK_PERIOD_NS : POSITIVE := 10;
|
||||
BLINK_PERIOD_MS : POSITIVE := 1000;
|
||||
N_BLINKS : POSITIVE := 4
|
||||
);
|
||||
port (
|
||||
clk : in std_logic;
|
||||
aresetn : in std_logic;
|
||||
start_blink : in std_logic;
|
||||
led : out std_logic
|
||||
PORT (
|
||||
clk : IN STD_LOGIC;
|
||||
aresetn : IN STD_LOGIC;
|
||||
start_blink : IN STD_LOGIC;
|
||||
led : OUT STD_LOGIC
|
||||
);
|
||||
end entity;
|
||||
END ENTITY;
|
||||
|
||||
architecture rtl of led_blinker is
|
||||
-- Calcoli per larghezze e valori massimi
|
||||
constant CLK_PER_MS : integer := 1_000_000 / CLK_PERIOD_NS;
|
||||
constant MAX_COUNT : integer := CLK_PER_MS * BLINK_PERIOD_MS;
|
||||
constant CNT_WIDTH : integer := integer(ceil(log2(real(MAX_COUNT))));
|
||||
constant BLINK_WIDTH : integer := integer(ceil(log2(real(N_BLINKS + 1))));
|
||||
ARCHITECTURE rtl OF led_blinker IS
|
||||
-- Calculations for widths and maximum values
|
||||
CONSTANT CLK_PER_MS : INTEGER := 1_000_000 / CLK_PERIOD_NS; -- Clock cycles per millisecond
|
||||
CONSTANT MAX_COUNT : INTEGER := CLK_PER_MS * BLINK_PERIOD_MS; -- Counter max value for one blink period
|
||||
CONSTANT CNT_WIDTH : INTEGER := INTEGER(ceil(log2(real(MAX_COUNT)))); -- Bit width for counter
|
||||
CONSTANT BLINK_WIDTH : INTEGER := INTEGER(ceil(log2(real(N_BLINKS + 1)))); -- Bit width for blink counter
|
||||
|
||||
signal counter : unsigned(CNT_WIDTH-1 downto 0) := (others => '0');
|
||||
signal blink_cnt : unsigned(BLINK_WIDTH-1 downto 0) := (others => '0');
|
||||
signal blinking : std_logic := '0';
|
||||
signal led_reg : std_logic := '0';
|
||||
SIGNAL counter : unsigned(CNT_WIDTH - 1 DOWNTO 0) := (OTHERS => '0'); -- Main blink period counter
|
||||
SIGNAL blink_cnt : unsigned(BLINK_WIDTH - 1 DOWNTO 0) := (OTHERS => '0'); -- Number of completed blinks
|
||||
SIGNAL blinking : STD_LOGIC := '0'; -- Indicates if blinking is active
|
||||
SIGNAL led_reg : STD_LOGIC := '0'; -- Register for LED output
|
||||
|
||||
signal start_prev : std_logic := '0';
|
||||
signal start_edge : std_logic;
|
||||
SIGNAL start_prev : STD_LOGIC := '0'; -- Previous value of start_blink
|
||||
SIGNAL start_edge : STD_LOGIC; -- Rising edge detector for start_blink
|
||||
|
||||
begin
|
||||
BEGIN
|
||||
-- Output assignment
|
||||
led <= led_reg;
|
||||
|
||||
process(clk, aresetn)
|
||||
begin
|
||||
if aresetn = '0' then
|
||||
counter <= (others => '0');
|
||||
blink_cnt <= (others => '0');
|
||||
blinking <= '0';
|
||||
led_reg <= '0';
|
||||
-- Main process: handles blinking logic and state
|
||||
PROCESS (clk, aresetn)
|
||||
BEGIN
|
||||
IF aresetn = '0' THEN
|
||||
-- Asynchronous reset: clear all registers and outputs
|
||||
counter <= (OTHERS => '0');
|
||||
blink_cnt <= (OTHERS => '0');
|
||||
blinking <= '0';
|
||||
led_reg <= '0';
|
||||
start_prev <= '0';
|
||||
start_edge <= '0';
|
||||
|
||||
elsif rising_edge(clk) then
|
||||
-- Rileva fronte di salita di start_blink
|
||||
start_edge <= start_blink and not start_prev;
|
||||
ELSIF rising_edge(clk) THEN
|
||||
-- Detect rising edge on start_blink input
|
||||
start_edge <= start_blink AND NOT start_prev;
|
||||
start_prev <= start_blink;
|
||||
|
||||
if blinking = '0' then
|
||||
if start_edge = '1' then
|
||||
blinking <= '1';
|
||||
counter <= (others => '0');
|
||||
blink_cnt <= (others => '0');
|
||||
led_reg <= '1';
|
||||
end if;
|
||||
else -- blinking = '1'
|
||||
if counter = to_unsigned(MAX_COUNT - 1, counter'length) then
|
||||
counter <= (others => '0');
|
||||
led_reg <= not led_reg;
|
||||
IF blinking = '0' THEN
|
||||
-- Idle state: wait for start_blink rising edge to begin blinking
|
||||
IF start_edge = '1' THEN
|
||||
blinking <= '1';
|
||||
counter <= (OTHERS => '0');
|
||||
blink_cnt <= (OTHERS => '0');
|
||||
led_reg <= '1'; -- Start with LED ON
|
||||
END IF;
|
||||
ELSE -- blinking = '1'
|
||||
-- Blinking state: count clock cycles for ON/OFF periods
|
||||
IF counter = to_unsigned(MAX_COUNT - 1, counter'length) THEN
|
||||
counter <= (OTHERS => '0');
|
||||
led_reg <= NOT led_reg; -- Toggle LED state
|
||||
|
||||
if led_reg = '1' then -- fine fase ON
|
||||
IF led_reg = '1' THEN -- End of ON phase
|
||||
blink_cnt <= blink_cnt + 1;
|
||||
if blink_cnt + 1 = to_unsigned(N_BLINKS, blink_cnt'length) then
|
||||
blinking <= '0';
|
||||
led_reg <= '0';
|
||||
end if;
|
||||
end if;
|
||||
else
|
||||
counter <= counter + 1;
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
end architecture;
|
||||
-- Check if required number of blinks is reached
|
||||
IF blink_cnt + 1 = to_unsigned(N_BLINKS, blink_cnt'length) THEN
|
||||
blinking <= '0'; -- Stop blinking
|
||||
led_reg <= '0'; -- Ensure LED is OFF at end
|
||||
END IF;
|
||||
END IF;
|
||||
ELSE
|
||||
counter <= counter + 1; -- Increment counter
|
||||
END IF;
|
||||
END IF;
|
||||
END IF;
|
||||
END PROCESS;
|
||||
END ARCHITECTURE;
|
||||
@@ -1,6 +1,8 @@
|
||||
---------- DEFAULT LIBRARIES -------
|
||||
LIBRARY ieee;
|
||||
USE ieee.std_logic_1164.ALL;
|
||||
USE ieee.numeric_std.ALL;
|
||||
------------------------------------
|
||||
|
||||
ENTITY packetizer IS
|
||||
GENERIC (
|
||||
@@ -32,7 +34,7 @@ ARCHITECTURE rtl OF packetizer IS
|
||||
SIGNAL s_axis_tready_int : STD_LOGIC;
|
||||
SIGNAL m_axis_tvalid_int : STD_LOGIC;
|
||||
|
||||
SIGNAL trigger : STD_LOGIC := '0';
|
||||
SIGNAL trigger : STD_LOGIC := '0'; -- Used to control when to send data
|
||||
|
||||
BEGIN
|
||||
|
||||
@@ -45,57 +47,62 @@ BEGIN
|
||||
IF rising_edge(clk) THEN
|
||||
IF aresetn = '0' THEN
|
||||
state <= SENDING_HEADER;
|
||||
|
||||
data_buffer <= (OTHERS => '0');
|
||||
|
||||
m_axis_tdata <= (OTHERS => '0');
|
||||
|
||||
s_axis_tready_int <= '0';
|
||||
m_axis_tvalid_int <= '0';
|
||||
|
||||
ELSE
|
||||
|
||||
-- Input data - slave
|
||||
s_axis_tready_int <= m_axis_tready;
|
||||
|
||||
IF s_axis_tvalid = '1' AND s_axis_tready_int = '1' THEN
|
||||
data_buffer <= s_axis_tdata;
|
||||
END IF;
|
||||
|
||||
-- Output data - master
|
||||
-- Clear valid flag when master interface is ready
|
||||
IF m_axis_tready = '1' THEN
|
||||
m_axis_tvalid_int <= '0';
|
||||
END IF;
|
||||
|
||||
IF trigger = '1' AND (m_axis_tvalid_int = '0' OR m_axis_tready = '1') THEN
|
||||
m_axis_tvalid_int <= '1';
|
||||
m_axis_tdata <= data_buffer;
|
||||
-- Send data when triggered
|
||||
IF trigger = '1' THEN
|
||||
IF (m_axis_tvalid_int = '0' OR m_axis_tready = '1') THEN
|
||||
m_axis_tvalid_int <= '1';
|
||||
m_axis_tdata <= data_buffer;
|
||||
s_axis_tready_int <= '1'; -- Enable slave interface
|
||||
|
||||
trigger <= '0';
|
||||
trigger <= '0';
|
||||
ELSE
|
||||
s_axis_tready_int <= '0'; -- Block slave interface to avoid data loss
|
||||
END IF;
|
||||
END IF;
|
||||
|
||||
-- State machine for packetization
|
||||
CASE state IS
|
||||
|
||||
WHEN SENDING_HEADER =>
|
||||
s_axis_tready_int <= '1'; -- Enable slave interface
|
||||
IF s_axis_tvalid = '1' AND s_axis_tready_int = '1' THEN
|
||||
m_axis_tdata <= STD_LOGIC_VECTOR(to_unsigned(HEADER, 8)); -- Prepare header
|
||||
m_axis_tvalid_int <= '1'; --Send header
|
||||
m_axis_tdata <= STD_LOGIC_VECTOR(to_unsigned(HEADER, 8)); -- Send header
|
||||
m_axis_tvalid_int <= '1';
|
||||
s_axis_tready_int <= m_axis_tready;
|
||||
|
||||
IF s_axis_tlast = '1' THEN
|
||||
s_axis_tready_int <= '0'; -- Block the slave interface to avoid data loss
|
||||
s_axis_tready_int <= '0'; -- Block slave interface if last
|
||||
state <= SENDING_FOOTER;
|
||||
ELSE
|
||||
state <= STREAMING;
|
||||
END IF;
|
||||
|
||||
|
||||
trigger <= '1';
|
||||
END IF;
|
||||
|
||||
WHEN STREAMING =>
|
||||
IF s_axis_tvalid = '1' AND s_axis_tready_int = '1' THEN
|
||||
s_axis_tready_int <= m_axis_tready;
|
||||
|
||||
IF s_axis_tlast = '1' THEN
|
||||
s_axis_tready_int <= '0'; -- Block the slave interface to avoid data loss
|
||||
s_axis_tready_int <= '0'; -- Block slave interface if last
|
||||
state <= SENDING_FOOTER;
|
||||
END IF;
|
||||
|
||||
@@ -104,7 +111,7 @@ BEGIN
|
||||
|
||||
WHEN SENDING_FOOTER =>
|
||||
IF m_axis_tvalid_int = '0' OR m_axis_tready = '1' THEN
|
||||
s_axis_tready_int <= '0'; -- Block the slave interface to avoid data loss
|
||||
s_axis_tready_int <= '0'; -- Block slave interface
|
||||
|
||||
data_buffer <= STD_LOGIC_VECTOR(to_unsigned(FOOTER, 8)); -- Send footer
|
||||
m_axis_tvalid_int <= '1';
|
||||
@@ -119,4 +126,4 @@ BEGIN
|
||||
|
||||
END PROCESS;
|
||||
|
||||
END ARCHITECTURE rtl;
|
||||
END ARCHITECTURE;
|
||||
@@ -1,6 +1,8 @@
|
||||
---------- DEFAULT LIBRARIES -------
|
||||
LIBRARY IEEE;
|
||||
USE IEEE.STD_LOGIC_1164.ALL;
|
||||
USE IEEE.NUMERIC_STD.ALL;
|
||||
------------------------------------
|
||||
|
||||
ENTITY rgb2gray IS
|
||||
PORT (
|
||||
|
||||
Reference in New Issue
Block a user