1 ------------------------------------------------------------------------------- 3 -- Company : SLAC National Accelerator Laboratory 4 -- Created : 2014-01-27 5 -- Last update: 2014-03-14 6 ------------------------------------------------------------------------------- 7 -- Description: Generic SPI Slave Module 8 ------------------------------------------------------------------------------- 9 -- This file is part of 'SLAC Firmware Standard Library'. 10 -- It is subject to the license terms in the LICENSE.txt file found in the 11 -- top-level directory of this distribution and at: 12 -- https://confluence.slac.stanford.edu/display/ppareg/LICENSE.html. 13 -- No part of 'SLAC Firmware Standard Library', including this file, 14 -- may be copied, modified, propagated, or distributed except according to 15 -- the terms contained in the LICENSE.txt file. 16 ------------------------------------------------------------------------------- 19 use ieee.std_logic_1164.
all;
20 use ieee.std_logic_arith.
all;
21 use ieee.std_logic_unsigned.
all;
25 --! @ingroup protocols_spi 55 -- Input sync and edge detection regs 60 --Internal Shift regs and counters 69 constant REG_INIT_C : RegType := ( 73 shiftReg => (others => '0'), 78 signal r : RegType := REG_INIT_C;
116 seq :
process (
clk)
is 118 if (rising_edge(clk)) then 119 r <= rin after TPD_G;
125 comb :
process (mosiSync, r,
rdData,
rdStb,
rst, sclkSync, selLSync)
is 126 variable v : RegType;
128 impure function isLeadingEdge 131 return selLSync = '0' and r.sclkLast = CPOL_G and sclkSync = not CPOL_G;
134 impure function isTrailingEdge 137 return selLSync = '0' and r.sclkLast = not CPOL_G and sclkSync = CPOL_G;
140 -- Shift a new bit out 143 v.shiftReg := r.shiftReg(WORD_SIZE_G-1 downto 0) & '0';
146 -- Clock in the current mosi bit and increment counter 149 v.shiftReg(0) := mosiSync;
151 v.shiftCnt := r.shiftCnt + 1;
152 if (r.shiftCnt = MAX_COUNT_C) then 153 v.shiftCnt := (others => '0');
160 v.sclkLast := sclkSync;
161 v.mosiLast := mosiSync;
162 v.selLLast := selLSync;
164 -- CPHA_G = 0 is a special case 165 -- Do a shift on falling edge of selL 166 if (CPHA_G = '0' and r.selLLast = '1' and selLSync = '0') then 170 if (isLeadingEdge) then 179 if (isTrailingEdge) then 182 elsif (CPHA_G = '0' and r.shiftCnt /= MAX_COUNT_C) then 187 -- Assert wrStb when max count reached 188 if (r.shiftCnt = MAX_COUNT_C and isTrailingEdge and r.gotSclk = '1') then 192 -- Read strobe only allowed when Write strobe is high 193 if (r.wrStb = '1' and (rdStb = '1' or isLeadingEdge)) then 206 if (selLSync = '0') then 215 end architecture rtl;
in rstsl :=not RST_POLARITY_G
WORD_SIZE_Gpositive := 16
out wrDataslv( WORD_SIZE_G- 1 downto 0)
in rdDataslv( WORD_SIZE_G- 1 downto 0)