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

Subversion Repositories neorv32

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

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

Rev 68 Rev 69
Line 151... Line 151...
  signal tx_fifo_half  : std_ulogic_vector(7 downto 0);
  signal tx_fifo_half  : std_ulogic_vector(7 downto 0);
 
 
  -- interrupt generator --
  -- interrupt generator --
  type detect_t is array (0 to 7) of std_ulogic_vector(1 downto 0);
  type detect_t is array (0 to 7) of std_ulogic_vector(1 downto 0);
  type irq_t is record
  type irq_t is record
    pending : std_ulogic; -- pending interrupt request
 
    detect  : detect_t; -- rising-edge detector
    detect  : detect_t; -- rising-edge detector
    trigger : std_ulogic_vector(7 downto 0);
    trigger : std_ulogic_vector(7 downto 0);
    set     : std_ulogic_vector(7 downto 0);
    set     : std_ulogic_vector(7 downto 0);
    clr     : std_ulogic;
 
  end record;
  end record;
  signal rx_irq, tx_irq : irq_t;
  signal rx_irq, tx_irq : irq_t;
 
 
begin
begin
 
 
Line 259... Line 257...
  fifo_clear <= not enable;
  fifo_clear <= not enable;
 
 
 
 
  -- Interrupt Generator --------------------------------------------------------------------
  -- Interrupt Generator --------------------------------------------------------------------
  -- -------------------------------------------------------------------------------------------
  -- -------------------------------------------------------------------------------------------
  irq_type: process(irq_rx_mode, rx_fifo_avail, rx_fifo_half,
  -- interrupt trigger type / condition --
                    irq_tx_mode, tx_fifo_free,  tx_fifo_half)
  irq_type: process(irq_rx_mode, rx_fifo_avail, rx_fifo_half, irq_tx_mode, tx_fifo_free, tx_fifo_half, tx_fifo_we)
  begin
  begin
    -- RX interrupt --
    -- RX interrupt --
    rx_irq.trigger <= (others => '0');
    rx_irq.trigger <= (others => '0');
    for i in 0 to SLINK_NUM_RX-1 loop
    for i in 0 to SLINK_NUM_RX-1 loop
      if (SLINK_RX_FIFO = 1) then
      if (SLINK_RX_FIFO = 1) or (irq_rx_mode(i) = '0') then
        rx_irq.trigger(i) <= rx_fifo_avail(i); -- fire if any RX_FIFO is not empty
        rx_irq.trigger(i) <= rx_fifo_avail(i); -- fire if any RX_FIFO is not empty (= data available)
      else
      else
        if (irq_rx_mode(i) = '0') then -- fire if any RX_FIFO is at least half-full
 
          rx_irq.trigger(i) <= rx_fifo_half(i);
          rx_irq.trigger(i) <= rx_fifo_half(i);
        else -- fire if any RX_FIFO is not empty (= data available)
 
          rx_irq.trigger(i) <= rx_fifo_avail(i);
 
        end if;
 
      end if;
      end if;
    end loop;
    end loop;
    -- TX interrupt --
    -- TX interrupt --
    tx_irq.trigger <= (others => '0');
    tx_irq.trigger <= (others => '0');
    for i in 0 to SLINK_NUM_TX-1 loop
    for i in 0 to SLINK_NUM_TX-1 loop
      if (SLINK_TX_FIFO = 1) then
      if (SLINK_TX_FIFO = 1) or (irq_tx_mode(i) = '0') then
        tx_irq.trigger(i) <= tx_fifo_free(i); -- fire if any TX_FIFO is not full
        tx_irq.trigger(i) <= tx_fifo_free(i) and tx_fifo_we(i); -- fire if any TX_FIFO is not full (= free buffer space available)
      else
      else
        if (irq_tx_mode(i) = '0') then -- fire if any TX_FIFO is less than half-full
 
          tx_irq.trigger(i) <= not tx_fifo_half(i);
          tx_irq.trigger(i) <= not tx_fifo_half(i);
        else -- fire if any TX_FIFO is not full (= free buffer space available)
 
          tx_irq.trigger(i) <= tx_fifo_free(i);
 
        end if;
 
      end if;
      end if;
    end loop;
    end loop;
  end process irq_type;
  end process irq_type;
 
 
  -- interrupt trigger --
  -- edge detector - sync --
  irq_trigger_sync: process(clk_i)
  irq_edge_detect_sync: process(clk_i)
  begin
  begin
    if rising_edge(clk_i) then
    if rising_edge(clk_i) then
      -- RX --
      -- RX --
      rx_irq.detect <= (others => (others => '0')); -- default
 
      if (enable = '1') then
 
        for i in 0 to SLINK_NUM_RX-1 loop
        for i in 0 to SLINK_NUM_RX-1 loop
 
        if (enable = '1') and (irq_rx_en(i) = '1') then
          rx_irq.detect(i) <= rx_irq.detect(i)(0) & rx_irq.trigger(i);
          rx_irq.detect(i) <= rx_irq.detect(i)(0) & rx_irq.trigger(i);
        end loop;
        else
 
          rx_irq.detect(i) <= "00";
      end if;
      end if;
 
      end loop;
      -- TX --
      -- TX --
      tx_irq.detect <= (others => (others => '0')); -- default
 
      if (enable = '1') then
 
        for i in 0 to SLINK_NUM_TX-1 loop
        for i in 0 to SLINK_NUM_TX-1 loop
 
        if (enable = '1') and (irq_tx_en(i) = '1') then
          tx_irq.detect(i) <= tx_irq.detect(i)(0) & tx_irq.trigger(i);
          tx_irq.detect(i) <= tx_irq.detect(i)(0) & tx_irq.trigger(i);
        end loop;
        else
 
          tx_irq.detect(i) <= "00";
      end if;
      end if;
 
      end loop;
    end if;
    end if;
  end process irq_trigger_sync;
  end process irq_edge_detect_sync;
 
 
  -- interrupt trigger --
  -- edge detector - sync --
  irq_trigger_comb: process(rx_irq, irq_rx_en, tx_irq, irq_tx_en)
  irq_edge_detect_comb: process(rx_irq, irq_rx_en, tx_irq, irq_tx_en)
  begin
  begin
    -- RX --
    -- RX --
    rx_irq.set <= (others => '0');
    rx_irq.set <= (others => '0');
    for i in 0 to SLINK_NUM_RX-1 loop
    for i in 0 to SLINK_NUM_RX-1 loop
      if (rx_irq.detect(i) = "01") and (irq_rx_en(i) = '1') then -- rising-edge
      if (rx_irq.detect(i) = "01") then -- rising-edge
        rx_irq.set(i) <= '1';
        rx_irq.set(i) <= '1';
      end if;
      end if;
    end loop;
    end loop;
    -- TX --
    -- TX --
    tx_irq.set <= (others => '0');
    tx_irq.set <= (others => '0');
    for i in 0 to SLINK_NUM_TX-1 loop
    for i in 0 to SLINK_NUM_TX-1 loop
      if (tx_irq.detect(i) = "01") and (irq_tx_en(i) = '1') then -- rising-edge
      if (tx_irq.detect(i) = "01") then -- rising-edge
        tx_irq.set(i) <= '1';
        tx_irq.set(i) <= '1';
      end if;
      end if;
    end loop;
    end loop;
  end process irq_trigger_comb;
  end process irq_edge_detect_comb;
 
 
  -- interrupt arbiter --
  -- interrupt arbiter --
  irq_generator: process(clk_i)
  irq_generator: process(clk_i)
  begin
  begin
    if rising_edge(clk_i) then
    if rising_edge(clk_i) then
      if (enable = '0') then
      irq_rx_o <= or_reduce_f(rx_irq.set);
        rx_irq.pending <= '0';
      irq_tx_o <= or_reduce_f(tx_irq.set);
        tx_irq.pending <= '0';
 
      else
 
        -- RX --
 
        if (or_reduce_f(rx_irq.set) = '1') then
 
          rx_irq.pending <= '1';
 
        elsif (rx_irq.clr = '1') then
 
          rx_irq.pending <= '0';
 
        end if;
 
        -- TX --
 
        if (or_reduce_f(tx_irq.set) = '1') then
 
          tx_irq.pending <= '1';
 
        elsif (tx_irq.clr = '1') then
 
          tx_irq.pending <= '0';
 
        end if;
 
      end if;
 
    end if;
    end if;
  end process irq_generator;
  end process irq_generator;
 
 
  -- IRQ requests to CPU --
 
  irq_rx_o <= rx_irq.pending;
 
  irq_tx_o <= tx_irq.pending;
 
 
 
  -- IRQ acknowledge --
 
  rx_irq.clr <= '1' when ((rden = '1') and (addr(5) = '1')) or ((wren = '1') and (addr(5 downto 3) = "000")) else '0'; -- read from data FIFO OR write to control register
 
  tx_irq.clr <= '1' when ((wren = '1') and (addr(5) = '1')) or ((wren = '1') and (addr(5 downto 3) = "000")) else '0'; -- write to data FIFO  OR write to control register
 
 
 
 
 
  -- Link Select ----------------------------------------------------------------------------
  -- Link Select ----------------------------------------------------------------------------
  -- -------------------------------------------------------------------------------------------
  -- -------------------------------------------------------------------------------------------
  link_select: process(addr)
  link_select: process(addr)
  begin
  begin

powered by: WebSVN 2.1.0

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