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

Subversion Repositories neorv32

[/] [neorv32/] [trunk/] [rtl/] [core/] [neorv32_spi.vhd] - Diff between revs 2 and 6

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

Rev 2 Rev 6
Line 1... Line 1...
-- #################################################################################################
-- #################################################################################################
-- # << NEORV32 - Serial Peripheral Interface Master (SPI) >>                                      #
-- # << NEORV32 - Serial Peripheral Interface Controller (SPI) >>                                  #
-- # ********************************************************************************************* #
-- # ********************************************************************************************* #
-- # Frame format: 8/16/24/32-bit RTX, MSB or LSB first, 2 clock modes, 8 clock speeds,            #
-- # Frame format: 8/16/24/32-bit RTX, MSB or LSB first, 2 clock modes, 8 clock speeds,            #
-- # 8 dedicated CS lines (low-active). Interrupt: SPI_transfer_done                               #
-- # 8 dedicated CS lines (low-active). Interrupt: SPI_transfer_done                               #
-- # ********************************************************************************************* #
-- # ********************************************************************************************* #
-- # BSD 3-Clause License                                                                          #
-- # BSD 3-Clause License                                                                          #
Line 55... Line 55...
    ack_o       : out std_ulogic; -- transfer acknowledge
    ack_o       : out std_ulogic; -- transfer acknowledge
    -- clock generator --
    -- clock generator --
    clkgen_en_o : out std_ulogic; -- enable clock generator
    clkgen_en_o : out std_ulogic; -- enable clock generator
    clkgen_i    : in  std_ulogic_vector(07 downto 0);
    clkgen_i    : in  std_ulogic_vector(07 downto 0);
    -- com lines --
    -- com lines --
    spi_sclk_o  : out std_ulogic; -- SPI serial clock
    spi_sck_o   : out std_ulogic; -- SPI serial clock
    spi_mosi_o  : out std_ulogic; -- SPI master out, slave in
    spi_sdo_o   : out std_ulogic; -- controller data out, peripheral data in
    spi_miso_i  : in  std_ulogic; -- SPI master in, slave out
    spi_sdi_i   : in  std_ulogic; -- controller data in, peripheral data out
    spi_csn_o   : out std_ulogic_vector(07 downto 0); -- SPI CS
    spi_csn_o   : out std_ulogic_vector(07 downto 0); -- SPI CS
    -- interrupt --
    -- interrupt --
    spi_irq_o   : out std_ulogic -- transmission done interrupt
    spi_irq_o   : out std_ulogic -- transmission done interrupt
  );
  );
end neorv32_spi;
end neorv32_spi;
Line 114... Line 114...
  signal spi_state0   : std_ulogic;
  signal spi_state0   : std_ulogic;
  signal spi_state1   : std_ulogic;
  signal spi_state1   : std_ulogic;
  signal spi_rtx_sreg : std_ulogic_vector(31 downto 0);
  signal spi_rtx_sreg : std_ulogic_vector(31 downto 0);
  signal spi_rx_data  : std_ulogic_vector(31 downto 0);
  signal spi_rx_data  : std_ulogic_vector(31 downto 0);
  signal spi_bitcnt   : std_ulogic_vector(05 downto 0);
  signal spi_bitcnt   : std_ulogic_vector(05 downto 0);
  signal spi_miso_ff0 : std_ulogic;
  signal spi_sdi_ff0  : std_ulogic;
  signal spi_miso_ff1 : std_ulogic;
  signal spi_sdi_ff1  : std_ulogic;
 
 
begin
begin
 
 
  -- Access Control -------------------------------------------------------------------------
  -- Access Control -------------------------------------------------------------------------
  -- -------------------------------------------------------------------------------------------
  -- -------------------------------------------------------------------------------------------
Line 215... Line 215...
  -- SPI Transceiver ------------------------------------------------------------------------
  -- SPI Transceiver ------------------------------------------------------------------------
  -- -------------------------------------------------------------------------------------------
  -- -------------------------------------------------------------------------------------------
  spi_rtx_unit: process(clk_i)
  spi_rtx_unit: process(clk_i)
  begin
  begin
    if rising_edge(clk_i) then
    if rising_edge(clk_i) then
      -- input (MISO) synchronizer --
      -- input (sdi) synchronizer --
      spi_miso_ff0 <= spi_miso_i;
      spi_sdi_ff0 <= spi_sdi_i;
      spi_miso_ff1 <= spi_miso_ff0;
      spi_sdi_ff1 <= spi_sdi_ff0;
 
 
      -- serial engine --
      -- serial engine --
      spi_irq_o <= '0';
      spi_irq_o <= '0';
      if (spi_state0 = '0') or (ctrl(ctrl_spi_en_c) = '0') then -- idle or disabled
      if (spi_state0 = '0') or (ctrl(ctrl_spi_en_c) = '0') then -- idle or disabled
        case ctrl(ctrl_spi_size1_c downto ctrl_spi_size0_c) is
        case ctrl(ctrl_spi_size1_c downto ctrl_spi_size0_c) is
