189216e241b0ec5fbd51a3bce826edc376f11c5e
3 from migen
import ClockSignal
, ResetSignal
, Signal
, Instance
, Cat
5 from litex
.soc
.interconnect
import wishbone
as wb
6 from litex
.soc
.cores
.cpu
import CPU
8 from soc
.config
.pinouts
import get_pinspecs
9 from soc
.debug
.jtag
import Pins
10 from c4m
.nmigen
.jtag
.tap
import IOType
12 from libresoc
.ls180
import io
13 from litex
.build
.generic_platform
import ConstraintManager
16 CPU_VARIANTS
= ["standard", "standard32", "standardjtag",
17 "standardjtagtestgpio", "ls180",
21 def make_wb_bus(prefix
, obj
, simple
=False):
23 outpins
= ['stb', 'cyc', 'we', 'adr', 'dat_w', 'sel']
25 outpins
+= ['cti', 'bte']
27 res
['o_%s__%s' % (prefix
, o
)] = getattr(obj
, o
)
28 for i
in ['ack', 'err', 'dat_r']:
29 res
['i_%s__%s' % (prefix
, i
)] = getattr(obj
, i
)
32 def make_wb_slave(prefix
, obj
, simple
=False):
34 inpins
= ['stb', 'cyc', 'we', 'adr', 'dat_w', 'sel']
36 inpins
+= ['cti', 'bte']
38 res
['i_%s__%s' % (prefix
, i
)] = getattr(obj
, i
)
39 for o
in ['ack', 'err', 'dat_r']:
40 res
['o_%s__%s' % (prefix
, o
)] = getattr(obj
, o
)
43 def make_pad(res
, dirn
, name
, suffix
, cpup
, iop
):
44 cpud
, iod
= ('i', 'o') if dirn
else ('o', 'i')
45 cname
= '%s_%s__core__%s' % (cpud
, name
, suffix
)
46 pname
= '%s_%s__pad__%s' % (iod
, name
, suffix
)
47 print ("make pad", name
, dirn
, cpud
, iod
, cname
, pname
, suffix
, cpup
, iop
)
48 res
[cname
], res
[pname
] = cpup
, iop
50 def get_field(rec
, name
):
54 return getattr(rec
, f
)
57 def make_jtag_ioconn(res
, pin
, cpupads
, iopads
):
58 (fn
, pin
, iotype
, pin_name
, scan_idx
) = pin
59 #serial_tx__core__o, serial_rx__pad__i,
60 # special-case sdram_clock
61 if pin
== 'clock' and fn
== 'sdr':
62 cpu
= cpupads
['sdram_clock']
63 io
= iopads
['sdram_clock']
67 print ("cpupads", cpupads
)
68 print ("iopads", iopads
)
69 print ("pin", fn
, pin
, iotype
, pin_name
)
72 name
= "%s_%s" % (fn
, pin
)
76 if iotype
in (IOType
.In
, IOType
.Out
):
78 if pin
== 'clock' and fn
== 'sdr':
81 elif len(ps
) == 2 and ps
[-1].isdigit():
84 print ("ps split", pin
, idx
)
85 cpup
= getattr(cpu
, pin
)[idx
]
86 iop
= getattr(io
, pin
)[idx
]
93 cpup
= getattr(cpu
, pin
)
94 iop
= getattr(io
, pin
)
96 if iotype
== IOType
.Out
:
97 # output from the pad is routed through C4M JTAG and so
98 # is an *INPUT* into core. ls180soc connects this to "real" peripheral
99 make_pad(res
, True, name
, "o", cpup
, iop
)
101 elif iotype
== IOType
.In
:
102 # input to the pad is routed through C4M JTAG and so
103 # is an *OUTPUT* into core. ls180soc connects this to "real" peripheral
104 make_pad(res
, True, name
, "i", cpup
, iop
)
106 elif iotype
== IOType
.InTriOut
:
107 if fn
== 'gpio': # sigh decode GPIO special-case
110 elif fn
== 'sdr': # sigh
111 idx
= int(pin
.split('_')[-1])
116 print ("gpio tri", fn
, pin
, iotype
, pin_name
, scan_idx
, idx
)
117 cpup
, iop
= get_field(cpu
, "i")[idx
], get_field(io
, "i")[idx
]
118 make_pad(res
, True, name
, "i", cpup
, iop
)
119 cpup
, iop
= get_field(cpu
, "o")[idx
], get_field(io
, "o")[idx
]
120 make_pad(res
, True, name
, "o", cpup
, iop
)
121 cpup
, iop
= get_field(cpu
, "oe")[oe_idx
], get_field(io
, "oe")[oe_idx
]
122 make_pad(res
, True, name
, "oe", cpup
, iop
)
124 if iotype
in (IOType
.In
, IOType
.InTriOut
):
125 sigs
.append(("i", 1))
126 if iotype
in (IOType
.Out
, IOType
.TriOut
, IOType
.InTriOut
):
127 sigs
.append(("o", 1))
128 if iotype
in (IOType
.TriOut
, IOType
.InTriOut
):
129 sigs
.append(("oe", 1))
134 human_name
= "Libre-SoC"
135 variants
= CPU_VARIANTS
136 endianness
= "little"
137 gcc_triple
= ("powerpc64le-linux", "powerpc64le-linux-gnu")
138 linker_output_format
= "elf64-powerpcle"
140 io_regions
= {0xc0000000: 0x10000000} # origin, length
144 return {"csr": 0xc0000000}
149 flags
+= "-mabi=elfv2 "
150 flags
+= "-msoft-float "
151 flags
+= "-mno-string "
152 flags
+= "-mno-multiple "
154 flags
+= "-mno-altivec "
155 flags
+= "-mlittle-endian "
156 flags
+= "-mstrict-align "
157 flags
+= "-fno-stack-protector "
158 flags
+= "-mcmodel=small "
159 flags
+= "-D__microwatt__ "
162 def __init__(self
, platform
, variant
="standard"):
163 self
.platform
= platform
164 self
.variant
= variant
165 self
.reset
= Signal()
167 irq_en
= "noirq" not in variant
170 self
.interrupt
= Signal(16)
172 if variant
== "standard32":
174 self
.dbus
= dbus
= wb
.Interface(data_width
=32, adr_width
=30)
176 self
.dbus
= dbus
= wb
.Interface(data_width
=64, adr_width
=29)
178 self
.ibus
= ibus
= wb
.Interface(data_width
=64, adr_width
=29)
180 self
.xics_icp
= icp
= wb
.Interface(data_width
=32, adr_width
=30)
181 self
.xics_ics
= ics
= wb
.Interface(data_width
=32, adr_width
=30)
183 jtag_en
= ('jtag' in variant
) or variant
== 'ls180'
185 if "testgpio" in variant
:
186 self
.simple_gpio
= gpio
= wb
.Interface(data_width
=32, adr_width
=30)
188 self
.jtag_wb
= jtag_wb
= wb
.Interface(data_width
=64, adr_width
=29)
190 if "sram4k" in variant
or variant
== 'ls180':
191 self
.srams
= srams
= []
193 srams
.append(wb
.Interface(data_width
=64, adr_width
=29))
195 self
.periph_buses
= [ibus
, dbus
]
196 self
.memory_buses
= []
199 self
.periph_buses
.append(jtag_wb
)
200 self
.jtag_tck
= Signal(1)
201 self
.jtag_tms
= Signal(1)
202 self
.jtag_tdi
= Signal(1)
203 self
.jtag_tdo
= Signal(1)
205 self
.dmi_addr
= Signal(4)
206 self
.dmi_din
= Signal(64)
207 self
.dmi_dout
= Signal(64)
208 self
.dmi_wr
= Signal(1)
209 self
.dmi_ack
= Signal(1)
210 self
.dmi_req
= Signal(1)
214 self
.cpu_params
= dict(
216 i_clk
= ClockSignal(),
217 i_rst
= ResetSignal() | self
.reset
,
219 # Monitoring / Debugging
222 i_core_bigendian_i
= 0, # Signal(),
223 o_busy_o
= Signal(), # not connected
224 o_memerr_o
= Signal(), # not connected
225 o_pc_o
= Signal(64), # not connected
230 self
.cpu_params
['i_int_level_i'] = self
.interrupt
233 self
.cpu_params
.update(dict(
235 o_TAP_bus__tdo
= self
.jtag_tdo
,
236 i_TAP_bus__tdi
= self
.jtag_tdi
,
237 i_TAP_bus__tms
= self
.jtag_tms
,
238 i_TAP_bus__tck
= self
.jtag_tck
,
241 self
.cpu_params
.update(dict(
243 i_dmi_addr_i
= self
.dmi_addr
,
244 i_dmi_din
= self
.dmi_din
,
245 o_dmi_dout
= self
.dmi_dout
,
246 i_dmi_req_i
= self
.dmi_req
,
247 i_dmi_we_i
= self
.dmi_wr
,
248 o_dmi_ack_o
= self
.dmi_ack
,
251 # add clock select, pll output
252 if variant
== "ls180":
253 self
.pll_18_o
= Signal()
254 self
.clk_sel
= Signal(2)
255 self
.pll_lck_o
= Signal()
256 self
.cpu_params
['i_clk_sel_i'] = self
.clk_sel
257 self
.cpu_params
['o_pll_18_o'] = self
.pll_18_o
258 self
.cpu_params
['o_pll_lck_o'] = self
.pll_lck_o
260 # add wishbone buses to cpu params
261 self
.cpu_params
.update(make_wb_bus("ibus", ibus
, True))
262 self
.cpu_params
.update(make_wb_bus("dbus", dbus
, True))
263 self
.cpu_params
.update(make_wb_slave("ics_wb", ics
, True))
264 self
.cpu_params
.update(make_wb_slave("icp_wb", icp
, True))
265 if "testgpio" in variant
:
266 self
.cpu_params
.update(make_wb_slave("gpio_wb", gpio
))
268 self
.cpu_params
.update(make_wb_bus("jtag_wb", jtag_wb
, simple
=True))
269 if "sram4k" in variant
or variant
== 'ls180':
270 for i
, sram
in enumerate(srams
):
271 self
.cpu_params
.update(make_wb_slave("sram4k_%d_wb" % i
, sram
))
273 # and set ibus advanced tags to zero (disable)
274 self
.cpu_params
['i_ibus__cti'] = 0
275 self
.cpu_params
['i_ibus__bte'] = 0
276 self
.cpu_params
['i_dbus__cti'] = 0
277 self
.cpu_params
['i_dbus__bte'] = 0
279 if variant
== 'ls180':
280 # urr yuk. have to expose iopads / pins from core to litex
281 # then back again. cut _some_ of that out by connecting
282 self
.padresources
= io()
283 self
.pad_cm
= ConstraintManager(self
.padresources
, [])
287 subset
= {'uart', 'mtwi', 'eint', 'gpio', 'mspi0', 'mspi1',
289 for periph
in subset
:
292 if periph
[-1].isdigit():
293 periph
, num
= periph
[:-1], int(periph
[-1])
294 print ("periph request", periph
, num
)
297 periph
, num
= 'spimaster', None
299 periph
, num
= 'spisdcard', None
300 elif periph
== 'sdr':
302 elif periph
== 'mtwi':
305 periph
, num
= 'sdcard', None
306 litexmap
[origperiph
] = (periph
, num
)
307 self
.cpupads
[origperiph
] = platform
.request(periph
, num
)
308 iopads
[origperiph
] = self
.pad_cm
.request(periph
, num
)
309 if periph
== 'sdram':
310 # special-case sdram clock
311 ck
= platform
.request("sdram_clock")
312 self
.cpupads
['sdram_clock'] = ck
313 ck
= self
.pad_cm
.request("sdram_clock")
314 iopads
['sdram_clock'] = ck
316 pinset
= get_pinspecs(subset
=subset
)
319 make_jtag_ioconn(self
.cpu_params
, pin
, self
.cpupads
, iopads
)
321 # add verilog sources
322 self
.add_sources(platform
)
324 def set_reset_address(self
, reset_address
):
325 assert not hasattr(self
, "reset_address")
326 self
.reset_address
= reset_address
327 assert reset_address
== 0x00000000
330 def add_sources(platform
):
331 cdir
= os
.path
.dirname(__file__
)
332 platform
.add_source(os
.path
.join(cdir
, "libresoc.v"))
334 def do_finalize(self
):
335 self
.specials
+= Instance("test_issuer", **self
.cpu_params
)