Line 142... |
Line 142... |
-- transmission buffer --
|
-- transmission buffer --
|
type tx_fifo_t is array (0 to tx_buffer_entries_c-1) of std_ulogic_vector(31+1 downto 0);
|
type tx_fifo_t is array (0 to tx_buffer_entries_c-1) of std_ulogic_vector(31+1 downto 0);
|
type tx_buffer_t is record
|
type tx_buffer_t is record
|
we : std_ulogic; -- write enable
|
we : std_ulogic; -- write enable
|
re : std_ulogic; -- read enable
|
re : std_ulogic; -- read enable
|
wdata : std_ulogic_vector(31 downto 0); -- write data (excluding excluding)
|
wdata : std_ulogic_vector(31 downto 0); -- write data (excluding mode)
|
rdata : std_ulogic_vector(31+1 downto 0); -- read data (including mode)
|
rdata : std_ulogic_vector(31+1 downto 0); -- read data (including mode)
|
--
|
--
|
w_pnt : std_ulogic_vector(index_size_f(tx_buffer_entries_c) downto 0); -- write pointer
|
|
r_pnt : std_ulogic_vector(index_size_f(tx_buffer_entries_c) downto 0); -- read pointer
|
|
match : std_ulogic;
|
|
empty : std_ulogic;
|
|
empty_ff : std_ulogic;
|
|
full : std_ulogic;
|
|
avail : std_ulogic; -- data available?
|
avail : std_ulogic; -- data available?
|
free : std_ulogic; -- free entry available?
|
free : std_ulogic; -- free entry available?
|
free_ff : std_ulogic;
|
free_ff : std_ulogic;
|
|
empty : std_ulogic;
|
|
empty_ff : std_ulogic;
|
--
|
--
|
data : tx_fifo_t; -- fifo memory
|
data : tx_fifo_t; -- fifo memory
|
end record;
|
end record;
|
signal tx_buffer : tx_buffer_t;
|
signal tx_buffer : tx_buffer_t;
|
|
signal fifo_clear : std_ulogic;
|
|
signal fifo_wdata : std_ulogic_vector(31+1 downto 0);
|
|
|
-- serial transmission engine --
|
-- serial transmission engine --
|
type serial_state_t is (S_IDLE, S_INIT, S_GETBIT, S_PULSE);
|
type serial_state_t is (S_IDLE, S_INIT, S_GETBIT, S_PULSE);
|
type serial_t is record
|
type serial_t is record
|
-- state control --
|
-- state control --
|
Line 244... |
Line 242... |
clkgen_en_o <= ctrl.enable;
|
clkgen_en_o <= ctrl.enable;
|
|
|
|
|
-- TX Buffer (FIFO) -----------------------------------------------------------------------
|
-- TX Buffer (FIFO) -----------------------------------------------------------------------
|
-- -------------------------------------------------------------------------------------------
|
-- -------------------------------------------------------------------------------------------
|
instr_prefetch_buffer: process(clk_i)
|
tx_data_fifo: neorv32_fifo
|
begin
|
generic map (
|
if rising_edge(clk_i) then
|
FIFO_DEPTH => tx_buffer_entries_c, -- number of fifo entries; has to be a power of two; min 1
|
|
FIFO_WIDTH => 32+1, -- size of data elements in fifo
|
|
FIFO_RSYNC => true, -- sync read
|
|
FIFO_SAFE => false -- no safe access required (ensured by FIFO-external control)
|
|
)
|
|
port map (
|
|
-- control --
|
|
clk_i => clk_i, -- clock, rising edge
|
|
rstn_i => '1', -- async reset, low-active
|
|
clear_i => fifo_clear, -- sync reset, high-active
|
-- write port --
|
-- write port --
|
if (ctrl.enable = '0') then
|
wdata_i => fifo_wdata, -- write data
|
tx_buffer.w_pnt <= (others => '0');
|
we_i => tx_buffer.we, -- write enable
|
elsif (tx_buffer.we = '1') then
|
free_o => tx_buffer.free, -- at least one entry is free when set
|
tx_buffer.w_pnt <= std_ulogic_vector(unsigned(tx_buffer.w_pnt) + 1);
|
|
end if;
|
|
if (tx_buffer.we = '1') then -- write data
|
|
tx_buffer.data(to_integer(unsigned(tx_buffer.w_pnt(tx_buffer.w_pnt'left-1 downto 0)))) <= ctrl.mode & tx_buffer.wdata;
|
|
end if;
|
|
-- read port --
|
-- read port --
|
if (ctrl.enable = '0') then
|
re_i => tx_buffer.re, -- read enable
|
tx_buffer.r_pnt <= (others => '0');
|
rdata_o => tx_buffer.rdata, -- read data
|
elsif (tx_buffer.re = '1') then
|
avail_o => tx_buffer.avail -- data available when set
|
tx_buffer.r_pnt <= std_ulogic_vector(unsigned(tx_buffer.r_pnt) + 1);
|
);
|
end if;
|
|
tx_buffer.rdata <= tx_buffer.data(to_integer(unsigned(tx_buffer.r_pnt(tx_buffer.r_pnt'left-1 downto 0)))); -- sync read
|
-- helper signals --
|
-- status buffer --
|
fifo_clear <= not ctrl.enable;
|
tx_buffer.empty_ff <= tx_buffer.empty;
|
fifo_wdata <= ctrl.mode & tx_buffer.wdata;
|
tx_buffer.free_ff <= tx_buffer.free;
|
tx_buffer.empty <= not tx_buffer.avail;
|
end if;
|
|
end process instr_prefetch_buffer;
|
|
|
|
-- status --
|
|
tx_buffer.match <= '1' when (tx_buffer.r_pnt(tx_buffer.r_pnt'left-1 downto 0) = tx_buffer.w_pnt(tx_buffer.w_pnt'left-1 downto 0)) else '0';
|
|
tx_buffer.full <= '1' when (tx_buffer.r_pnt(tx_buffer.r_pnt'left) /= tx_buffer.w_pnt(tx_buffer.w_pnt'left)) and (tx_buffer.match = '1') else '0';
|
|
tx_buffer.empty <= '1' when (tx_buffer.r_pnt(tx_buffer.r_pnt'left) = tx_buffer.w_pnt(tx_buffer.w_pnt'left)) and (tx_buffer.match = '1') else '0';
|
|
tx_buffer.free <= not tx_buffer.full;
|
|
tx_buffer.avail <= not tx_buffer.empty;
|
|
|
|
|
|
-- Buffer Status Flag and IRQ Generator ---------------------------------------------------
|
-- Buffer Status Flag and IRQ Generator ---------------------------------------------------
|
-- -------------------------------------------------------------------------------------------
|
-- -------------------------------------------------------------------------------------------
|
-- ctrl.bscon = 0: clear buffer/busy status flag and send IRQ if -> there is at least one free entry in buffer
|
-- ctrl.bscon = 0: clear buffer/busy status flag and send IRQ if -> there is at least one free entry in buffer
|