diff --git a/LAB2/sim/tb_packetizer.vhd b/LAB2/sim/tb_packetizer.vhd
new file mode 100644
index 0000000..9269669
--- /dev/null
+++ b/LAB2/sim/tb_packetizer.vhd
@@ -0,0 +1,208 @@
+----------------------------------------------------------------------------------
+-- Company:
+-- Engineer:
+--
+-- Create Date: 04/21/2025
+-- Design Name:
+-- Module Name: tb_packetizer - Behavioral
+-- Project Name:
+-- Target Devices:
+-- Tool Versions:
+-- Description: Testbench for packetizer
+--
+-- Dependencies:
+--
+-- Revision:
+-- Revision 0.01 - File Created
+-- Additional Comments:
+--
+----------------------------------------------------------------------------------
+LIBRARY IEEE;
+USE IEEE.STD_LOGIC_1164.ALL;
+USE IEEE.NUMERIC_STD.ALL;
+
+ENTITY tb_packetizer IS
+END tb_packetizer;
+
+ARCHITECTURE Behavioral OF tb_packetizer IS
+
+ COMPONENT packetizer IS
+ GENERIC (
+ HEADER : INTEGER := 16#FF#;
+ FOOTER : INTEGER := 16#F1#
+ );
+ 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;
+
+ m_axis_tdata : OUT STD_LOGIC_VECTOR(7 DOWNTO 0);
+ m_axis_tvalid : OUT STD_LOGIC;
+ m_axis_tready : IN STD_LOGIC
+ );
+ END COMPONENT;
+
+ SIGNAL clk : STD_LOGIC := '0';
+ SIGNAL aresetn : STD_LOGIC := '0';
+
+ SIGNAL s_axis_tdata : STD_LOGIC_VECTOR(7 DOWNTO 0) := (OTHERS => '0');
+ SIGNAL s_axis_tvalid : STD_LOGIC := '0';
+ SIGNAL s_axis_tready : STD_LOGIC;
+ SIGNAL s_axis_tlast : STD_LOGIC := '0';
+
+ SIGNAL m_axis_tdata : STD_LOGIC_VECTOR(7 DOWNTO 0);
+ SIGNAL m_axis_tvalid : STD_LOGIC;
+ SIGNAL m_axis_tready : STD_LOGIC := '1';
+
+ -- Stimulus memory
+ TYPE mem_type IS ARRAY(0 TO 7) OF STD_LOGIC_VECTOR(7 DOWNTO 0);
+ SIGNAL mem : mem_type := (
+ 0 => x"10",
+ 1 => x"20",
+ 2 => x"30",
+ 3 => x"4",
+ 4 => x"54",
+ 5 => x"65",
+ 6 => x"73",
+ 7 => x"90"
+ );
+
+ SIGNAL data_index : INTEGER := 0;
+
+ SIGNAL tready_block_req : STD_LOGIC := '0';
+
+BEGIN
+
+ -- Clock generation
+ clk <= NOT clk AFTER 5 ns;
+
+ -- Asynchronous tready block process
+ PROCESS (clk)
+ VARIABLE block_counter : INTEGER := 0;
+ VARIABLE tready_blocked : BOOLEAN := FALSE;
+ BEGIN
+ IF rising_edge(clk) THEN
+ IF tready_block_req = '1' AND NOT tready_blocked THEN
+ tready_blocked := TRUE;
+ block_counter := 0;
+ END IF;
+
+ IF tready_blocked THEN
+ IF block_counter < 9 THEN
+ m_axis_tready <= '0';
+ block_counter := block_counter + 1;
+ ELSE
+ m_axis_tready <= '1';
+ tready_blocked := FALSE;
+ block_counter := 0;
+ END IF;
+ ELSE
+ m_axis_tready <= '1';
+ END IF;
+ END IF;
+ END PROCESS;
+
+ -- DUT instantiation
+ uut: packetizer
+ PORT MAP (
+ clk => clk,
+ aresetn => aresetn,
+
+ s_axis_tdata => s_axis_tdata,
+ s_axis_tvalid => s_axis_tvalid,
+ s_axis_tready => s_axis_tready,
+ s_axis_tlast => s_axis_tlast,
+
+ m_axis_tdata => m_axis_tdata,
+ m_axis_tvalid => m_axis_tvalid,
+ m_axis_tready => m_axis_tready
+ );
+
+ -- Stimulus process
+ PROCESS
+ BEGIN
+ -- Reset
+ aresetn <= '0';
+ WAIT FOR 20 ns;
+ aresetn <= '1';
+ WAIT UNTIL rising_edge(clk);
+
+ -- Start tready block asynchronously after 60 ns
+ WAIT FOR 60 ns;
+ tready_block_req <= '1';
+ WAIT UNTIL rising_edge(clk);
+ tready_block_req <= '0';
+
+ -- Send 4 data words as a packet
+ FOR i IN 0 TO 3 LOOP
+ s_axis_tdata <= mem(i);
+ s_axis_tvalid <= '1';
+ IF i = 3 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;
+ s_axis_tlast <= '0';
+
+ -- Wait a bit, then send another packet of 2 words
+ WAIT FOR 50 ns;
+ FOR i IN 4 TO 5 LOOP
+ s_axis_tdata <= mem(i);
+ s_axis_tvalid <= '1';
+ IF i = 5 THEN
+ s_axis_tlast <= '1';
+ ELSE
+ s_axis_tlast <= '0';
+ END IF;
+ 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';
+
+ -- Start another tready block asynchronously
+ WAIT FOR 40 ns;
+ tready_block_req <= '1';
+ WAIT UNTIL rising_edge(clk);
+ tready_block_req <= '0';
+
+ -- Send packet of 3 words
+ WAIT FOR 30 ns;
+ FOR i IN 5 TO 7 LOOP
+ s_axis_tdata <= mem(i);
+ s_axis_tvalid <= '1';
+ IF i = 7 THEN
+ s_axis_tlast <= '1';
+ ELSE
+ s_axis_tlast <= '0';
+ END IF;
+ 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';
+
+ -- Send packet of 4 words without initial waiting
+ FOR i IN 2 TO 6 LOOP
+ s_axis_tdata <= mem(i);
+ s_axis_tvalid <= '1';
+ IF i = 6 THEN
+ s_axis_tlast <= '1';
+ ELSE
+ s_axis_tlast <= '0';
+ END IF;
+ 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;
+ END PROCESS;
+
+END Behavioral;
\ No newline at end of file
diff --git a/LAB2/src/packetizer.vhd b/LAB2/src/packetizer.vhd
index 7161607..9572529 100644
--- a/LAB2/src/packetizer.vhd
+++ b/LAB2/src/packetizer.vhd
@@ -18,22 +18,21 @@ ENTITY packetizer IS
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_tready : IN STD_LOGIC
);
END ENTITY packetizer;
ARCHITECTURE rtl OF packetizer IS
- TYPE state_type IS (IDLE, SENDING_HEADER, SENDING_DATA, SENDING_FOOTER);
- SIGNAL state : state_type := IDLE;
+ TYPE state_type IS (SENDING_HEADER, STREAMING, SENDING_FOOTER);
+ SIGNAL state : state_type := SENDING_HEADER;
SIGNAL data_buffer : STD_LOGIC_VECTOR(7 DOWNTO 0);
SIGNAL s_axis_tready_int : STD_LOGIC;
SIGNAL m_axis_tvalid_int : STD_LOGIC;
- SIGNAL last_seen : STD_LOGIC := '0';
+ SIGNAL trigger : STD_LOGIC := '0';
BEGIN
@@ -41,75 +40,22 @@ BEGIN
m_axis_tvalid <= m_axis_tvalid_int;
PROCESS (clk)
- VARIABLE trigger : STD_LOGIC := '0';
BEGIN
IF rising_edge(clk) THEN
IF aresetn = '0' THEN
+ state <= SENDING_HEADER;
data_buffer <= (OTHERS => '0');
+ m_axis_tdata <= (OTHERS => '0');
+ m_axis_tvalid_int <= '0';
+
s_axis_tready_int <= '0';
m_axis_tvalid_int <= '0';
- m_axis_tlast <= '0';
ELSE
- m_axis_tlast <= '0';
-
- IF m_axis_tready = '1' THEN
- m_axis_tvalid_int <= '0';
- END IF;
-
- CASE state IS
- WHEN IDLE =>
- IF s_axis_tvalid = '1' AND s_axis_tready_int = '1' THEN
- state <= SENDING_HEADER;
- END IF;
-
- WHEN SENDING_HEADER =>
- IF m_axis_tvalid_int = '0' OR m_axis_tready = '1' THEN
- m_axis_tvalid_int <= '1';
- m_axis_tdata <= STD_LOGIC_VECTOR(to_unsigned(HEADER, 8));
-
- state <= SENDING_DATA;
- END IF;
-
- WHEN SENDING_DATA =>
- IF s_axis_tvalid = '1' AND s_axis_tready_int = '1' THEN
- IF s_axis_tlast = '1' THEN
- last_seen <= '1';
- END IF;
-
- trigger := '1';
- END IF;
-
- IF last_seen = '1' THEN
- state <= SENDING_FOOTER;
- last_seen <= '0';
-
- trigger := '1';
- END IF;
-
- WHEN SENDING_FOOTER =>
- IF m_axis_tvalid_int = '0' OR m_axis_tready = '1' THEN
- m_axis_tvalid_int <= '1';
- m_axis_tlast <= '1';
- m_axis_tdata <= STD_LOGIC_VECTOR(to_unsigned(FOOTER, 8));
-
- state <= IDLE;
- END IF;
-
- END CASE;
-
- -- Output data - master
- 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;
-
- trigger := '0';
- END IF;
-
-- Input data - slave
s_axis_tready_int <= m_axis_tready;
@@ -117,6 +63,52 @@ BEGIN
data_buffer <= s_axis_tdata;
END IF;
+ -- Output data - master
+ 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;
+
+ trigger <= '0';
+ END IF;
+
+ -- State machine for packetization
+ CASE state IS
+
+ WHEN SENDING_HEADER =>
+ 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
+
+ trigger <= '1';
+ state <= STREAMING;
+ END IF;
+
+ WHEN STREAMING =>
+ IF s_axis_tvalid = '1' AND s_axis_tready_int = '1' THEN
+ IF s_axis_tlast = '1' THEN
+ s_axis_tready_int <= '0'; -- Block the slave interface to avoid data loss
+ state <= SENDING_FOOTER;
+ END IF;
+
+ trigger <= '1';
+ END IF;
+
+ 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
+
+ data_buffer <= STD_LOGIC_VECTOR(to_unsigned(FOOTER, 8)); -- Send footer
+ m_axis_tvalid_int <= '1';
+
+ trigger <= '1';
+ state <= SENDING_HEADER;
+ END IF;
+
+ END CASE;
END IF;
END IF;
diff --git a/LAB2/vivado/packetizer_test/packetizer_test.xpr b/LAB2/vivado/packetizer_test/packetizer_test.xpr
new file mode 100644
index 0000000..092d185
--- /dev/null
+++ b/LAB2/vivado/packetizer_test/packetizer_test.xpr
@@ -0,0 +1,214 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Vivado Synthesis Defaults
+
+
+
+
+
+
+
+
+
+
+ Default settings for Implementation.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ default_dashboard
+
+
+
diff --git a/LAB2/vivado/packetizer_test/tb_packetizer_behav.wcfg b/LAB2/vivado/packetizer_test/tb_packetizer_behav.wcfg
new file mode 100644
index 0000000..74e1646
--- /dev/null
+++ b/LAB2/vivado/packetizer_test/tb_packetizer_behav.wcfg
@@ -0,0 +1,92 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ mem[0:7][7:0]
+ mem[0:7][7:0]
+
+
+ clk
+ clk
+
+
+ aresetn
+ aresetn
+
+
+ state
+ state
+ #00FFFF
+ true
+
+
+ data_buffer[7:0]
+ data_buffer[7:0]
+
+
+ s_axis
+ label
+
+
+ s_axis_tdata[7:0]
+ s_axis_tdata[7:0]
+
+
+ s_axis_tvalid
+ s_axis_tvalid
+
+
+ s_axis_tready
+ s_axis_tready
+ #FFD700
+ true
+
+
+ s_axis_tlast
+ s_axis_tlast
+ #0000FF
+ true
+
+
+ m_axis
+ label
+
+
+ m_axis_tdata[7:0]
+ m_axis_tdata[7:0]
+
+
+ m_axis_tvalid
+ m_axis_tvalid
+
+
+ m_axis_tready
+ m_axis_tready
+ #FFD700
+ true
+
+
+ m_axis_tlast
+ m_axis_tlast
+ #0000FF
+ true
+
+