ba7bcf071e8a477f7ebc5d69fd3e83e886693ee0
[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
140 def __init__(self, platform):
141 clk_freq = 166*1000000
142 GenSoC.__init__(self, platform, clk_freq)
143 self.submodules.crg = _CRG(platform)
144
145 # SATA PHY/Core/Frontend
146 self.submodules.sata_phy = LiteSATAPHY(platform.device, platform.request("sata"), "sata_gen2", clk_freq)
147 self.comb += self.crg.reset.eq(self.sata_phy.ctrl.need_reset) # XXX FIXME
148 self.submodules.sata = LiteSATA(self.sata_phy, with_bist=True, with_bist_csr=True)
149
150 # Status Leds
151 self.submodules.leds = BISTLeds(platform, self.sata_phy)
152
153 class BISTSoCDevel(BISTSoC, AutoCSR):
154 csr_map = {
155 "la": 10
156 }
157 csr_map.update(BISTSoC.csr_map)
158 def __init__(self, platform):
159 BISTSoC.__init__(self, platform)
160
161 self.sata_core_link_rx_fsm_state = Signal(4)
162 self.sata_core_link_tx_fsm_state = Signal(4)
163 self.sata_core_transport_rx_fsm_state = Signal(4)
164 self.sata_core_transport_tx_fsm_state = Signal(4)
165 self.sata_core_command_rx_fsm_state = Signal(4)
166 self.sata_core_command_tx_fsm_state = Signal(4)
167
168 self.debug = (
169 self.sata_phy.ctrl.ready,
170
171 self.sata_phy.source.stb,
172 self.sata_phy.source.data,
173 self.sata_phy.source.charisk,
174
175 self.sata_phy.sink.stb,
176 self.sata_phy.sink.data,
177 self.sata_phy.sink.charisk,
178
179 self.sata.core.command.sink.stb,
180 self.sata.core.command.sink.sop,
181 self.sata.core.command.sink.eop,
182 self.sata.core.command.sink.ack,
183 self.sata.core.command.sink.write,
184 self.sata.core.command.sink.read,
185 self.sata.core.command.sink.identify,
186
187 self.sata.core.command.source.stb,
188 self.sata.core.command.source.sop,
189 self.sata.core.command.source.eop,
190 self.sata.core.command.source.ack,
191 self.sata.core.command.source.write,
192 self.sata.core.command.source.read,
193 self.sata.core.command.source.identify,
194 self.sata.core.command.source.failed,
195 self.sata.core.command.source.data,
196
197 self.sata_core_link_rx_fsm_state,
198 self.sata_core_link_tx_fsm_state,
199 self.sata_core_transport_rx_fsm_state,
200 self.sata_core_transport_tx_fsm_state,
201 self.sata_core_command_rx_fsm_state,
202 self.sata_core_command_tx_fsm_state,
203 )
204
205 self.submodules.la = LiteScopeLA(2048, self.debug)
206 self.la.add_port(LiteScopeTerm)
207 atexit.register(self.exit, platform)
208
209 def do_finalize(self):
210 BISTSoC.do_finalize(self)
211 self.comb += [
212 self.sata_core_link_rx_fsm_state.eq(self.sata.core.link.rx.fsm.state),
213 self.sata_core_link_tx_fsm_state.eq(self.sata.core.link.tx.fsm.state),
214 self.sata_core_transport_rx_fsm_state.eq(self.sata.core.transport.rx.fsm.state),
215 self.sata_core_transport_tx_fsm_state.eq(self.sata.core.transport.tx.fsm.state),
216 self.sata_core_command_rx_fsm_state.eq(self.sata.core.command.rx.fsm.state),
217 self.sata_core_command_tx_fsm_state.eq(self.sata.core.command.tx.fsm.state)
218 ]
219
220 def exit(self, platform):
221 if platform.vns is not None:
222 self.la.export(self.debug, platform.vns, "./test/la.csv")
223
224 default_subtarget = BISTSoC