Enhance bram_writer: add image size parameter, improve state machine for data handling, and refine signal management for better performance
This commit is contained in:
141
LAB2/sim/tb_bram_writer.vhd
Normal file
141
LAB2/sim/tb_bram_writer.vhd
Normal file
@@ -0,0 +1,141 @@
|
|||||||
|
----------------------------------------------------------------------------------
|
||||||
|
-- Company:
|
||||||
|
-- Engineer:
|
||||||
|
--
|
||||||
|
-- Create Date: 04/17/2025
|
||||||
|
-- Design Name:
|
||||||
|
-- Module Name: tb_bram_writer - sim
|
||||||
|
-- Project Name:
|
||||||
|
-- Target Devices:
|
||||||
|
-- Tool Versions:
|
||||||
|
-- Description: Testbench for bram_writer, stimulus and timing inspired by tb_img_conv.vhd
|
||||||
|
--
|
||||||
|
-- Dependencies:
|
||||||
|
--
|
||||||
|
-- Revision:
|
||||||
|
-- Revision 0.01 - File Created
|
||||||
|
-- Additional Comments:
|
||||||
|
--
|
||||||
|
----------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
LIBRARY ieee;
|
||||||
|
USE ieee.std_logic_1164.ALL;
|
||||||
|
USE ieee.numeric_std.ALL;
|
||||||
|
|
||||||
|
ENTITY tb_bram_writer IS
|
||||||
|
END ENTITY;
|
||||||
|
|
||||||
|
ARCHITECTURE sim OF tb_bram_writer IS
|
||||||
|
|
||||||
|
-- Testbench constants
|
||||||
|
CONSTANT ADDR_WIDTH : POSITIVE := 4;
|
||||||
|
CONSTANT IMG_SIZE : POSITIVE := 2; -- Small size for quick simulation
|
||||||
|
|
||||||
|
-- Signals for DUT
|
||||||
|
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 conv_addr : STD_LOGIC_VECTOR(ADDR_WIDTH-1 DOWNTO 0) := (OTHERS => '0');
|
||||||
|
SIGNAL conv_data : STD_LOGIC_VECTOR(6 DOWNTO 0);
|
||||||
|
SIGNAL start_conv : STD_LOGIC;
|
||||||
|
SIGNAL done_conv : STD_LOGIC := '0';
|
||||||
|
SIGNAL write_ok : STD_LOGIC;
|
||||||
|
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;
|
||||||
|
|
||||||
|
BEGIN
|
||||||
|
|
||||||
|
-- Clock generation
|
||||||
|
clk <= not clk after 5 ns;
|
||||||
|
|
||||||
|
-- Instantiate DUT
|
||||||
|
bram_writer_inst: bram_writer
|
||||||
|
GENERIC MAP (
|
||||||
|
ADDR_WIDTH => ADDR_WIDTH,
|
||||||
|
IMG_SIZE => IMG_SIZE
|
||||||
|
)
|
||||||
|
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,
|
||||||
|
conv_addr => conv_addr,
|
||||||
|
conv_data => conv_data,
|
||||||
|
start_conv => start_conv,
|
||||||
|
done_conv => done_conv,
|
||||||
|
write_ok => write_ok,
|
||||||
|
overflow => overflow,
|
||||||
|
underflow => underflow
|
||||||
|
);
|
||||||
|
|
||||||
|
-- Stimulus process
|
||||||
|
stimulus : process
|
||||||
|
begin
|
||||||
|
-- Initial reset
|
||||||
|
aresetn <= '0';
|
||||||
|
wait for 10 ns;
|
||||||
|
aresetn <= '1';
|
||||||
|
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));
|
||||||
|
s_axis_tvalid <= '1';
|
||||||
|
if i = IMG_SIZE*IMG_SIZE-1 then
|
||||||
|
s_axis_tlast <= '1';
|
||||||
|
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';
|
||||||
|
|
||||||
|
-- Wait for write_ok and start_conv
|
||||||
|
wait until write_ok = '1';
|
||||||
|
wait until rising_edge(clk);
|
||||||
|
|
||||||
|
-- Simulate convolution done
|
||||||
|
done_conv <= '1';
|
||||||
|
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;
|
||||||
|
|
||||||
|
END ARCHITECTURE;
|
||||||
@@ -1,116 +1,161 @@
|
|||||||
library ieee;
|
LIBRARY ieee;
|
||||||
use ieee.std_logic_1164.all;
|
USE ieee.std_logic_1164.ALL;
|
||||||
use ieee.numeric_std.all;
|
USE ieee.numeric_std.ALL;
|
||||||
|
|
||||||
entity bram_writer is
|
ENTITY bram_writer IS
|
||||||
generic(
|
GENERIC (
|
||||||
ADDR_WIDTH: POSITIVE :=16
|
ADDR_WIDTH : POSITIVE := 16;
|
||||||
|
IMG_SIZE : POSITIVE := 256 -- Image size (256x256)
|
||||||
);
|
);
|
||||||
port (
|
PORT (
|
||||||
clk : in std_logic;
|
clk : IN STD_LOGIC;
|
||||||
aresetn : in std_logic;
|
aresetn : IN STD_LOGIC;
|
||||||
|
|
||||||
s_axis_tdata : in std_logic_vector(7 downto 0);
|
s_axis_tdata : IN STD_LOGIC_VECTOR(7 DOWNTO 0);
|
||||||
s_axis_tvalid : in std_logic;
|
s_axis_tvalid : IN STD_LOGIC;
|
||||||
s_axis_tready : out std_logic;
|
s_axis_tready : OUT STD_LOGIC;
|
||||||
s_axis_tlast : in std_logic;
|
s_axis_tlast : IN STD_LOGIC;
|
||||||
|
|
||||||
conv_addr: in std_logic_vector(ADDR_WIDTH-1 downto 0);
|
conv_addr : IN STD_LOGIC_VECTOR(ADDR_WIDTH - 1 DOWNTO 0);
|
||||||
conv_data: out std_logic_vector(6 downto 0);
|
conv_data : OUT STD_LOGIC_VECTOR(6 DOWNTO 0);
|
||||||
|
|
||||||
start_conv: out std_logic;
|
start_conv : OUT STD_LOGIC;
|
||||||
done_conv: in std_logic;
|
done_conv : IN STD_LOGIC;
|
||||||
|
|
||||||
write_ok : out std_logic;
|
write_ok : OUT STD_LOGIC;
|
||||||
overflow : out std_logic;
|
overflow : OUT STD_LOGIC;
|
||||||
underflow: out std_logic
|
underflow : OUT STD_LOGIC
|
||||||
|
|
||||||
);
|
);
|
||||||
end entity bram_writer;
|
END ENTITY bram_writer;
|
||||||
|
|
||||||
architecture rtl of bram_writer is
|
ARCHITECTURE rtl OF bram_writer IS
|
||||||
|
|
||||||
component bram_controller is
|
COMPONENT bram_controller IS
|
||||||
generic (
|
GENERIC (
|
||||||
ADDR_WIDTH: POSITIVE :=16
|
ADDR_WIDTH : POSITIVE := 16
|
||||||
);
|
);
|
||||||
port (
|
PORT (
|
||||||
clk : in std_logic;
|
clk : IN STD_LOGIC;
|
||||||
aresetn : in std_logic;
|
aresetn : IN STD_LOGIC;
|
||||||
|
|
||||||
addr: in std_logic_vector(ADDR_WIDTH-1 downto 0);
|
addr : IN STD_LOGIC_VECTOR(ADDR_WIDTH - 1 DOWNTO 0);
|
||||||
dout: out std_logic_vector(7 downto 0);
|
dout : OUT STD_LOGIC_VECTOR(7 DOWNTO 0);
|
||||||
din: in std_logic_vector(7 downto 0);
|
din : IN STD_LOGIC_VECTOR(7 DOWNTO 0);
|
||||||
we: in std_logic
|
we : IN STD_LOGIC
|
||||||
);
|
);
|
||||||
end component;
|
END COMPONENT;
|
||||||
|
|
||||||
TYPE state_type is (IDLE, RECEIVING, CONVOLUTION);
|
TYPE state_type IS (IDLE, RECEIVING, CONVOLUTION);
|
||||||
SIGNAL state : state_type := IDLE;
|
SIGNAL state : state_type := IDLE;
|
||||||
|
|
||||||
SIGNAL s_axis_tready_int : std_logic := '0';
|
SIGNAL s_axis_tready_int : STD_LOGIC := '0';
|
||||||
|
|
||||||
SIGNAL bram_addr : std_logic_vector(ADDR_WIDTH-1 downto 0) := (others => '0'); -- Indirizzo BRAM
|
SIGNAL bram_addr : STD_LOGIC_VECTOR(ADDR_WIDTH - 1 DOWNTO 0) := (OTHERS => '0'); -- BRAM address
|
||||||
SIGNAL bram_we : std_logic := '0'; -- Segnale di scrittura per il BRAM
|
SIGNAL bram_we : STD_LOGIC := '0'; -- Write enable signal for BRAM
|
||||||
|
|
||||||
SIGNAL wr_addr : std_logic_vector(ADDR_WIDTH-1 downto 0) := (others => '0'); -- Indirizzo di scrittura BRAM
|
SIGNAL wr_addr : STD_LOGIC_VECTOR(ADDR_WIDTH - 1 DOWNTO 0) := (OTHERS => '0'); -- Write address for BRAM
|
||||||
|
|
||||||
begin
|
BEGIN
|
||||||
|
|
||||||
BRAM_CTRL: bram_controller
|
-- Instantiate BRAM controller
|
||||||
generic map (
|
BRAM_CTRL : bram_controller
|
||||||
ADDR_WIDTH => ADDR_WIDTH
|
GENERIC MAP(
|
||||||
)
|
ADDR_WIDTH => ADDR_WIDTH
|
||||||
port map (
|
)
|
||||||
clk => clk,
|
PORT MAP(
|
||||||
aresetn => aresetn,
|
clk => clk,
|
||||||
addr => bram_addr,
|
aresetn => aresetn,
|
||||||
dout => conv_data,
|
addr => bram_addr,
|
||||||
din => s_axis_tdata,
|
dout => conv_data,
|
||||||
we => bram_we
|
din => s_axis_tdata,
|
||||||
);
|
we => bram_we
|
||||||
|
);
|
||||||
|
|
||||||
-- AXIS
|
-- Assign AXIS ready signal
|
||||||
s_axis_tready <= s_axis_tready_int
|
s_axis_tready <= s_axis_tready_int;
|
||||||
|
|
||||||
-- Gestione addr BRAM
|
-- Select BRAM address based on state
|
||||||
with state select bram_addr <= conv_addr when CONVOLUTION,
|
WITH state SELECT bram_addr <= conv_addr WHEN CONVOLUTION,
|
||||||
wr_addr when Others;
|
wr_addr WHEN OTHERS;
|
||||||
|
|
||||||
process(clk)
|
PROCESS (clk)
|
||||||
begin
|
BEGIN
|
||||||
if rising_edge(clk) then
|
IF rising_edge(clk) THEN
|
||||||
if aresetn = '0' then
|
IF aresetn = '0' THEN
|
||||||
|
-- Reset all signals and state
|
||||||
state <= IDLE;
|
state <= IDLE;
|
||||||
|
|
||||||
s_axis_tready_int <= '0';
|
s_axis_tready_int <= '0';
|
||||||
|
|
||||||
bram_we <= '0';
|
bram_we <= '0';
|
||||||
wr_addr <= (others => '0');
|
wr_addr <= (OTHERS => '0');
|
||||||
|
|
||||||
start_conv <= '0';
|
start_conv <= '0';
|
||||||
write_ok <= '0';
|
write_ok <= '0';
|
||||||
overflow <= '0';
|
overflow <= '0';
|
||||||
underflow <= '0';
|
underflow <= '0';
|
||||||
else
|
ELSE
|
||||||
|
-- Default assignments for each clock cycle
|
||||||
start_conv <= '0';
|
start_conv <= '0';
|
||||||
|
bram_we <= '0';
|
||||||
write_ok <= '0';
|
write_ok <= '0';
|
||||||
overflow <= '0';
|
overflow <= '0';
|
||||||
underflow <= '0';
|
underflow <= '0';
|
||||||
|
s_axis_tready_int <= '1';
|
||||||
|
|
||||||
case state is
|
-- State machine for data handling
|
||||||
when IDLE =>
|
CASE state IS
|
||||||
s_axis_tready_int <= '1';
|
WHEN IDLE =>
|
||||||
|
-- Wait for valid input data
|
||||||
|
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
|
||||||
|
state <= RECEIVING;
|
||||||
|
END IF;
|
||||||
|
|
||||||
|
WHEN RECEIVING =>
|
||||||
|
-- Receiving data, increment write address
|
||||||
|
IF s_axis_tvalid = '1' AND s_axis_tready_int = '1' THEN
|
||||||
|
-- Check for overflow: if address reaches max image size
|
||||||
|
IF unsigned(wr_addr) = (IMG_SIZE ** 2 - 1) THEN
|
||||||
|
overflow <= '1';
|
||||||
|
state <= IDLE;
|
||||||
|
ELSE
|
||||||
|
-- Increment write address and write data to BRAM
|
||||||
|
wr_addr <= STD_LOGIC_VECTOR(unsigned(wr_addr) + 1);
|
||||||
|
bram_we <= '1'; -- Enable write to BRAM
|
||||||
|
|
||||||
when RECEIVING =>
|
-- Check for last data signal
|
||||||
|
IF s_axis_tlast = '1' THEN
|
||||||
|
-- Check for underflow: if not enough data received
|
||||||
|
IF unsigned(wr_addr) < (IMG_SIZE ** 2 - 2) THEN
|
||||||
|
underflow <= '1';
|
||||||
|
state <= IDLE;
|
||||||
|
ELSE
|
||||||
|
-- Data reception complete, start convolution
|
||||||
|
write_ok <= '1';
|
||||||
|
|
||||||
|
s_axis_tready_int <= '0';
|
||||||
|
start_conv <= '1';
|
||||||
|
state <= CONVOLUTION;
|
||||||
|
END IF;
|
||||||
|
END IF;
|
||||||
|
END IF;
|
||||||
|
END IF;
|
||||||
|
|
||||||
when CONVOLUTION =>
|
WHEN CONVOLUTION =>
|
||||||
|
-- Wait for convolution to finish
|
||||||
|
s_axis_tready_int <= '0';
|
||||||
|
|
||||||
end case;
|
IF done_conv = '1' THEN
|
||||||
end if;
|
state <= IDLE;
|
||||||
end if;
|
END IF;
|
||||||
end process;
|
|
||||||
|
|
||||||
end architecture;
|
END CASE;
|
||||||
|
END IF;
|
||||||
|
END IF;
|
||||||
|
END PROCESS;
|
||||||
|
|
||||||
|
END ARCHITECTURE;
|
||||||
Reference in New Issue
Block a user