Čeština / English
Login

SVN Repository / Prohlížení

Aktuální adresář: FITkit / trunk / fpga / ctrls / spi /

spi_adc_autoincr.vhd

   1  -- spi_adc_autoincr.vhd : SPI Decoder with ADDR autoincrement
   2  -- Copyright (C) 2006 Brno University of Technology,
   3  --                    Faculty of Information Technology
   4  -- Author(s): Zdenek Vasicek <xvasic11 AT stud.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  use work.math_pack.all;
  49  
  50  architecture autoincrement of SPI_adc is
  51  
  52  subtype tcntr is integer range 0 to max(ADDR_WIDTH, DATA_WIDTH);
  53  signal  bitcntr : tcntr := 0;
  54  signal  bitcntr_rst : std_logic;
  55  
  56  signal  cmp_4bits : std_logic;
  57  signal  cmp_baseaddr : std_logic;
  58  signal  cmp_abits : std_logic;
  59  signal  cmp_dbits : std_logic;
  60  signal  cmp_bitszero : std_logic;
  61  
  62  type    FSMstate is (SCmdRcv, SAddrRcv, SDataRcv, SAddrInc, SNop);
  63  signal  pstate    : FSMstate; -- actual state
  64  signal  nstate    : FSMstate; -- next state
  65  
  66  signal  shreg_cmd  : std_logic_vector(1 downto 0);
  67  signal  cmdreg_en  : std_logic;
  68  alias   cmd_we     : std_logic is shreg_cmd(0);
  69  alias   cmd_re     : std_logic is shreg_cmd(1);
  70  signal  shreg_addr : std_logic_vector(ADDR_WIDTH-1 downto 0);
  71  signal  addrreg_en : std_logic;
  72  signal  shreg_do   : std_logic_vector(DATA_WIDTH-1 downto 0);
  73  signal  shreg_di   : std_logic_vector(DATA_WIDTH-1 downto 0);
  74  signal  shreg_ld   : std_logic;
  75  signal  doreg_en   : std_logic;
  76  signal  rden       : std_logic;
  77  signal  diouten    : std_logic;
  78  signal  rden_reg   : std_logic_vector(max(DELAY,0) downto 0);
  79  signal  addr_inc   : std_logic;
  80  
  81  begin
  82  
  83     DATA_OUT <= shreg_do;
  84     ADDR <= shreg_addr(max(ADDR_OUT_WIDTH-1,0) DOWNTO 0);
  85     READ_EN <= rden;
  86  
  87     -- DI MX
  88     DI <= shreg_di(DATA_WIDTH-1) when (diouten='1') else 'Z';
  89  
  90     -- Bits counter
  91     bitecntr: process(CS, CLK)
  92     begin
  93        if (CS = '0') then
  94           bitcntr <= 0;
  95        elsif (CLK'event) and (CLK='1') then
  96           if (bitcntr_rst = '1') then
  97              bitcntr <= 0;
  98           elsif (DO_VLD='1') then
  99              bitcntr <= bitcntr + 1;
 100           end if;
 101        end if;
 102     end process;
 103  
 104     -- Comparators
 105     cmp_4bits <= '1' when (bitcntr = 4) else '0';
 106     cmp_abits <= '1' when (bitcntr = ADDR_WIDTH) else '0';
 107     cmp_dbits <= '1' when (bitcntr = DATA_WIDTH) else '0';
 108     cmp_bitszero <= '1' when (bitcntr = 0) else '0';
 109  
 110     cmp_baseaddr <= '1' when (shreg_addr(ADDR_WIDTH-1 downto ADDR_OUT_WIDTH) =
 111                               conv_std_logic_vector(BASE_ADDR,ADDR_WIDTH)(ADDR_WIDTH-1 downto ADDR_OUT_WIDTH))
 112                         else '0';
 113  
 114     -- ShReg Load delay
 115     shreg_ld <= rden_reg(DELAY);
 116     rden_reg(0) <= rden;
 117     process (CS, CLK)
 118     begin
 119        if (DELAY > 0) then
 120           if (CS = '0') then
 121              rden_reg(DELAY downto 1) <= (others=>'0');
 122           elsif (CLK'event) and (CLK='1') then
 123              rden_reg(DELAY downto 1) <= rden_reg(DELAY-1 downto 0);
 124           end if;
 125        end if;
 126     end process;
 127  
 128     -- Address register
 129     process (CS, CLK)
 130     begin
 131        if (CS = '0') then
 132           shreg_addr <= (others=>'0');
 133        elsif (CLK'event) and (CLK = '1') then
 134           if (DO_VLD='1') and (addrreg_en='1') then -- Shift enable
 135              shreg_addr <= shreg_addr(ADDR_WIDTH-2 downto 0) & DO;
 136           elsif (addr_inc='1') then
 137              shreg_addr <= shreg_addr + 1;
 138           end if;
 139        end if;
 140     end process;
 141  
 142     -- Shift registers
 143     process (CS, CLK)
 144     begin
 145        if (CS = '0') then
 146           shreg_cmd <= (others=>'0');
 147           shreg_do  <= (others=>'0');
 148           shreg_di  <= (others=>'0');
 149        elsif (CLK'event) and (CLK='1') then
 150  
 151           if (DO_VLD='1') then -- shift enable
 152              if (cmdreg_en='1') then  -- CMD register
 153                 shreg_cmd <= shreg_cmd(0) & DO;
 154              end if;
 155              if (doreg_en='1') then   -- DATA register
 156                 shreg_do <= shreg_do(DATA_WIDTH-2 downto 0) & DO;
 157              end if;
 158           end if;
 159  
 160           if (shreg_ld='1') then  -- parallel load
 161              shreg_di <= DATA_IN;
 162           elsif (DI_REQ='1') then -- shift enable
 163              shreg_di <= shreg_di(DATA_WIDTH-2 downto 0)&'0';
 164           end if;
 165        end if;
 166     end process;
 167  
 168     -- FSM
 169     process (CS, CLK)
 170     begin
 171        if (CS = '0') then
 172           pstate <= SCmdRcv;
 173        elsif (CLK'event) and (CLK='1') then
 174           pstate <= nstate;
 175        end if;
 176     end process;
 177  
 178     -- FSM next state logic
 179     process (pstate, cmp_4bits, cmp_abits, cmp_dbits, cmp_bitszero, cmp_baseaddr, shreg_cmd, cmd_we, cmd_re, DI_REQ)
 180     begin
 181        bitcntr_rst <= '0';
 182        cmdreg_en <= '0';
 183        doreg_en <= '0';
 184        addrreg_en <= '0';
 185        WRITE_EN <= '0';
 186        rden <= '0';
 187        diouten <= '0';
 188        addr_inc <= '0';
 189  
 190        nstate <= SCmdRcv;
 191        case pstate is
 192           --CMD receive
 193           when SCmdRcv =>
 194              cmdreg_en <= '1';
 195              if (cmp_4bits = '1') then
 196                 nstate <= SAddrRcv;
 197                 bitcntr_rst <= '1';
 198              end if;
 199  
 200           --ADDR receive
 201           when SAddrRcv =>
 202              nstate <= SAddrRcv;
 203              addrreg_en <= '1';
 204              if (cmp_abits = '1') then
 205                 if (cmp_baseaddr = '1') then
 206                    nstate <= SDataRcv;
 207                 else
 208                    nstate <= SNop;
 209                 end if;
 210                 bitcntr_rst <= '1';
 211              end if;
 212  
 213           --DATA receive & transmitt
 214           when SDataRcv =>
 215              nstate <= SDataRcv;
 216              doreg_en <= '1';
 217              diouten <= '1';
 218              if (cmp_bitszero = '1') and (DI_REQ = '1') then
 219                 rden <= cmd_re;
 220              end if;
 221              if (cmp_dbits = '1') then
 222                 WRITE_EN <= cmd_we;
 223                 bitcntr_rst <= '1';
 224                 nstate <= SAddrInc;
 225              end if;
 226  
 227            when SAddrInc =>
 228              nstate <= SDataRcv;
 229              addr_inc <= '1';
 230  
 231            --inactive device (different BASE_ADDR)
 232            when SNop =>
 233              nstate <= SNop;
 234              bitcntr_rst <= '1';
 235  
 236       end case;
 237     end process;
 238  
 239  
 240  end autoincrement;
 241  
Zobrazeno: 679787x Naposledy: 28.6.2022 20:43:29