source: FPGA/FTU/spi_interface/spi_rcv_shift_reg_16.vhd @ 156

Last change on this file since 156 was 156, checked in by qweitzel, 11 years ago
First check-in of VHDL code for FTU: counters, dcm, spi
File size: 6.5 KB
Line 
1---------------------------------------------------------------------------------------------
2---------------------------------------------------------------------------------------------
3--  File:          spi_rcv_shift_reg_16.vhd
4--
5--
6--  Original file: spi_rcv_shift_reg.vhd
7--
8--  Created:  9-6-00 ALS
9--  SPI shift register that shifts data in on MISO. No data is shifted out.
10--  This is an 8-bit register clocked on the outgoing SCK. The data input
11--  on the MISO pin is first clocked by two registers - one on the rising edge
12--  of SCK and one on the falling edge of SCK. The data selected to be input into the
13--  shift register is determined by a control bit in the control register (RCV_CPOL).
14--  When all bits have been shifted in, the data is loaded into the uC SPI Receive Data
15--  register.
16--
17--  Revised: 9-11-00 ALS
18--  Revised: 10-17-00 ALS
19--  Revised: 12-12-02 JRH
20   
21---------------------------------------------------------------------------------------------
22---------------------------------------------------------------------------------------------
23--  Modified from 8 to 16 bit word size by Patrick Vogler
24--  18th November 2009
25--
26--       Modifications are marked by: *Mod: <modification>
27--
28--  Cleaned up by Quirin Weitzel
29--  21th January 2010
30---------------------------------------------------------------------------------------------
31---------------------------------------------------------------------------------------------
32library IEEE;
33use IEEE.std_logic_1164.all;
34use IEEE.std_logic_arith.all;
35
36entity spi_rcv_shift_reg is
37  port( 
38    -- shift control and data
39    miso      : in  STD_LOGIC;                       -- Serial data in
40    shift_en  : in  STD_LOGIC;                       -- Active low shift enable   
41
42    -- parallel data out
43    data_out  : out STD_LOGIC_VECTOR (15 downto 0); -- Shifted data, *Mod: 15 instead of 7, parallel output extended from 8 to 16 bit   
44
45    rcv_load  : out std_logic;                      -- load signal to uC register
46   
47    -- rising edge and falling SCK edges
48    sck_re    : in  std_logic;                      -- rising edge of SCK
49    sck_fe    : in  std_logic;                      -- falling edge of SCK
50         
51    -- uC configuration for receive clock polarity
52    rcv_cpol  : in  STD_LOGIC;                      -- receive clock polarity
53    cpol      : in  std_logic;                      -- spi clock polarity
54     
55    ss_in_int : in  STD_LOGIC;                      -- signal indicating another master is on the bus
56   
57    reset     : in  STD_LOGIC;                      -- reset
58    sclk      : in  STD_LOGIC                       -- clock       
59  );       
60end spi_rcv_shift_reg;
61
62architecture DEFINITION of spi_rcv_shift_reg is
63
64  --******************************** Constants ***********************
65  constant RESET_ACTIVE   : std_logic := '0';
66
67  --******************************** Signals *************************
68  signal data_int       : STD_LOGIC_VECTOR (15 downto 0);-- *Mod: 15 instead of 7, extension form 8 to 16 bit
69  signal shift_in       : STD_LOGIC;                     -- data to be shifted in
70  signal miso_neg       : STD_LOGIC;                     -- data clocked on neg SCK
71  signal miso_pos       : STD_LOGIC;                     -- data clocked on pos SCK
72
73  signal rcv_bitcnt_int : unsigned(2 downto 0); -- internal bit count
74  signal rcv_bitcnt     : std_logic_vector(2 downto 0); -- bit count
75
76begin
77
78  --******************************** SPI Receive Shift Register ***********************
79  -- This shift register is clocked on the SCK output from the CPLD
80
81  rcv_shift_reg: process(sclk, reset, ss_in_int)
82  begin         
83    -- Clear output register
84    if (reset = RESET_ACTIVE or ss_in_int = '0') then
85      data_int <= (others => '0');
86           
87      -- On rising edge of spi clock, shift in data
88    elsif sclk'event and sclk = '1' then
89
90      -- If shift enable is high
91      if shift_en = '0' then
92
93        -- Shift the data
94        data_int <= data_int(14 downto 0) & shift_in;   -- *Mod: 14 instead of 6
95           
96      end if;
97
98    end if;
99
100  end process;
101
102  --******************************** MISO Input Registers ***********************
103  -- The MISO signal is clocked on both the rising and falling edges of SCK. The output
104  -- of both these registers is then multiplexed with the RCV_CPOL control bit choosing
105  -- which data is the valid data for the system. This data is then the input to the
106  -- shift register.
107
108  -- SCK rising edge register
109  inreg_pos: process (sclk, reset, ss_in_int)
110  begin
111    if reset = RESET_ACTIVE or ss_in_int = '0' then
112      miso_pos <= '0';
113    elsif sclk'event and sclk = '1' then   
114      miso_pos <= miso;
115    end if;
116  end process;
117
118  -- SCK falling edge register
119  inreg_neg: process (sclk, reset, ss_in_int)
120  begin
121    if reset = RESET_ACTIVE or ss_in_int = '0' then
122      miso_neg <= '0';
123    elsif sclk'event and sclk = '0' then   
124      miso_neg <= miso;
125    end if;
126  end process;
127
128  -- RCV_CPOL multiplexor to determine shift in data
129  miso_mux: process (miso_neg, miso_pos, rcv_cpol)
130  begin
131    if rcv_cpol = '1' then
132      shift_in <= miso_pos;
133    else
134      shift_in <= miso_neg;
135    end if;
136  end process;
137
138  --******************************** Parallel Data Out ***********************
139
140  data_out <= data_int(14 downto 0) & shift_in; --*Mod: 14 instead of 6
141
142  --******************************** Receive Bit Counter ***********************
143  -- Count bits loading into the SPI receive shift register based on SCK
144  -- assert RCV_LOAD when bit count is 0
145  RCV_BITCNT_PROC: process(sclk, reset, shift_en)
146  begin
147    if reset = RESET_ACTIVE or shift_en = '1' then
148      rcv_bitcnt_int <= (others => '0');
149    elsif sclk'event and sclk = '1' then
150      rcv_bitcnt_int <= rcv_bitcnt_int + 1;
151    end if;
152  end process;
153
154  rcv_bitcnt <= STD_LOGIC_VECTOR(rcv_bitcnt_int);
155
156  --******************************** Receive Load ***********************
157  -- If RCV_CPOL = '0', want to assert RCV_LOAD with falling edge of SCK
158  -- If RCV_CPOL = '1', want to assert RCV_LOAD with rising edge of SCK
159  -- only want RCV_LOAD to be 1 system clock pulse in width
160  rcv_load <= '1' when ( shift_en = '0' and
161                         (  (rcv_bitcnt="000" and cpol='0' and rcv_cpol='1' and sck_re='1')
162                            or (rcv_bitcnt="000" and cpol='1' and rcv_cpol='1' and sck_re='1')
163                            or (rcv_bitcnt="000" and cpol='0' and rcv_cpol='0' and sck_fe='1')
164                            or (rcv_bitcnt="111" and cpol='1' and rcv_cpol='0' and sck_fe='1') )
165                         )
166              else '0';
167
168end DEFINITION;
Note: See TracBrowser for help on using the repository browser.