Skip to content

Commit fa8251f

Browse files
committed
adding sy89297 to SURF
1 parent eb99646 commit fa8251f

File tree

5 files changed

+342
-0
lines changed

5 files changed

+342
-0
lines changed

devices/Microchip/ruckus.tcl

+1
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,4 @@ source $::env(RUCKUS_PROC_TCL)
33

44
# Load ruckus files
55
loadRuckusTcl "$::DIR_PATH/sy56040"
6+
loadRuckusTcl "$::DIR_PATH/sy89297"
+285
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,285 @@
1+
-------------------------------------------------------------------------------
2+
-- Company : SLAC National Accelerator Laboratory
3+
-------------------------------------------------------------------------------
4+
-- Description: This controller is designed around the Microchip SY89297UMH
5+
-------------------------------------------------------------------------------
6+
-- This file is part of 'SLAC Firmware Standard Library'.
7+
-- It is subject to the license terms in the LICENSE.txt file found in the
8+
-- top-level directory of this distribution and at:
9+
-- https://confluence.slac.stanford.edu/display/ppareg/LICENSE.html.
10+
-- No part of 'SLAC Firmware Standard Library', including this file,
11+
-- may be copied, modified, propagated, or distributed except according to
12+
-- the terms contained in the LICENSE.txt file.
13+
-------------------------------------------------------------------------------
14+
15+
library ieee;
16+
use ieee.std_logic_1164.all;
17+
use ieee.std_logic_unsigned.all;
18+
use ieee.std_logic_arith.all;
19+
20+
library surf;
21+
use surf.StdRtlPkg.all;
22+
use surf.AxiStreamPkg.all;
23+
use surf.AxiLitePkg.all;
24+
25+
entity Sy89297 is
26+
generic (
27+
TPD_G : time := 1 ns;
28+
SIMULATION_G : boolean := false);
29+
port (
30+
-- Delay control signals
31+
enableL : out sl;
32+
enaL : out sl;
33+
enbL : out sl;
34+
sdata : out sl;
35+
sclk : out sl;
36+
sload : out sl;
37+
-- AXI-Lite Interface
38+
axilClk : in sl;
39+
axilRst : in sl;
40+
axilReadMaster : in AxiLiteReadMasterType;
41+
axilReadSlave : out AxiLiteReadSlaveType;
42+
axilWriteMaster : in AxiLiteWriteMasterType;
43+
axilWriteSlave : out AxiLiteWriteSlaveType);
44+
end Sy89297;
45+
46+
architecture rtl of Sy89297 is
47+
48+
type StateType is (
49+
IDLE_S,
50+
SEND_DATA_S,
51+
SLOAD_S);
52+
53+
type RegType is record
54+
delayA : slv(9 downto 0);
55+
delayB : slv(9 downto 0);
56+
busy : sl;
57+
cnt : natural range 0 to 20;
58+
shiftReg : slv(19 downto 0);
59+
-- Serial Clock Generation
60+
sclkEn : sl;
61+
sclkCnt : slv(7 downto 0);
62+
sckHalfCycle : slv(7 downto 0);
63+
-- I/O Signals
64+
sclk : sl;
65+
sload : sl;
66+
-- AXIL and state machine
67+
axilReadSlave : AxiLiteReadSlaveType;
68+
axilWriteSlave : AxiLiteWriteSlaveType;
69+
state : StateType;
70+
end record RegType;
71+
72+
constant REG_INIT_C : RegType := (
73+
delayA => (others => '0'),
74+
delayB => (others => '0'),
75+
busy => '0',
76+
cnt => 0,
77+
shiftReg => (others => '0'),
78+
-- Serial Clock Generation
79+
sclkEn => '0',
80+
sclkCnt => (others => '0'),
81+
sckHalfCycle => ite(SIMULATION_G, x"00", x"0F"),
82+
-- I/O Signals
83+
sclk => '0',
84+
sload => '1',
85+
-- AXIL and state machine
86+
axilReadSlave => AXI_LITE_READ_SLAVE_INIT_C,
87+
axilWriteSlave => AXI_LITE_WRITE_SLAVE_INIT_C,
88+
state => IDLE_S);
89+
90+
signal r : RegType := REG_INIT_C;
91+
signal rin : RegType;
92+
93+
begin
94+
95+
comb : process (axilReadMaster, axilRst, axilWriteMaster, r) is
96+
variable v : RegType;
97+
variable axilStatus : AxiLiteStatusType;
98+
variable axilWriteResp : slv(1 downto 0);
99+
variable axilReadResp : slv(1 downto 0);
100+
begin
101+
-- Latch the current value
102+
v := r;
103+
104+
-- Reset strobes
105+
axilWriteResp := AXI_RESP_OK_C;
106+
axilReadResp := AXI_RESP_OK_C;
107+
108+
-- Check for timeout
109+
if r.sclkCnt = 0 then
110+
111+
-- Check if enabled
112+
if (r.sclkEn = '1') then
113+
-- Set the flag
114+
v.sclk := not(r.sclk);
115+
end if;
116+
117+
-- Preset counter
118+
v.sclkCnt := r.sckHalfCycle;
119+
120+
else
121+
-- Decreament counter
122+
v.sclkCnt := r.sclkCnt - 1;
123+
end if;
124+
125+
-- Determine the transaction type
126+
axiSlaveWaitTxn(axilWriteMaster, axilReadMaster, v.axilWriteSlave, v.axilReadSlave, axilStatus);
127+
128+
case r.state is
129+
----------------------------------------------------------------------
130+
when IDLE_S =>
131+
-- Reset the signals in IDLE state
132+
v.busy := '0';
133+
v.sload := '1';
134+
v.sclk := '0';
135+
v.sclkEn := '0';
136+
v.sclkCnt := r.sckHalfCycle;
137+
v.cnt := 0;
138+
139+
-- Check for a write request
140+
if (axilStatus.writeEnable = '1') then
141+
142+
-- Decode address and perform write
143+
case (axilWriteMaster.awaddr(3 downto 0)) is
144+
--------------------------------------------------------
145+
when x"0" =>
146+
-- Set the value
147+
v.delayA := axilWriteMaster.wdata(9 downto 0);
148+
-- Set the flags
149+
v.busy := '1';
150+
v.sload := '0';
151+
v.sclkEn := '1';
152+
-- Next state
153+
v.state := SEND_DATA_S;
154+
--------------------------------------------------------
155+
when x"4" =>
156+
-- Set the value
157+
v.delayB := axilWriteMaster.wdata(9 downto 0);
158+
-- Set the flags
159+
v.busy := '1';
160+
v.sload := '0';
161+
v.sclkEn := '1';
162+
-- Next state
163+
v.state := SEND_DATA_S;
164+
--------------------------------------------------------
165+
when x"C" =>
166+
-- Set the value
167+
v.sckHalfCycle := axilWriteMaster.wdata(7 downto 0);
168+
-- Send AXI-Lite response
169+
axiSlaveWriteResponse(v.axilWriteSlave, axilWriteResp);
170+
--------------------------------------------------------
171+
when others =>
172+
axilWriteResp := AXI_RESP_DECERR_C;
173+
-- Send AXI-Lite response
174+
axiSlaveWriteResponse(v.axilWriteSlave, AXI_RESP_DECERR_C);
175+
--------------------------------------------------------
176+
end case;
177+
178+
-- Check for a read request
179+
elsif (axilStatus.readEnable = '1') then
180+
case (axilReadMaster.araddr(3 downto 0)) is
181+
--------------------------------------------------------
182+
when x"0" =>
183+
v.axilReadSlave.rdata(9 downto 0) := r.delayA;
184+
--------------------------------------------------------
185+
when x"4" =>
186+
v.axilReadSlave.rdata(9 downto 0) := r.delayB;
187+
--------------------------------------------------------
188+
when x"C" =>
189+
v.axilReadSlave.rdata(7 downto 0) := r.sckHalfCycle;
190+
--------------------------------------------------------
191+
when others =>
192+
axilReadResp := AXI_RESP_DECERR_C;
193+
--------------------------------------------------------
194+
end case;
195+
-- Send AXI-Lite Response
196+
axiSlaveReadResponse(v.axilReadSlave, axilReadResp);
197+
end if;
198+
199+
-- Update the shift Register value
200+
v.shiftReg := v.delayB & v.delayA;
201+
-------------------------------------------------
202+
when SEND_DATA_S =>
203+
-- Check for SCLK fallling edge
204+
if (r.sclk = '1') and (v.sclk = '0') then
205+
206+
-- Update the shift register
207+
v.shiftReg := '0' & r.shiftReg(19 downto 1);
208+
209+
-- Increment the counter
210+
v.cnt := r.cnt + 1;
211+
212+
end if;
213+
214+
-- Check for SCLK rising edge
215+
if (r.sclk = '0') and (v.sclk = '1') then
216+
217+
-- Check for last serial bit
218+
if r.cnt = 19 then
219+
220+
-- Reset counter
221+
v.cnt := 0;
222+
223+
-- Next state
224+
v.state := SLOAD_S;
225+
226+
end if;
227+
228+
end if;
229+
-------------------------------------------------
230+
when SLOAD_S =>
231+
-- Check for timeout
232+
if r.sclkCnt = 0 then
233+
234+
-- Increment the counter
235+
v.cnt := r.cnt + 1;
236+
237+
if (r.cnt = 0) then
238+
-- Reset flag
239+
v.sclkEn := '0';
240+
241+
elsif (r.cnt = 1) then
242+
-- Set flag
243+
v.sload := '1';
244+
245+
else
246+
247+
-- Send AXI-Lite response
248+
axiSlaveWriteResponse(v.axilWriteSlave, axilWriteResp);
249+
250+
-- Next state
251+
v.state := IDLE_S;
252+
253+
end if;
254+
255+
end if;
256+
-------------------------------------------------
257+
end case;
258+
259+
-- Outputs
260+
axilWriteSlave <= r.axilWriteSlave;
261+
axilReadSlave <= r.axilReadSlave;
262+
enableL <= r.busy; -- Active LOW
263+
enaL <= r.busy; -- Active LOW
264+
enbL <= r.busy; -- Active LOW
265+
sdata <= r.shiftReg(0);
266+
sclk <= r.sclk;
267+
sload <= r.sload;
268+
269+
-- Reset
270+
if (axilRst = '1') then
271+
v := REG_INIT_C;
272+
end if;
273+
274+
-- Register the variable for next clock cycle
275+
rin <= v;
276+
end process;
277+
278+
seq : process (axilClk) is
279+
begin
280+
if rising_edge(axilClk) then
281+
r <= rin after TPD_G;
282+
end if;
283+
end process seq;
284+
285+
end rtl;

