9d8031490dafaa4b4404ab9f82ced5e8b99a1d69
[litex.git] / targets / bist.py
1 import os, atexit
2
3 from litesata.common import *
4 from migen.bank import csrgen
5 from migen.bus import wishbone, csr
6 from migen.bus import wishbone2csr
7 from migen.genlib.cdc import *
8 from migen.genlib.resetsync import AsyncResetSynchronizer
9 from migen.bank.description import *
10
11 from misoclib import identifier
12
13 from litescope.common import *
14 from litescope.bridge.uart2wb import LiteScopeUART2WB
15 from litescope.frontend.la import LiteScopeLA
16 from litescope.core.trigger import LiteScopeTerm
17
18 from litesata.common import *
19 from litesata.phy import LiteSATAPHY
20 from litesata import LiteSATA
21
22 class _CRG(Module):
23 def __init__(self, platform):
24 self.clock_domains.cd_sys = ClockDomain()
25 self.reset = Signal()
26
27 clk200 = platform.request("clk200")
28 clk200_se = Signal()
29 self.specials += Instance("IBUFDS", i_I=clk200.p, i_IB=clk200.n, o_O=clk200_se)
30
31 pll_locked = Signal()
32 pll_fb = Signal()
33 pll_sys = Signal()
34 self.specials += [
35 Instance("PLLE2_BASE",
36 p_STARTUP_WAIT="FALSE", o_LOCKED=pll_locked,
37
38 # VCO @ 1GHz
39 p_REF_JITTER1=0.01, p_CLKIN1_PERIOD=5.0,
40 p_CLKFBOUT_MULT=5, p_DIVCLK_DIVIDE=1,
41 i_CLKIN1=clk200_se, i_CLKFBIN=pll_fb, o_CLKFBOUT=pll_fb,
42
43 # 166MHz
44 p_CLKOUT0_DIVIDE=6, p_CLKOUT0_PHASE=0.0, o_CLKOUT0=pll_sys,
45
46 p_CLKOUT1_DIVIDE=2, p_CLKOUT1_PHASE=0.0, #o_CLKOUT1=,
47
48 p_CLKOUT2_DIVIDE=2, p_CLKOUT2_PHASE=0.0, #o_CLKOUT2=,
49
50 p_CLKOUT3_DIVIDE=2, p_CLKOUT3_PHASE=0.0, #o_CLKOUT3=,
51
52 p_CLKOUT4_DIVIDE=2, p_CLKOUT4_PHASE=0.0, #o_CLKOUT4=
53 ),
54 Instance("BUFG", i_I=pll_sys, o_O=self.cd_sys.clk),
55 AsyncResetSynchronizer(self.cd_sys, ~pll_locked | platform.request("cpu_reset") | self.reset),
56 ]
57
58 class GenSoC(Module):
59 csr_base = 0x00000000
60 csr_data_width = 32
61 csr_map = {
62 "bridge": 0,
63 "identifier": 1,
64 }
65 interrupt_map = {}
66 cpu_type = None
67 def __init__(self, platform, clk_freq):
68 self.clk_freq = clk_freq
69 # UART <--> Wishbone bridge
70 self.submodules.bridge = LiteScopeUART2WB(platform.request("serial"), clk_freq, baud=921600)
71
72 # CSR bridge 0x00000000 (shadow @0x00000000)
73 self.submodules.wishbone2csr = wishbone2csr.WB2CSR(bus_csr=csr.Interface(self.csr_data_width))
74 self._wb_masters = [self.bridge.wishbone]
75 self._wb_slaves = [(lambda a: a[23:25] == 0, self.wishbone2csr.wishbone)]
76 self.cpu_csr_regions = [] # list of (name, origin, busword, csr_list/Memory)
77
78 # CSR
79 self.submodules.identifier = identifier.Identifier(0, int(clk_freq), 0)
80
81 def add_cpu_memory_region(self, name, origin, length):
82 self.cpu_memory_regions.append((name, origin, length))
83
84 def add_cpu_csr_region(self, name, origin, busword, obj):
85 self.cpu_csr_regions.append((name, origin, busword, obj))
86
87 def do_finalize(self):
88 # Wishbone
89 self.submodules.wishbonecon = wishbone.InterconnectShared(self._wb_masters,
90 self._wb_slaves, register=True)
91
92 # CSR
93 self.submodules.csrbankarray = csrgen.BankArray(self,
94 lambda name, memory: self.csr_map[name if memory is None else name + "_" + memory.name_override],
95 data_width=self.csr_data_width)
96 self.submodules.csrcon = csr.Interconnect(self.wishbone2csr.csr, self.csrbankarray.get_buses())
97 for name, csrs, mapaddr, rmap in self.csrbankarray.banks:
98 self.add_cpu_csr_region(name, 0xe0000000+0x800*mapaddr, flen(rmap.bus.dat_w), csrs)
99 for name, memory, mapaddr, mmap in self.csrbankarray.srams:
100 self.add_cpu_csr_region(name, 0xe0000000+0x800*mapaddr, flen(rmap.bus.dat_w), memory)
101
102 class BISTLeds(Module):
103 def __init__(self, platform, sata_phy):
104 # 1Hz blinking leds (sata_rx and sata_tx clocks)
105 sata_rx_led = platform.request("user_led", 0)
106 sata_tx_led = platform.request("user_led", 1)
107
108 sata_rx_cnt = Signal(32)
109 sata_tx_cnt = Signal(32)
110
111 sata_freq = int(frequencies[sata_phy.revision]*1000*1000)
112
113 self.sync.sata_rx += \
114 If(sata_rx_cnt == 0,
115 sata_rx_led.eq(~sata_rx_led),
116 sata_rx_cnt.eq(sata_freq//2)
117 ).Else(
118 sata_rx_cnt.eq(sata_rx_cnt-1)
119 )
120
121 self.sync.sata_tx += \
122 If(sata_tx_cnt == 0,
123 sata_tx_led.eq(~sata_tx_led),
124 sata_tx_cnt.eq(sata_freq//2)
125 ).Else(
126 sata_tx_cnt.eq(sata_tx_cnt-1)
127 )
128
129 # ready leds (crg and ctrl)
130 self.comb += platform.request("user_led", 2).eq(sata_phy.crg.ready)
131 self.comb += platform.request("user_led", 3).eq(sata_phy.ctrl.ready)
132
133 class BISTSoC(GenSoC, AutoCSR):
134 default_platform = "kc705"
135 csr_map = {
136 "sata": 10,
137 }
138 csr_map.update(GenSoC.csr_map)
139 def __init__(self, platform):
140 clk_freq = 166*1000000
141 GenSoC.__init__(self, platform, clk_freq)
142 self.submodules.crg = _CRG(platform)
143
144 # SATA PHY/Core/Frontend
145 self.submodules.sata_phy = LiteSATAPHY(platform.device, platform.request("sata"), "sata_gen2", clk_freq)
146 self.comb += self.crg.reset.eq(self.sata_phy.ctrl.need_reset) # XXX FIXME
147 self.submodules.sata = LiteSATA(self.sata_phy, with_bist=True, with_bist_csr=True)
148
149 # Status Leds
150 self.submodules.leds = BISTLeds(platform, self.sata_phy)
151
152 class BISTSoCDevel(BISTSoC, AutoCSR):
153 csr_map = {
154 "la": 20
155 }
156 csr_map.update(BISTSoC.csr_map)
157 def __init__(self, platform):
158 BISTSoC.__init__(self, platform)
159
160 self.sata_core_link_rx_fsm_state = Signal(4)
161 self.sata_core_link_tx_fsm_state = Signal(4)
162 self.sata_core_transport_rx_fsm_state = Signal(4)
163 self.sata_core_transport_tx_fsm_state = Signal(4)
164 self.sata_core_command_rx_fsm_state = Signal(4)
165 self.sata_core_command_tx_fsm_state = Signal(4)
166
167 self.debug = (
168 self.sata_phy.ctrl.ready,
169
170 self.sata_phy.source.stb,
171 self.sata_phy.source.data,
172 self.sata_phy.source.charisk,
173
174 self.sata_phy.sink.stb,
175 self.sata_phy.sink.data,
176 self.sata_phy.sink.charisk,
177
178 self.sata.core.command.sink.stb,
179 self.sata.core.command.sink.sop,
180 self.sata.core.command.sink.eop,
181 self.sata.core.command.sink.ack,
182 self.sata.core.command.sink.write,
183 self.sata.core.command.sink.read,
184 self.sata.core.command.sink.identify,
185
186 self.sata.core.command.source.stb,
187 self.sata.core.command.source.sop,
188 self.sata.core.command.source.eop,
189 self.sata.core.command.source.ack,
190 self.sata.core.command.source.write,
191 self.sata.core.command.source.read,
192 self.sata.core.command.source.identify,
193 self.sata.core.command.source.failed,
194 self.sata.core.command.source.data,
195
196 self.sata_core_link_rx_fsm_state,
197 self.sata_core_link_tx_fsm_state,
198 self.sata_core_transport_rx_fsm_state,
199 self.sata_core_transport_tx_fsm_state,
200 self.sata_core_command_rx_fsm_state,
201 self.sata_core_command_tx_fsm_state,
202 )
203
204 self.submodules.la = LiteScopeLA(2048, self.debug)
205 self.la.add_port(LiteScopeTerm)
206 atexit.register(self.exit, platform)
207
208 def do_finalize(self):
209 BISTSoC.do_finalize(self)
210 self.comb += [
211 self.sata_core_link_rx_fsm_state.eq(self.sata.core.link.rx.fsm.state),
212 self.sata_core_link_tx_fsm_state.eq(self.sata.core.link.tx.fsm.state),
213 self.sata_core_transport_rx_fsm_state.eq(self.sata.core.transport.rx.fsm.state),
214 self.sata_core_transport_tx_fsm_state.eq(self.sata.core.transport.tx.fsm.state),
215 self.sata_core_command_rx_fsm_state.eq(self.sata.core.command.rx.fsm.state),
216 self.sata_core_command_tx_fsm_state.eq(self.sata.core.command.tx.fsm.state)
217 ]
218
219 def exit(self, platform):
220 if platform.vns is not None:
221 self.la.export(self.debug, platform.vns, "./test/la.csv")
222
223 default_subtarget = BISTSoC