1 ------------------------------------------------------------------------------- 2 -- File : SaciSlaveOld.vhd 3 -- Company : SLAC National Accelerator Laboratory 4 -- Created : 2012-07-12 5 -- Last update: 2016-06-17 6 ------------------------------------------------------------------------------- 7 -- Description: Slave module for SACI interface. Legacy (bloated) version. 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.numeric_std.
all;
24 --! @ingroup protocols_saci 39 -- Silly reset hack to get saciSelL | rst onto dedicated reset bar 43 -- Detector (Parallel) Interface 52 end entity SaciSlaveOld;
56 type StateType is (IDLE_S, 63 type RegType is record 64 headerShiftReg : slv(20 downto 0);
65 dataShiftReg : slv(31 downto 0);
66 shiftCount : (5 downto 0);
73 signal r, rin : RegType;
74 signal saciCmdFall : sl;
76 procedure shiftInLeft (
82 v := r(r'low+1 to r'high) & i;
84 v := r(r'high-1 downto r'low) & i;
86 end procedure shiftInLeft;
90 -- Chip select also functions as async reset 94 -- Clock in serial input on falling edge 98 saciCmdFall <= '0' after TPD_G;
99 elsif (falling_edge(saciClk)) then 108 r.headerShiftReg <= (others => '0') after TPD_G;
109 r.dataShiftReg <= (others => '0') after TPD_G;
110 r.shiftCount <= (others => '0') after TPD_G;
111 r.state <= IDLE_S after TPD_G;
113 r.writeFlag <= '0' after TPD_G;
115 elsif (rising_edge(saciClk)) then 116 r <= rin after TPD_G;
121 variable rVar : RegType;
126 -- Overridden in some states 130 -- Main state machine 134 -- Shift in bits until a start bit is seen 135 shiftInLeft(saciCmdFall, r.headerShiftReg, rVar.headerShiftReg);
136 rVar.shiftCount := (others => '0');
137 rVar.dataShiftReg := (others => '0');
138 if (saciCmdFall = '1') then 139 rVar.state := SHIFT_HEADER_IN_S;
142 when SHIFT_HEADER_IN_S => 143 -- Shift in the header 144 shiftInLeft(saciCmdFall, r.headerShiftReg, rVar.headerShiftReg);
145 rVar.shiftCount := r.shiftCount + 1;
146 if (r.shiftCount = 19) then 147 -- Header rx'd, check r/w bit 148 rVar.writeFlag := r.headerShiftReg(18);
149 rVar.shiftCount := (others => '0');
150 if (r.headerShiftReg(18) = '1') then -- r/w bit will be at index 19 when frozen 152 rVar.state := SHIFT_DATA_IN_S;
155 rVar.state := EXEC_S;
159 when SHIFT_DATA_IN_S => 160 -- Write being performed, shift in write data 161 shiftInLeft(saciCmdFall, r.dataShiftReg, rVar.dataShiftReg);
162 rVar.shiftCount := r.shiftCount + 1;
163 if (r.shiftCount = 31) then 164 rVar.state := EXEC_S;
170 rVar.shiftCount := (others => '0');
172 rVar.dataShiftReg := rdData;
173 rVar.state := SHIFT_HEADER_OUT_S;
176 when SHIFT_HEADER_OUT_S => 177 -- Always send back the header, even on writes, as an ack to the other side 178 rVar.shiftCount := r.shiftCount + 1;
179 rVar.saciRsp := r.headerShiftReg(20);
180 -- Technically shifting out but its the same 181 -- Any saciCmd data shifted in here will be ignored (but there shouldn't be any) 182 shiftInLeft(saciCmdFall, r.headerShiftReg, rVar.headerShiftReg);
183 if (r.shiftCount = 20) then 184 rVar.shiftCount := (others => '0');
185 if (r.writeFlag = '1') then 187 rVar.state := IDLE_S;
189 -- Must now send read data back 190 rVar.state := SHIFT_DATA_OUT_S;
195 when SHIFT_DATA_OUT_S => 196 -- Read being performed, the read data obtained during EXEC_S 197 rVar.shiftCount := r.shiftCount + 1;
198 rVar.saciRsp := r.dataShiftReg(31);
199 shiftInLeft(saciCmdFall, r.dataShiftReg, rVar.dataShiftReg);
200 if (r.shiftCount = 32) then 201 rVar.state := IDLE_S;
205 rVar.headerShiftReg := (others => '0');
206 rVar.dataShiftReg := (others => '0');
207 rVar.shiftCount := (others => '0');
208 rVar.state := IDLE_S;
210 rVar.writeFlag := '0';
218 -- Assign outputs from registers 220 readL <= r.writeFlag;
221 cmd <= r.headerShiftReg(18 downto 12);
222 addr <= r.headerShiftReg(11 downto 0);
228 -- data <= r.dataShiftReg when r.writeFlag = '1' else (others => 'Z'); 229 -- saciRsp <= r.saciRsp when saciSelL = '0' else 'Z'; 231 end architecture rtl;
out addrslv( 11 downto 0)
in rdDataslv( 31 downto 0)
out wrDataslv( 31 downto 0)