1 ------------------------------------------------------------------------------- 2 -- File : SaciMaster2.vhd 3 -- Company : SLAC National Accelerator Laboratory 4 -- Created : 2012-08-10 5 -- Last update: 2016-06-17 6 ------------------------------------------------------------------------------- 7 -- Description: New and improved version of the SaciMaster. 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_saci 58 end entity SaciMaster2;
63 constant SACI_CLK_COUNTER_SIZE_C : := log2(SACI_CLK_HALF_PERIOD_C);
65 type StateType is (IDLE_S, TX_S, RX_START_S, RX_HEADER_S, RX_DATA_S, ACK_S);
67 type RegType is record 69 shiftReg : slv(52 downto 0);
70 shiftCount : slv(5 downto 0);
73 clkCount : slv(SACI_CLK_COUNTER_SIZE_C-1 downto 0);
88 constant REG_INIT_C : RegType := ( 90 shiftReg => (others => '0'), 91 shiftCount => (others => '0'), 92 clkCount => (others => '0'), 94 saciClkFalling => '0', 102 signal r : RegType := REG_INIT_C;
103 signal rin : RegType;
109 ------------------------------------------------------------------------------------------------- 110 -- Synchronize saciRsp to sysClk 111 ------------------------------------------------------------------------------------------------- 112 RSP_SYNC : for i in saciRsp'range generate 120 dataOut => saciRspSync
(i
));
-- [out] 121 end generate RSP_SYNC;
123 ------------------------------------------------------------------------------------------------- 125 ------------------------------------------------------------------------------------------------- 127 variable v : RegType;
128 variable rspIndex : ;
137 v.clkCount := r.clkCount + 1;
138 if (r.clkCount = SACI_CLK_HALF_PERIOD_C) then 140 v.clkCount := (others => '0');
143 -- Create saciClk edge strobes 144 v.saciClkRising := '0';
145 v.saciClkFalling := '0';
146 if (r.clkCount = SACI_CLK_HALF_PERIOD_C-1) then 148 v.saciClkRising := '1';
151 v.saciClkFalling := '1';
158 v.shiftReg := (others => '0');
159 v.shiftCount := (others => '0');
161 -- Hold clock inactive while idle 162 -- Make this configurable? 165 v.clkCount := (others => '0');
168 -- Start new command on the falling edge of saciClk 169 -- If clock is not freerunning then start right away 170 if (req = '1' and r.saciClk = '0' and r.clkCount = 0) then 171 -- New command, load shift reg 172 v.shiftReg(52) := '1';
-- Start bit 173 v.shiftReg(51) := op;
174 v.shiftReg(50 downto 44) := cmd;
175 v.shiftReg(43 downto 32) := addr;
177 v.shiftReg(31 downto 0) := wrData;
179 v.shiftReg(31 downto 0) := (others => '0');
181 -- Assert saciSelL line 187 -- Shift out data on rising edge of saciClk 188 if r.saciClkRising = '1' then 190 v.shiftReg := r.shiftReg(51 downto 0) & '0';
191 v.shiftCount := r.shiftCount + 1;
194 if (op = '0' and r.shiftCount = 21) then -- Read 195 v.state := RX_START_S;
196 elsif (op = '1' and r.shiftCount = 53) then -- Write 197 v.state := RX_START_S;
202 -- Clear last saciCmd on rising edge of saciCLk 203 if (r.saciClkRising = '1') then 207 -- Wait for saciRsp start bit 208 v.shiftCount := (others => '0');
209 if (saciRspSync(rspIndex) = '1' and r.saciClkFalling = '1') then 210 v.state := RX_HEADER_S;
214 -- Shift data in and check that header is correct 215 if (r.saciClkFalling = '1') then 216 v.shiftCount := r.shiftCount + 1;
217 v.shiftReg := r.shiftReg(r.shiftReg'high-1 downto r.shiftReg'low) & saciRspSync(rspIndex);
220 if (r.shiftCount = 20) then 221 -- Check that op, cmd and addr in response are correct 222 if (r.shiftReg(19) /= op or 223 r.shiftReg(18 downto 12) /= cmd or 224 r.shiftReg(11 downto 0) /= addr) then 229 v.state := RX_DATA_S;
236 if (r.saciClkFalling = '1') then 237 v.shiftCount := r.shiftCount + 1;
238 v.shiftReg := r.shiftReg(r.shiftReg'high-1 downto r.shiftReg'low) & saciRspSync(rspIndex);
239 if (r.shiftCount = 51) then 247 v.rdData := r.shiftReg(31 downto 0);
273 if (rising_edge(sysClk)) then 274 r <= rin after TPD_G;
279 end architecture rtl;
SYS_CLK_PERIOD_Greal := 8.0e-9
in rstsl :=not RST_POLARITY_G
in saciRspslv( ite( SACI_RSP_BUSSED_G, 0, SACI_NUM_CHIPS_G- 1) downto 0)
out rdDataslv( 31 downto 0)
SACI_RSP_BUSSED_Gboolean := false
in chipslv( log2(SACI_NUM_CHIPS_G )- 1 downto 0)
in wrDataslv( 31 downto 0)
SACI_CLK_FREERUN_Gboolean := false
SACI_NUM_CHIPS_Gpositive := 1
out saciSelLslv( SACI_NUM_CHIPS_G- 1 downto 0)
SACI_CLK_PERIOD_Greal := 1.0e-6