5
5
from migen .sim .generic import run_simulation
6
6
7
7
8
+ class WaitTimer (Module ):
9
+ def __init__ (self , t ):
10
+ self .wait = Signal ()
11
+ self .done = Signal ()
12
+
13
+ # # #
14
+
15
+ count = Signal (bits_for (t ), reset = t )
16
+ self .comb += self .done .eq (count == 0 )
17
+ self .sync += \
18
+ If (self .wait ,
19
+ If (~ self .done , count .eq (count - 1 ))
20
+ ).Else (count .eq (count .reset ))
21
+
22
+
8
23
class AD9858 (Module ):
9
24
"""Wishbone interface to the AD9858 DDS chip.
10
25
@@ -33,7 +48,9 @@ class AD9858(Module):
33
48
Round-trip addr A setup (> RX, RD, D to Z), RD prop, D valid (< D
34
49
valid), D prop is ~15 + 10 + 20 + 10 = 55ns
35
50
"""
36
- def __init__ (self , pads , drive_fud = False , bus = None ):
51
+ def __init__ (self , pads , drive_fud = False ,
52
+ read_wait_cycles = 10 , hiz_wait_cycles = 3 ,
53
+ bus = None ):
37
54
if bus is None :
38
55
bus = wishbone .Interface ()
39
56
self .bus = bus
@@ -42,10 +59,11 @@ def __init__(self, pads, drive_fud=False, bus=None):
42
59
43
60
dts = TSTriple (8 )
44
61
self .specials += dts .get_tristate (pads .d )
62
+ hold_address = Signal ()
45
63
dr = Signal (8 )
46
64
rx = Signal ()
47
65
self .sync += [
48
- pads .a .eq (bus .adr ),
66
+ If ( ~ hold_address , pads .a .eq (bus .adr ) ),
49
67
dts .o .eq (bus .dat_w ),
50
68
dr .eq (dts .i ),
51
69
dts .oe .eq (~ rx )
@@ -76,6 +94,9 @@ def __init__(self, pads, drive_fud=False, bus=None):
76
94
rd = Signal ()
77
95
self .sync += pads .wr_n .eq (~ wr ), pads .rd_n .eq (~ rd )
78
96
97
+ self .submodules .read_timer = WaitTimer (read_wait_cycles )
98
+ self .submodules .hiz_timer = WaitTimer (hiz_wait_cycles )
99
+
79
100
fsm = FSM ("IDLE" )
80
101
self .submodules += fsm
81
102
@@ -112,38 +133,18 @@ def __init__(self, pads, drive_fud=False, bus=None):
112
133
# 15ns D valid to RD active
113
134
rx .eq (1 ),
114
135
rd .eq (1 ),
115
- NextState ("READ0" )
116
- )
117
- fsm .act ("READ0" ,
118
- rx .eq (1 ),
119
- rd .eq (1 ),
120
- NextState ("READ1" )
121
- )
122
- fsm .act ("READ1" ,
123
- rx .eq (1 ),
124
- rd .eq (1 ),
125
- NextState ("READ2" )
126
- )
127
- fsm .act ("READ2" ,
128
- rx .eq (1 ),
129
- rd .eq (1 ),
130
- NextState ("READ3" )
131
- )
132
- fsm .act ("READ3" ,
133
- rx .eq (1 ),
134
- rd .eq (1 ),
135
- NextState ("READ4" )
136
- )
137
- fsm .act ("READ4" ,
138
- rx .eq (1 ),
139
- NextState ("READ5" )
136
+ self .read_timer .wait .eq (1 ),
137
+ If (self .read_timer .done ,
138
+ bus .ack .eq (1 ),
139
+ NextState ("WAIT_HIZ" )
140
+ )
140
141
)
141
- fsm .act ("READ5" ,
142
- # 5ns D three-state to RD inactive
143
- # 10ns A hold to RD inactive
142
+ fsm .act ("WAIT_HIZ" ,
144
143
rx .eq (1 ),
145
- bus .ack .eq (1 ),
146
- NextState ("IDLE" )
144
+ # For some reason, AD9858 has a address hold time to RD inactive.
145
+ hold_address .eq (1 ),
146
+ self .hiz_timer .wait .eq (1 ),
147
+ If (self .hiz_timer .done , NextState ("IDLE" ))
147
148
)
148
149
if drive_fud :
149
150
fsm .act ("FUD" ,
0 commit comments