Line 229... Line 229...
          when "01"   => spi_bitcnt <= "010000"; -- 16-bit mode
          when "01"   => spi_bitcnt <= "010000"; -- 16-bit mode
          when "10"   => spi_bitcnt <= "011000"; -- 24-bit mode
          when "10"   => spi_bitcnt <= "011000"; -- 24-bit mode
          when others => spi_bitcnt <= "100000"; -- 32-bit mode
          when others => spi_bitcnt <= "100000"; -- 32-bit mode
        end case;
        end case;
        spi_state1 <= '0';
        spi_state1 <= '0';
        spi_mosi_o <= '0';
        spi_sdo_o <= '0';
        spi_sclk_o <= '0';
        spi_sck_o <= '0';
        if (ctrl(ctrl_spi_en_c) = '0') then -- disabled
        if (ctrl(ctrl_spi_en_c) = '0') then -- disabled
          spi_busy <= '0';
          spi_busy <= '0';
        elsif (spi_start = '1') then -- start new transmission
        elsif (spi_start = '1') then -- start new transmission
          case ctrl(ctrl_spi_size1_c downto ctrl_spi_size0_c) is
          case ctrl(ctrl_spi_size1_c downto ctrl_spi_size0_c) is
            when "00"   => spi_rtx_sreg <= tx_data(07 downto 0) & x"000000"; -- 8-bit mode
            when "00"   => spi_rtx_sreg <= tx_data(07 downto 0) & x"000000"; -- 8-bit mode
Line 247... Line 247...
        spi_state0 <= spi_busy and spi_clk; -- start with next new clock pulse
        spi_state0 <= spi_busy and spi_clk; -- start with next new clock pulse
 
 
      else -- transmission in progress
      else -- transmission in progress
        if (spi_state1 = '0') then -- first half of transmission
        if (spi_state1 = '0') then -- first half of transmission
 
 
          spi_sclk_o <= ctrl(ctrl_spi_cpha_c);
          spi_sck_o <= ctrl(ctrl_spi_cpha_c);
          if (ctrl(ctrl_spi_dir_c) = '0') then
          if (ctrl(ctrl_spi_dir_c) = '0') then
            spi_mosi_o <= spi_rtx_sreg(31); -- MSB first
            spi_sdo_o <= spi_rtx_sreg(31); -- MSB first
          else
          else
            spi_mosi_o <= spi_rtx_sreg(0); -- LSB first
            spi_sdo_o <= spi_rtx_sreg(0); -- LSB first
          end if;
          end if;
          if (spi_clk = '1') then
          if (spi_clk = '1') then
            spi_state1 <= '1';
            spi_state1 <= '1';
            if (ctrl(ctrl_spi_cpha_c) = '0') then
            if (ctrl(ctrl_spi_cpha_c) = '0') then
              if (ctrl(ctrl_spi_dir_c) = '0') then
              if (ctrl(ctrl_spi_dir_c) = '0') then
                spi_rtx_sreg <= spi_rtx_sreg(30 downto 0) & spi_miso_ff1; -- MSB first
                spi_rtx_sreg <= spi_rtx_sreg(30 downto 0) & spi_sdi_ff1; -- MSB first
              else
              else
                spi_rtx_sreg <= spi_miso_ff1 & spi_rtx_sreg(31 downto 1); -- LSB first
                spi_rtx_sreg <= spi_sdi_ff1 & spi_rtx_sreg(31 downto 1); -- LSB first
              end if;
              end if;
            end if;
            end if;
            spi_bitcnt <= std_ulogic_vector(unsigned(spi_bitcnt) - 1);
            spi_bitcnt <= std_ulogic_vector(unsigned(spi_bitcnt) - 1);
          end if;
          end if;
        else -- second half of transmission
        else -- second half of transmission
 
 
          spi_sclk_o <= not ctrl(ctrl_spi_cpha_c);
          spi_sck_o <= not ctrl(ctrl_spi_cpha_c);
          if (spi_clk = '1') then
          if (spi_clk = '1') then
            spi_state1 <= '0';
            spi_state1 <= '0';
            if (ctrl(ctrl_spi_cpha_c) = '1') then
            if (ctrl(ctrl_spi_cpha_c) = '1') then
              if (ctrl(ctrl_spi_dir_c) = '0') then
              if (ctrl(ctrl_spi_dir_c) = '0') then
                spi_rtx_sreg <= spi_rtx_sreg(30 downto 0) & spi_miso_ff1; -- MSB first
                spi_rtx_sreg <= spi_rtx_sreg(30 downto 0) & spi_sdi_ff1; -- MSB first
              else
              else
                spi_rtx_sreg <= spi_miso_ff1 & spi_rtx_sreg(31 downto 1); -- LSB first
                spi_rtx_sreg <= spi_sdi_ff1 & spi_rtx_sreg(31 downto 1); -- LSB first
              end if;
              end if;
            end if;
            end if;
            if (spi_bitcnt = "000000") then
            if (spi_bitcnt = "000000") then
              spi_state0 <= '0';
              spi_state0 <= '0';
              spi_busy   <= '0';
              spi_busy   <= '0';

powered by: WebSVN 2.1.0

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