1
+ from migen .fhdl .std import *
2
+ from migen .flow .actor import *
3
+ from migen .fhdl .specials import *
4
+
5
+ from migen .sim .generic import run_simulation
6
+
7
+ from misoclib .com .liteusb .common import *
8
+ from misoclib .com .liteusb .phy .ft2232h import FT2232HPHYSynchronous
9
+ from misoclib .com .liteusb .test .common import *
10
+
11
+ # XXX for now use it from liteeth to avoid duplication
12
+ from misoclib .com .liteeth .test .common import *
13
+
14
+ class FT2232HSynchronousModel (Module , RandRun ):
15
+ def __init__ (self , rd_data ):
16
+ RandRun .__init__ (self , 10 )
17
+ self .rd_data = [0 ] + rd_data
18
+ self .rd_idx = 0
19
+
20
+ # pads
21
+ self .data = Signal (8 )
22
+ self .rxf_n = Signal (reset = 1 )
23
+ self .txe_n = Signal (reset = 1 )
24
+ self .rd_n = Signal (reset = 1 )
25
+ self .wr_n = Signal (reset = 1 )
26
+ self .oe_n = Signal (reset = 1 )
27
+ self .siwua = Signal ()
28
+ self .pwren_n = Signal (reset = 1 )
29
+
30
+ self .init = True
31
+ self .wr_data = []
32
+ self .wait_wr_n = False
33
+ self .rd_done = 0
34
+
35
+
36
+ self .data_w = Signal (8 )
37
+ self .data_r = Signal (8 )
38
+
39
+ self .specials += Tristate (self .data , self .data_r , ~ self .oe_n , self .data_w )
40
+
41
+ def wr_sim (self , selfp ):
42
+ if not selfp .wr_n and not selfp .txe_n :
43
+ self .wr_data .append (selfp .data_w )
44
+ self .wait_wr_n = False
45
+
46
+ if not self .wait_wr_n :
47
+ if self .run :
48
+ selfp .txe_n = 1
49
+ else :
50
+ if selfp .txe_n :
51
+ self .wait_wr_n = True
52
+ selfp .txe_n = 0
53
+
54
+ def rd_sim (self , selfp ):
55
+ rxf_n = selfp .rxf_n
56
+ if self .run :
57
+ if self .rd_idx < len (self .rd_data )- 1 :
58
+ self .rd_done = selfp .rxf_n
59
+ selfp .rxf_n = 0
60
+ else :
61
+ selfp .rxf_n = self .rd_done
62
+ else :
63
+ selfp .rxf_n = self .rd_done
64
+
65
+ if not selfp .rd_n and not selfp .oe_n :
66
+ if self .rd_idx < len (self .rd_data )- 1 :
67
+ self .rd_idx += not rxf_n
68
+ selfp .data_r = self .rd_data [self .rd_idx ]
69
+ self .rd_done = 1
70
+
71
+ def do_simulation (self , selfp ):
72
+ RandRun .do_simulation (self , selfp )
73
+ if self .init :
74
+ selfp .rxf_n = 0
75
+ self .wr_data = []
76
+ self .init = False
77
+ self .wr_sim (selfp )
78
+ self .rd_sim (selfp )
79
+
80
+ test_packet = [i % 256 for i in range (512 )]
81
+
82
+
83
+ class TB (Module ):
84
+ def __init__ (self ):
85
+ self .submodules .model = FT2232HSynchronousModel (test_packet )
86
+ self .submodules .phy = FT2232HPHYSynchronous (self .model )
87
+
88
+ self .submodules .streamer = PacketStreamer (phy_description (8 ))
89
+ self .submodules .streamer_randomizer = AckRandomizer (phy_description (8 ), level = 10 )
90
+
91
+ self .submodules .logger_randomizer = AckRandomizer (phy_description (8 ), level = 10 )
92
+ self .submodules .logger = PacketLogger (phy_description (8 ))
93
+
94
+ self .comb += [
95
+ Record .connect (self .streamer .source , self .streamer_randomizer .sink ),
96
+ self .phy .sink .stb .eq (self .streamer_randomizer .source .stb ),
97
+ self .phy .sink .data .eq (self .streamer_randomizer .source .data ),
98
+ self .streamer_randomizer .source .ack .eq (self .phy .sink .ack ),
99
+
100
+ self .logger_randomizer .sink .stb .eq (self .phy .source .stb ),
101
+ self .logger_randomizer .sink .data .eq (self .phy .source .data ),
102
+ self .phy .source .ack .eq (self .logger_randomizer .sink .ack ),
103
+ Record .connect (self .logger_randomizer .source , self .logger .sink )
104
+ ]
105
+
106
+ # Use sys_clk as ftdi_clk in simulation
107
+ self .comb += [
108
+ ClockSignal ("ftdi" ).eq (ClockSignal ()),
109
+ ResetSignal ("ftdi" ).eq (ResetSignal ())
110
+ ]
111
+
112
+ def gen_simulation (self , selfp ):
113
+ yield from self .streamer .send (Packet (test_packet ))
114
+ for i in range (2000 ):
115
+ yield
116
+ s , l , e = check (test_packet , self .model .wr_data )
117
+ print ("shift " + str (s ) + " / length " + str (l ) + " / errors " + str (e ))
118
+
119
+ s , l , e = check (test_packet , self .logger .packet [1 :])
120
+ print ("shift " + str (s ) + " / length " + str (l ) + " / errors " + str (e ))
121
+
122
+
123
+ def main ():
124
+ run_simulation (TB (), ncycles = 8000 , vcd_name = "my.vcd" , keep_files = True )
125
+
126
+ if __name__ == "__main__" :
127
+ main ()
0 commit comments