devices/Microchip/sy89297/ruckus.tcl

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
# Load RUCKUS library
2+
source $::env(RUCKUS_PROC_TCL)
3+
4+
# Load Source Code
5+
loadSource -lib surf -dir "$::DIR_PATH/rtl"
+50
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
##############################################################################
2+
## This file is part of 'SLAC Firmware Standard Library'.
3+
## It is subject to the license terms in the LICENSE.txt file found in the
4+
## top-level directory of this distribution and at:
5+
## https://confluence.slac.stanford.edu/display/ppareg/LICENSE.html.
6+
## No part of 'SLAC Firmware Standard Library', including this file,
7+
## may be copied, modified, propagated, or distributed except according to
8+
## the terms contained in the LICENSE.txt file.
9+
##############################################################################
10+
11+
import pyrogue as pr
12+
13+
class Sy89297(pr.Device):
14+
def __init__( self, **kwargs):
15+
super().__init__(**kwargs)
16+
17+
self.add(pr.RemoteVariable(
18+
name = 'DelayA',
19+
description = 'Delay Channel A',
20+
offset = 0x0,
21+
bitSize = 10,
22+
mode = 'RW',
23+
units = '5ps/step',
24+
))
25+
26+
self.add(pr.RemoteVariable(
27+
name = 'DelayB',
28+
description = 'Delay Channel B',
29+
offset = 0x4,
30+
bitSize = 10,
31+
mode = 'RW',
32+
units = '5ps/step',
33+
))
34+
35+
self.add(pr.RemoteVariable(
36+
name = 'SckHalfPeriod',
37+
offset = 0xC,
38+
bitSize = 8,
39+
mode = 'RW',
40+
hidden = True,
41+
))
42+
43+
def setDelay(self, delayA=None, delayB=None):
44+
if delayA is not None:
45+
if self.DelayB.value() != delayA:
46+
self.DelayA.set(delayA)
47+
48+
if delayB is not None:
49+
if self.DelayB.value() != delayB:
50+
self.DelayB.set(delayB)

python/surf/devices/microchip/__init__.py

+1
Original file line numberDiff line numberDiff line change
@@ -10,3 +10,4 @@
1010
from surf.devices.microchip._Axi24LC64FT import *
1111
from surf.devices.microchip._AxiSy56040 import *
1212
from surf.devices.microchip._Tcn75a import *
13+
from surf.devices.microchip._Sy89297 import *

0 commit comments

Comments
 (0)