Line 153... |
Line 153... |
end record;
|
end record;
|
signal tx_buffer : tx_buffer_t;
|
signal tx_buffer : tx_buffer_t;
|
|
|
-- interrupt generator --
|
-- interrupt generator --
|
type irq_t is record
|
type irq_t is record
|
pending : std_ulogic; -- pending interrupt request
|
|
set : std_ulogic;
|
set : std_ulogic;
|
clr : std_ulogic;
|
buf : std_ulogic_vector(1 downto 0);
|
end record;
|
end record;
|
signal irq : irq_t;
|
signal irq : irq_t;
|
|
|
-- serial transmission engine --
|
-- serial transmission engine --
|
type serial_state_t is (S_IDLE, S_INIT, S_GETBIT, S_PULSE, S_STROBE);
|
type serial_state_t is (S_IDLE, S_INIT, S_GETBIT, S_PULSE, S_STROBE);
|
Line 248... |
Line 247... |
tx_buffer.clear <= not ctrl.enable;
|
tx_buffer.clear <= not ctrl.enable;
|
|
|
|
|
-- IRQ Generator --------------------------------------------------------------------------
|
-- IRQ Generator --------------------------------------------------------------------------
|
-- -------------------------------------------------------------------------------------------
|
-- -------------------------------------------------------------------------------------------
|
irq_select: process(ctrl, tx_buffer)
|
irq_select: process(ctrl, tx_buffer, serial.done)
|
begin
|
begin
|
if (FIFO_DEPTH = 1) then
|
if (FIFO_DEPTH = 1) or (ctrl.irq_conf = '1') then
|
irq.set <= tx_buffer.free; -- fire IRQ if FIFO is empty
|
irq.set <= tx_buffer.free and serial.done; -- fire IRQ if FIFO is empty
|
else
|
else
|
if (ctrl.irq_conf = '0') then -- fire IRQ if FIFO is less than half-full
|
irq.set <= not tx_buffer.half; -- fire IRQ if FIFO is less than half-full
|
irq.set <= not tx_buffer.half;
|
|
else -- fire IRQ if FIFO is empty
|
|
irq.set <= tx_buffer.free;
|
|
end if;
|
|
end if;
|
end if;
|
end process irq_select;
|
end process irq_select;
|
|
|
-- Interrupt Arbiter --
|
-- Interrupt Edge Detector --
|
irq_generator: process(clk_i)
|
irq_detect: process(clk_i)
|
begin
|
begin
|
if rising_edge(clk_i) then
|
if rising_edge(clk_i) then
|
if (ctrl.enable = '0') then
|
if (ctrl.enable = '0') then
|
irq.pending <= '0';
|
irq.buf <= "00";
|
else
|
else
|
if (irq.set = '1') and (serial.done = '1') then -- evaluate IRQ condition when transmitter is done again
|
irq.buf <= irq.buf(0) & irq.set;
|
irq.pending <= '1';
|
|
elsif (irq.clr = '1') then
|
|
irq.pending <= '0';
|
|
end if;
|
|
end if;
|
end if;
|
end if;
|
end if;
|
end process irq_generator;
|
end process irq_detect;
|
|
|
-- IRQ request to CPU --
|
-- IRQ request to CPU --
|
irq_o <= irq.pending;
|
irq_o <= '1' when (irq.buf = "01") else '0';
|
|
|
-- IRQ acknowledge --
|
|
irq.clr <= '1' when (wren = '1') else '0'; -- write data or control register
|
|
|
|
|
|
-- TX Buffer (FIFO) -----------------------------------------------------------------------
|
-- TX Buffer (FIFO) -----------------------------------------------------------------------
|
-- -------------------------------------------------------------------------------------------
|
-- -------------------------------------------------------------------------------------------
|
tx_data_fifo: neorv32_fifo
|
tx_data_fifo: neorv32_fifo
|