Čeština / English
Login

SVN Repository / Prohlížení

Aktuální adresář: FITkit / trunk / apps / audio / ring_buffer_mcu / fpga /

spi_controller.vhd

   1  -- spi_controler.vhd: SPI controller
   2  -- Copyright (C) 2009 Brno University of Technology,
   3  --                    Faculty of Information Technology
   4  -- Author(s): Zdenek Vasicek <vasicek AT fit.vutbr.cz>
   5  --
   6  -- LICENSE TERMS
   7  --
   8  -- Redistribution and use in source and binary forms, with or without
   9  -- modification, are permitted provided that the following conditions
  10  -- are met:
  11  -- 1. Redistributions of source code must retain the above copyright
  12  --    notice, this list of conditions and the following disclaimer.
  13  -- 2. Redistributions in binary form must reproduce the above copyright
  14  --    notice, this list of conditions and the following disclaimer in
  15  --    the documentation and/or other materials provided with the
  16  --    distribution.
  17  -- 3. All advertising materials mentioning features or use of this software
  18  --    or firmware must display the following acknowledgement:
  19  --
  20  --      This product includes software developed by the University of
  21  --      Technology, Faculty of Information Technology, Brno and its
  22  --      contributors.
  23  --
  24  -- 4. Neither the name of the Company nor the names of its contributors
  25  --    may be used to endorse or promote products derived from this
  26  --    software without specific prior written permission.
  27  --
  28  -- This software or firmware is provided ``as is'', and any express or implied
  29  -- warranties, including, but not limited to, the implied warranties of
  30  -- merchantability and fitness for a particular purpose are disclaimed.
  31  -- In no event shall the company or contributors be liable for any
  32  -- direct, indirect, incidental, special, exemplary, or consequential
  33  -- damages (including, but not limited to, procurement of substitute
  34  -- goods or services; loss of use, data, or profits; or business
  35  -- interruption) however caused and on any theory of liability, whether
  36  -- in contract, strict liability, or tort (including negligence or
  37  -- otherwise) arising in any way out of the use of this software, even
  38  -- if advised of the possibility of such damage.
  39  --
  40  -- $Id$
  41  --
  42  --
  43  
  44  library ieee;
  45  use ieee.std_logic_1164.all;
  46  use ieee.std_logic_arith.all;
  47  use ieee.std_logic_unsigned.all;
  48  
  49  entity spi_ringbuffer is
  50    port (
  51      -- Control signals
  52      RESET    : in std_logic;
  53      CLK      : in std_logic;
  54      EN       : in std_logic;  -- enable
  55      READY    : out std_logic; -- sample ready
  56      OVERFLOW : out std_logic; -- buffer overflow
  57  
  58      -- BRAM Ring Buffer interface
  59      BRAM_ADDR : out std_logic_vector(8 downto 0);
  60      BRAM_DOUT : in std_logic_vector(31 downto 0);
  61      BRAM_DIN  : out std_logic_vector(31 downto 0);
  62      BRAM_EN   : out std_logic;
  63      BRAM_WE   : out std_logic;
  64  
  65      ADDR_RD   : in std_logic_vector(8 downto 0);
  66      ADDR_WR   : in std_logic_vector(8 downto 0);
  67  
  68      -- SPI interface
  69      MOSI    : in std_logic;
  70      MISO    : out std_logic;
  71      SCK     : in std_logic
  72    );
  73  end entity;
  74  
  75  
  76  architecture main of spi_ringbuffer is
  77  
  78    signal wr_cntr : std_logic_vector(8 downto 0);
  79    signal rd_cntr : std_logic_vector(8 downto 0);
  80    signal wr_cntr_en : std_logic;
  81    signal rd_cntr_en : std_logic;
  82  
  83    signal sck_reg : std_logic_vector(1 downto 0);
  84    signal sck_re : std_logic;
  85    signal sck_fe : std_logic;
  86    signal sample_ready : std_logic;
  87    signal di_reg : std_logic;
  88  
  89    signal bit_cntr : std_logic_vector(4 downto 0);
  90    signal bit_cntr_last : std_logic;
  91    signal data_shreg : std_logic_vector(31 downto 0);
  92    signal data_shreg_en : std_logic;
  93    signal data_shreg_ld : std_logic;
  94    signal bram_addr_sel : std_logic;
  95    signal overflow_reg : std_logic;
  96  
  97    type FSMstate is (SInit, SReadSample, SDataTrans, SWriteSample);
  98    signal pstate : FSMstate; -- actual state
  99    signal nstate : FSMstate; -- next state
 100  begin
 101     -- je alespon jeden vzorek v bufferu?
 102     sample_ready <= '1' when rd_cntr /= ADDR_WR else '0';
 103  
 104     OVERFLOW <= overflow_reg;
 105  
 106     -- hlidani preteceni
 107     process (RESET, CLK)
 108     begin
 109        if (RESET = '1') then
 110           overflow_reg <= '0';
 111        elsif (CLK'event) and (CLK = '1') then
 112           if (wr_cntr = ADDR_RD) then
 113              overflow_reg <= '1';
 114           end if;
 115        end if;
 116     end process;
 117  
 118     sck_sample: process (RESET, CLK, SCK)
 119     begin
 120        if (RESET = '1') then
 121           sck_reg <= SCK & SCK;
 122        elsif (CLK'event) and (CLK = '1') then
 123           sck_reg <= sck_reg(0) & SCK;
 124           di_reg <= MOSI;
 125        end if;
 126     end process;
 127  
 128     --SCK rising edge
 129     sck_re <= '1' when (sck_reg(1) = '0') and (sck_reg(0) = '1') else '0';
 130     --SCK fallig edge
 131     sck_fe <= '1' when (sck_reg(1) = '1') and (sck_reg(0) = '0') else '0';
 132  
 133     bit_counter: process (RESET, CLK)
 134     begin
 135        if (RESET = '1') then
 136           bit_cntr <= (others => '0');
 137        elsif (CLK'event) and (CLK = '1') then
 138           if (EN = '1') and (sck_re = '1') then
 139              bit_cntr <= bit_cntr + 1;
 140           end if;
 141        end if;
 142     end process;
 143  
 144     bit_cntr_last <= '1' when bit_cntr = "11111" else '0';
 145  
 146     misoreg: process (RESET, CLK)
 147     begin
 148        if (RESET = '1') then
 149           MISO <= '0';
 150        elsif (CLK'event) and (CLK = '1') then
 151           if (sck_fe = '1') then
 152              MISO <= data_shreg(31);
 153           end if;
 154        end if;
 155     end process;
 156  
 157     spi_shift_register: process (CLK)
 158     begin
 159        if (CLK'event) and (CLK = '1') then
 160           if (data_shreg_ld = '1') then
 161              data_shreg <= BRAM_DOUT;
 162           elsif (data_shreg_en = '1') and (sck_re = '1') then
 163              data_shreg <= data_shreg(30 downto 0) & di_reg;
 164           end if;
 165        end if;
 166     end process;
 167  
 168     BRAM_DIN <= data_shreg;
 169  
 170     cntrs: process (RESET, CLK)
 171     begin
 172        if (RESET = '1') then
 173           rd_cntr <= (others => '0');
 174           wr_cntr <= (others => '0');
 175        elsif (CLK'event) and (CLK = '1') then
 176           if (rd_cntr_en = '1') then
 177              rd_cntr <= rd_cntr + 1;
 178           end if;
 179           if (wr_cntr_en = '1') then
 180              wr_cntr <= wr_cntr + 1;
 181           end if;
 182        end if;
 183     end process;
 184  
 185     BRAM_ADDR <= rd_cntr when bram_addr_sel = '0' else wr_cntr;
 186  
 187     --Present State registr
 188     pstatereg: process(RESET, CLK)
 189     begin
 190        if (RESET='1') then
 191           pstate <= SInit;
 192        elsif (CLK'event) and (CLK='1') then
 193           pstate <= nstate;
 194        end if;
 195     end process;
 196  
 197     --Next State logic, Output logic
 198     nstate_output_logic: process(pstate, sample_ready, sck_fe, sck_re, bit_cntr_last, EN)
 199     begin
 200        bram_addr_sel <= '0';
 201        data_shreg_ld <= '0';
 202        data_shreg_en <= '0';
 203        wr_cntr_en <= '0';
 204        rd_cntr_en <= '0';
 205        BRAM_WE <= '0';
 206        BRAM_EN <= '0';
 207        READY <= '0';
 208  
 209        nstate <= SInit;
 210        case pstate is
 211           when SInit =>
 212               nstate <= SInit;
 213  
 214               if (sample_ready = '1') and (EN = '1') then
 215                  nstate <= SReadSample;
 216                  bram_addr_sel <= '0';
 217                  BRAM_EN <= '1';
 218               end if;
 219  
 220           when SReadSample =>
 221                nstate <= SDataTrans;
 222  
 223                BRAM_EN <= '1';
 224                data_shreg_ld <= '1';
 225                rd_cntr_en <= '1';
 226  
 227           when SDataTrans =>
 228                nstate <= SDataTrans;
 229  
 230                READY <= '1';
 231                data_shreg_en <= '1';
 232                if (bit_cntr_last = '1') and (sck_re = '1') then
 233                   nstate <= SWriteSample;
 234                end if;
 235  
 236           when SWriteSample =>
 237                nstate <= SInit;
 238  
 239                -- Write received sample to BRAM, increment wr_counter
 240                BRAM_EN <= '1';
 241                BRAM_WE <= '1';
 242                bram_addr_sel <= '1';
 243                wr_cntr_en <= '1';
 244  
 245           when others => null;
 246        end case;
 247     end process;
 248  
 249  end main;
 250  
 251  
Zobrazeno: 154124x Naposledy: 18.11.2017 16:38:33