OpenCores
URL https://opencores.org/ocsvn/neorv32/neorv32/trunk

Subversion Repositories neorv32

[/] [neorv32/] [trunk/] [rtl/] [core/] [neorv32_uart.vhd] - Diff between revs 68 and 69

Go to most recent revision | Show entire file | Details | Blame | View Log

Rev 68 Rev 69
Line 229... Line 229...
  end record;
  end record;
  signal rx_buffer : rx_buffer_t;
  signal rx_buffer : rx_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 rx_irq, tx_irq : irq_t;
  signal rx_irq, tx_irq : irq_t;
 
 
begin
begin
 
 
Line 488... Line 487...
 
 
        end case;
        end case;
 
 
        -- overrun flag --
        -- overrun flag --
        if (rden = '1') and (addr = uart_id_rtx_addr_c) then -- clear when reading data register
        if (rden = '1') and (addr = uart_id_rtx_addr_c) then -- clear when reading data register
          rx_engine.overr <= '1';
 
        elsif (rx_buffer.we = '1') and (rx_buffer.free = '0') then -- write to full FIFO
 
          rx_engine.overr <= '0';
          rx_engine.overr <= '0';
 
        elsif (rx_buffer.we = '1') and (rx_buffer.free = '0') then -- write to full FIFO
 
          rx_engine.overr <= '1';
        end if;
        end if;
      end if;
      end if;
    end if;
    end if;
  end process uart_rx_engine;
  end process uart_rx_engine;
 
 
Line 554... Line 553...
  end process flow_control_buffer;
  end process flow_control_buffer;
 
 
 
 
  -- Interrupt Generator --------------------------------------------------------------------
  -- Interrupt Generator --------------------------------------------------------------------
  -- -------------------------------------------------------------------------------------------
  -- -------------------------------------------------------------------------------------------
  irq_type: process(ctrl, tx_buffer, rx_buffer)
  irq_type: process(ctrl, tx_buffer, rx_buffer, tx_engine.done)
  begin
  begin
    -- TX interrupt --
    -- TX interrupt --
    if (UART_TX_FIFO = 1) then
    if (UART_TX_FIFO = 1) or (ctrl(ctrl_tx_irq_c) = '0') then
      tx_irq.set <= tx_buffer.free; -- fire IRQ if FIFO is not full
      tx_irq.set <= tx_buffer.free and tx_engine.done; -- fire IRQ if FIFO is not full
    else
 
      if (ctrl(ctrl_tx_irq_c) = '1') then
 
        tx_irq.set <= not tx_buffer.half; -- fire IRQ if FIFO is less than half-full
 
      else
      else
        tx_irq.set <= tx_buffer.free; -- fire IRQ if FIFO is not full
      tx_irq.set <= (not tx_buffer.half) and tx_engine.done; -- fire IRQ if FIFO is less than half-full
      end if;
 
    end if;
    end if;
 
 
    -- RX interrupt --
    -- RX interrupt --
    if (UART_RX_FIFO = 1) then
    if (UART_RX_FIFO = 1) or (ctrl(ctrl_rx_irq_c) = '0') then
      rx_irq.set <= rx_buffer.avail; -- fire IRQ if FIFO is not empty
      rx_irq.set <= rx_buffer.avail; -- fire IRQ if FIFO is not empty
    else
    else
      if (ctrl(ctrl_rx_irq_c) = '1') then
 
        rx_irq.set <= rx_buffer.half; -- fire IRQ if FIFO is at least half-full
        rx_irq.set <= rx_buffer.half; -- fire IRQ if FIFO is at least half-full
      else
 
        rx_irq.set <= rx_buffer.avail; -- fire IRQ is FIFO is not empty
 
      end if;
 
    end if;
    end if;
  end process irq_type;
  end process irq_type;
 
 
  -- 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(ctrl_en_c) = '0') then
      if (ctrl(ctrl_en_c) = '0') then
        rx_irq.pending <= '0';
        tx_irq.buf <= "00";
        tx_irq.pending <= '0';
        rx_irq.buf <= "00";
      else
      else
        -- TX --
        tx_irq.buf <= tx_irq.buf(0) & tx_irq.set;
        if (tx_irq.set = '1') and (tx_engine.done = '1') then -- evaluate IRQ condition when TX is done with current sending
        rx_irq.buf <= rx_irq.buf(0) & rx_irq.set;
          tx_irq.pending <= '1';
 
        elsif (tx_irq.clr = '1') then
 
          tx_irq.pending <= '0';
 
        end if;
        end if;
        -- RX --
 
        if (rx_irq.set = '1') and (rx_engine.done = '1') then -- evaluate IRQ condition when RX is done with current receiving
 
          rx_irq.pending <= '1';
 
        elsif (rx_irq.clr = '1') then
 
          rx_irq.pending <= '0';
 
        end if;
        end if;
      end if;
  end process irq_detect;
    end if;
 
  end process irq_generator;
 
 
 
  -- IRQ requests to CPU --
  -- IRQ requests to CPU --
  irq_txd_o <= tx_irq.pending;
  irq_txd_o <= '1' when (tx_irq.buf = "01") else '0';
  irq_rxd_o <= rx_irq.pending;
  irq_rxd_o <= '1' when (rx_irq.buf = "01") else '0';
 
 
  -- IRQ acknowledge --
 
  tx_irq.clr <= '1' when (tx_buffer.we = '1') or ((wren = '1') and (addr = uart_id_ctrl_addr_c)) else '0'; -- write to data reg OR write to control reg
 
  rx_irq.clr <= '1' when (rx_buffer.re = '1') or ((wren = '1') and (addr = uart_id_ctrl_addr_c)) else '0'; -- read from data reg OR write to control reg
 
 
 
 
 
  -- SIMULATION Transmitter -----------------------------------------------------------------
  -- SIMULATION Transmitter -----------------------------------------------------------------
  -- -------------------------------------------------------------------------------------------
  -- -------------------------------------------------------------------------------------------
-- pragma translate_off
-- pragma translate_off

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.