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)