Refactor bram_writer: streamline entity definition, remove unused signals, and enhance state management for improved clarity and functionality

This commit is contained in:
2025-04-17 17:25:21 +02:00
parent 9bf8c21957
commit 1d226709ac

View File

@@ -1,191 +1,116 @@
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 -- Dimensione immagine NxN
); );
PORT ( port (
clk : IN STD_LOGIC; clk : in std_logic;
aresetn : IN STD_LOGIC; aresetn : in std_logic;
-- Interfaccia AXI Stream per ricezione dati 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;
-- Interfaccia di lettura BRAM per il modulo di convoluzione 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); -- solo 7 bit usati
-- Controllo avvio/fine convoluzione 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;
overflow : out std_logic;
underflow: out std_logic
-- LED di stato (come da immagine)
write_ok : OUT STD_LOGIC;
overflow : 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
-- Componente BRAM (controller) 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;
CONSTANT total_px_expected : unsigned(ADDR_WIDTH - 1 DOWNTO 0) := to_unsigned(IMG_SIZE ** 2 - 1, ADDR_WIDTH); -- IMG_SIZE * IMG_SIZE TYPE state_type is (IDLE, RECEIVING, CONVOLUTION);
TYPE state_type IS (IDLE, RECEIVING, CHECK_START_CONV, CONVOLUTION);
SIGNAL state : state_type := IDLE; SIGNAL state : state_type := IDLE;
-- Registri di stato e segnale interno SIGNAL s_axis_tready_int : std_logic := '0';
signal addr_write : UNSIGNED(ADDR_WIDTH DOWNTO 0) := (OTHERS => '0'); -- Indirizzo BRAM
SIGNAL addr_bram : STD_LOGIC_VECTOR(ADDR_WIDTH - 1 DOWNTO 0) := (OTHERS => '0'); -- Indirizzo BRAM
SIGNAL wr_enable : STD_LOGIC := '0'; -- Segnale di scrittura BRAM SIGNAL bram_addr : std_logic_vector(ADDR_WIDTH-1 downto 0) := (others => '0'); -- Indirizzo BRAM
SIGNAL din_reg : STD_LOGIC_VECTOR(7 DOWNTO 0) := (OTHERS => '0'); -- Dato da scrivere in BRAM SIGNAL bram_we : std_logic := '0'; -- Segnale di scrittura per il BRAM
SIGNAL flag_of : STD_LOGIC := '0'; -- Flag overflow (se addr_count > total_px_expected)
SIGNAL dout_bram : STD_LOGIC_VECTOR(7 DOWNTO 0); -- Dato letto dalla BRAM SIGNAL wr_addr : std_logic_vector(ADDR_WIDTH-1 downto 0) := (others => '0'); -- Indirizzo di scrittura BRAM
SIGNAL s_axis_tready_int : STD_LOGIC; begin
BEGIN BRAM_CTRL: bram_controller
generic map (
-- Instanziazione BRAM (scrive e legge) ADDR_WIDTH => ADDR_WIDTH
BRAM_CTRL : bram_controller )
GENERIC MAP( port map (
ADDR_WIDTH => ADDR_WIDTH clk => clk,
) aresetn => aresetn,
PORT MAP( addr => bram_addr,
clk => clk, dout => conv_data,
aresetn => aresetn, din => s_axis_tdata,
addr => addr_bram, we => bram_we
dout => dout_bram, );
din => din_reg,
we => wr_enable
);
-- AXIS -- AXIS
s_axis_tready <= s_axis_tready_int; s_axis_tready <= s_axis_tready_int
-- Segnale di lettura BRAM per il modulo di convoluzione -- Gestione addr BRAM
conv_data <= dout_bram(6 DOWNTO 0); with state select bram_addr <= conv_addr when CONVOLUTION,
wr_addr when Others;
-- FSM principale 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 sincrono
state <= IDLE; state <= IDLE;
addr_bram <= (OTHERS => '0');
addr_write <= (OTHERS => '0');
wr_enable <= '0';
write_ok <= '0';
overflow <= '0';
underflow <= '0';
start_conv <= '0';
flag_of <= '0';
s_axis_tready_int <= '0'; s_axis_tready_int <= '0';
ELSE bram_we <= '0';
-- Valori di default ogni ciclo wr_addr <= (others => '0');
wr_enable <= '0';
start_conv <= '0';
write_ok <= '0';
overflow <= '0';
underflow <= '0';
else
start_conv <= '0'; start_conv <= '0';
write_ok <= '0'; write_ok <= '0';
overflow <= '0'; overflow <= '0';
underflow <= '0'; underflow <= '0';
addr_bram <= conv_addr; -- Passa indirizzo al modulo di convoluzione case state is
when IDLE =>
s_axis_tready_int <= '1';
CASE state IS
WHEN IDLE => when RECEIVING =>
addr_write <= (OTHERS => '0');
flag_of <= '0'; -- Reset flag overflow
s_axis_tready_int <= '1'; -- Pronto a ricevere dati
IF s_axis_tvalid = '1' AND s_axis_tready_int = '1' THEN
-- Registra dato ricevuto e scrive in BRAM
din_reg <= s_axis_tdata;
addr_bram <= STD_LOGIC_VECTOR(addr_write(ADDR_WIDTH - 1 DOWNTO 0));
wr_enable <= '1';
s_axis_tready_int <= '1'; -- Pronto a ricevere nuovi dati when CONVOLUTION =>
state <= RECEIVING; end case;
END IF; end if;
end if;
end process;
WHEN RECEIVING => -- Stato RICEZIONE (legge dati da AXIS) end architecture;
IF s_axis_tvalid = '1' AND s_axis_tready_int = '1' THEN
-- Registra dato ricevuto e scrive in BRAM
din_reg <= s_axis_tdata;
addr_bram <= STD_LOGIC_VECTOR(addr_write(ADDR_WIDTH - 1 DOWNTO 0));
wr_enable <= '1';
addr_write <= addr_write + 1;
s_axis_tready_int <= '1'; -- Pronto a ricevere nuovi dati
-- Se <20> l'ultimo pixel del pacchetto
IF s_axis_tlast = '1' THEN
state <= CHECK_START_CONV;
END IF;
END IF;
WHEN CHECK_START_CONV => -- Controllo overflow/underflow
s_axis_tready_int <= '0';
IF flag_of = '1' THEN
overflow <= '1'; -- LED overflow
state <= IDLE; -- Torna a stato IDLE
ELSIF addr_write < total_px_expected THEN
underflow <= '1'; -- LED underflow
state <= IDLE; -- Torna a stato IDLE
ELSIF addr_write = total_px_expected THEN
write_ok <= '1'; -- LED OK
start_conv <= '1'; -- Segnale per far partire modulo Conv
state <= CONVOLUTION; -- Vai a start convoluzione
END IF;
WHEN CONVOLUTION => -- Avvia convoluzione
s_axis_tready_int <= '0';
IF done_conv = '1' THEN
state <= IDLE;
s_axis_tready_int <= '1';
END IF;
END CASE;
-- il controllo viene eseguito qui nel caso in cui addr_write vada in overflow e risulti quindi minore di total_px_expected
IF addr_write > total_px_expected AND flag_of = '0' THEN
flag_of <= '1';
END IF;
END IF;
END IF;
END PROCESS;
END ARCHITECTURE;