Add testbench for LED blinker, enhance bram_writer with state management, and update test script for overflow/underflow handling

This commit is contained in:
2025-04-17 22:55:49 +02:00
parent 667632bfa3
commit a054085341
7 changed files with 185 additions and 44 deletions

View File

@@ -46,7 +46,7 @@ ARCHITECTURE rtl OF bram_writer IS
);
END COMPONENT;
TYPE state_type IS (IDLE, RECEIVING, CHECK_START_CONV, CONVOLUTION);
TYPE state_type IS (IDLE, RECEIVING, CHECK_DATA, CONVOLUTION);
SIGNAL state : state_type := IDLE;
SIGNAL s_axis_tready_int : STD_LOGIC := '0';
@@ -58,6 +58,8 @@ ARCHITECTURE rtl OF bram_writer IS
SIGNAL wr_addr : STD_LOGIC_VECTOR(ADDR_WIDTH - 1 DOWNTO 0) := (OTHERS => '0'); -- Write address for BRAM
SIGNAL overflow_flag : STD_LOGIC := '0'; -- Overflow flag for BRAM write
BEGIN
-- Instantiate BRAM controller
@@ -100,6 +102,8 @@ BEGIN
write_ok <= '0';
overflow <= '0';
underflow <= '0';
overflow_flag <= '0';
ELSE
-- Default assignments for each clock cycle
start_conv <= '0';
@@ -126,24 +130,27 @@ BEGIN
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
bram_data_in <= s_axis_tdata; -- Write data to BRAM
overflow_flag <= '1';
END IF;
-- Check for last data signal
IF s_axis_tlast = '1' THEN
state <= CHECK_START_CONV;
END IF;
-- Increment write address and write data to BRAM
wr_addr <= STD_LOGIC_VECTOR(unsigned(wr_addr) + 1);
bram_we <= '1'; -- Enable write to BRAM
bram_data_in <= s_axis_tdata; -- Write data to BRAM
-- Check for last data signal
IF s_axis_tlast = '1' THEN
state <= CHECK_DATA;
END IF;
END IF;
WHEN CHECK_START_CONV =>
-- Check for underflow: if not enough data received
IF unsigned(wr_addr) < (IMG_SIZE ** 2 - 2) THEN
WHEN CHECK_DATA =>
-- Check for overflow/underflow
IF overflow_flag = '1' THEN
overflow <= '1';
overflow_flag <= '0';
state <= IDLE;
ELSIF unsigned(wr_addr) < (IMG_SIZE ** 2 - 1) THEN
underflow <= '1';
state <= IDLE;
ELSE

View File

@@ -1,28 +1,78 @@
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
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
clk : in std_logic;
aresetn : in std_logic;
start_blink : in std_logic;
led : out std_logic
);
end entity led_blinker;
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))));
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 start_prev : std_logic := '0';
signal start_edge : std_logic;
begin
led <= led_reg;
process(clk, aresetn)
begin
if aresetn = '0' then
counter <= (others => '0');
blink_cnt <= (others => '0');
blinking <= '0';
led_reg <= '0';
start_prev <= '0';
start_edge <= '0';
end architecture;
elsif rising_edge(clk) then
-- Rileva fronte di salita di start_blink
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 led_reg = '1' then -- fine fase ON
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;