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

Subversion Repositories neorv32

[/] [neorv32/] [trunk/] [rtl/] [core/] [neorv32_spi.vhd] - Diff between revs 66 and 68

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

Rev 66 Rev 68
Line 1... Line 1...
-- #################################################################################################
-- #################################################################################################
-- # << NEORV32 - Serial Peripheral Interface Controller (SPI) >>                                  #
-- # << NEORV32 - Serial Peripheral Interface Controller (SPI) >>                                  #
-- # ********************************************************************************************* #
-- # ********************************************************************************************* #
-- # Frame format: 8/16/24/32-bit receive/transmit data, always MSB first, 2 clock modes,          #
-- # Frame format: 8/16/24/32-bit receive/transmit data, always MSB first, 2 clock modes,          #
-- # 8 pre-scaled clocks (derived from system clock), 8 dedicated chip-select lines (low-active).  #
-- # 8 pre-scaled clocks (derived from system clock), 8 dedicated chip-select lines (low-active).  #
-- # Interrupt: SPI_transfer_done                                                                  #
-- # Interrupt: "transfer done"                                                                    #
-- # ********************************************************************************************* #
-- # ********************************************************************************************* #
-- # BSD 3-Clause License                                                                          #
-- # BSD 3-Clause License                                                                          #
-- #                                                                                               #
-- #                                                                                               #
-- # Copyright (c) 2021, Stephan Nolting. All rights reserved.                                     #
-- # Copyright (c) 2021, Stephan Nolting. All rights reserved.                                     #
-- #                                                                                               #
-- #                                                                                               #
Line 114... Line 114...
    bytecnt  : std_ulogic_vector(02 downto 0);
    bytecnt  : std_ulogic_vector(02 downto 0);
    sdi_sync : std_ulogic_vector(01 downto 0);
    sdi_sync : std_ulogic_vector(01 downto 0);
  end record;
  end record;
  signal rtx_engine : rtx_engine_t;
  signal rtx_engine : rtx_engine_t;
 
 
 
  -- interrupt generator --
 
  type irq_t is record
 
    pending : std_ulogic; -- pending interrupt request
 
    set     : std_ulogic;
 
    clr     : std_ulogic;
 
  end record;
 
  signal irq : irq_t;
 
 
begin
begin
 
 
  -- Access Control -------------------------------------------------------------------------
  -- Access Control -------------------------------------------------------------------------
  -- -------------------------------------------------------------------------------------------
  -- -------------------------------------------------------------------------------------------
  acc_en <= '1' when (addr_i(hi_abb_c downto lo_abb_c) = spi_base_c(hi_abb_c downto lo_abb_c)) else '0';
  acc_en <= '1' when (addr_i(hi_abb_c downto lo_abb_c) = spi_base_c(hi_abb_c downto lo_abb_c)) else '0';
Line 229... Line 237...
        when others => spi_sdo_o <= rtx_engine.sreg(31); -- 32-bit mode
        when others => spi_sdo_o <= rtx_engine.sreg(31); -- 32-bit mode
      end case;
      end case;
 
 
      -- defaults --
      -- defaults --
      spi_sck_o <= ctrl(ctrl_cpol_c);
      spi_sck_o <= ctrl(ctrl_cpol_c);
 
      irq.set   <= '0';
 
 
      -- serial engine --
      -- serial engine --
      rtx_engine.state(2) <= ctrl(ctrl_en_c);
      rtx_engine.state(2) <= ctrl(ctrl_en_c);
      case rtx_engine.state is
      case rtx_engine.state is
 
 
Line 262... Line 271...
        -- ------------------------------------------------------------
        -- ------------------------------------------------------------
          spi_sck_o <= ctrl(ctrl_cpha_c) xnor ctrl(ctrl_cpol_c);
          spi_sck_o <= ctrl(ctrl_cpha_c) xnor ctrl(ctrl_cpol_c);
          if (spi_clk_en = '1') then
          if (spi_clk_en = '1') then
            rtx_engine.sreg <= rtx_engine.sreg(30 downto 0) & rtx_engine.sdi_sync(rtx_engine.sdi_sync'left);
            rtx_engine.sreg <= rtx_engine.sreg(30 downto 0) & rtx_engine.sdi_sync(rtx_engine.sdi_sync'left);
            if (rtx_engine.bitcnt(5 downto 3) = rtx_engine.bytecnt) then -- all bits transferred?
            if (rtx_engine.bitcnt(5 downto 3) = rtx_engine.bytecnt) then -- all bits transferred?
              rtx_engine.state(1 downto 0) <= "00";
              irq.set <= '1'; -- interrupt!
 
              rtx_engine.state(1 downto 0) <= "00"; -- transmission done
            else
            else
              rtx_engine.state(1 downto 0) <= "10";
              rtx_engine.state(1 downto 0) <= "10";
            end if;
            end if;
          end if;
          end if;
 
 
Line 280... Line 290...
 
 
  -- busy flag --
  -- busy flag --
  rtx_engine.busy <= '0' when (rtx_engine.state(1 downto 0) = "00") else '1';
  rtx_engine.busy <= '0' when (rtx_engine.state(1 downto 0) = "00") else '1';
 
 
 
 
  -- Interrupt ------------------------------------------------------------------------------
  -- Interrupt Generator --------------------------------------------------------------------
  -- -------------------------------------------------------------------------------------------
  -- -------------------------------------------------------------------------------------------
  irq_o <= '1' when (rtx_engine.state = "100") else '0'; -- fire IRQ if transceiver idle and enabled
  irq_generator: process(clk_i)
 
  begin
 
    if rising_edge(clk_i) then
 
      if (ctrl(ctrl_en_c) = '0') then
 
        irq.pending <= '0';
 
      else
 
        if (irq.set = '1') then
 
          irq.pending <= '1';
 
        elsif (irq.clr = '1') then
 
          irq.pending <= '0';
 
        end if;
 
      end if;
 
    end if;
 
  end process irq_generator;
 
 
 
  -- IRQ request to CPU --
 
  irq_o <= irq.pending;
 
 
 
  -- IRQ acknowledge --
 
  irq.clr <= '1' when ((rden = '1') and (addr = spi_rtx_addr_c)) or (wren = '1') else '0'; -- read data register OR write data/control register
 
 
 
 
end neorv32_spi_rtl;
end neorv32_spi_rtl;
 
 
 No newline at end of file
 No newline at end of file

powered by: WebSVN 2.1.0

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