1 ------------------------------------------------------------------------------- 2 -- File : SpiMaster.vhd 3 -- Company : SLAC National Accelerator Laboratory 4 -- Created : 2013-05-24 5 -- Last update: 2016-12-06 6 ------------------------------------------------------------------------------- 7 -- Description: Generic SPI Master 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_unsigned.
all;
21 use ieee.std_logic_arith.
all;
26 --! @ingroup protocols_spi 58 constant SCLK_COUNTER_SIZE_C : := bitSize(SPI_CLK_PERIOD_DIV2_CYCLES_C);
68 type RegType is record 74 sclkCounter : slv(SCLK_COUNTER_SIZE_C-1 downto 0);
81 constant REG_INIT_C : RegType := ( 86 dataCounter => (others => '0'), 87 sclkCounter => (others => '0'), 92 signal r : RegType := REG_INIT_C;
95 signal spiSdoRes : sl;
99 spiSdoRes <= to_x01z(spiSdo);
102 variable v : RegType;
111 v.dataCounter := (others => '0');
112 v.sclkCounter := (others => '0');
113 v.rdEn := '1';
-- rdEn always valid between txns, indicates ready for next txn 118 v.rdData := (others => '0');
122 -- Sample on first sclk edge so shift here before that happens 132 -- Wait half a clock period then shift out the next data bit 133 v.sclkCounter := r.sclkCounter + 1;
134 if (r.sclkCounter = SPI_CLK_PERIOD_DIV2_CYCLES_C) then 135 v.sclkCounter := (others => '0');
142 v.dataCounter := r.dataCounter + 1;
150 -- Wait half a clock period then sample the next data bit 151 v.sclkCounter := r.sclkCounter + 1;
152 if (r.sclkCounter = SPI_CLK_PERIOD_DIV2_CYCLES_C) then 153 v.sclkCounter := (others => '0');
159 v.dataCounter := r.dataCounter + 1;
167 -- Assert rdEn after half a SPI clk period 168 -- Go back to idle after one SPI clk period 169 -- Otherwise back to back operations happen too fast. 170 v.sclkCounter := r.sclkCounter + 1;
171 if (r.sclkCounter = SPI_CLK_PERIOD_DIV2_CYCLES_C) then 172 v.sclkCounter := (others => '0');
173 v.spiCsL := (others => '1');
198 seq :
process (
clk)
is 200 if (rising_edge(clk)) then 201 r <= rin after TPD_G;
out spiCsLslv( NUM_CHIPS_G- 1 downto 0)
in wrDataslv( DATA_SIZE_G- 1 downto 0)
out rdDataslv( DATA_SIZE_G- 1 downto 0)
SPI_SCLK_PERIOD_Greal := 1.0E-6
in chipSelslv( log2(NUM_CHIPS_G )- 1 downto 0)
in dataSizeslv( log2(DATA_SIZE_G )- 1 downto 0) := toSlv( DATA_SIZE_G- 1, log2(DATA_SIZE_G ))
NUM_CHIPS_Gpositive range 1 to 8:= 4
out shiftCountslv( bitSize(DATA_SIZE_G )- 1 downto 0)
CLK_PERIOD_Greal := 8.0E-9