Add testbench for LED blinker, enhance bram_writer with state management, and update test script for overflow/underflow handling
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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;
|
||||
Reference in New Issue
Block a user