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
.debug
.jtag
import Pins
# TODO move to suitable location
9 from c4m
.nmigen
.jtag
.tap
import IOType
11 from libresoc
.ls180io
import make_uart
, make_gpio
12 from litex
.build
.generic_platform
import ConstraintManager
15 CPU_VARIANTS
= ["standard", "standard32", "standardjtag", "ls180"]
18 def make_wb_bus(prefix
, obj
, simple
=False):
20 outpins
= ['stb', 'cyc', 'we', 'adr', 'dat_w', 'sel']
22 outpins
+= ['cti', 'bte']
24 res
['o_%s__%s' % (prefix
, o
)] = getattr(obj
, o
)
25 for i
in ['ack', 'err', 'dat_r']:
26 res
['i_%s__%s' % (prefix
, i
)] = getattr(obj
, i
)
29 def make_wb_slave(prefix
, obj
):
31 for i
in ['stb', 'cyc', 'cti', 'bte', 'we', 'adr', 'dat_w', 'sel']:
32 res
['i_%s__%s' % (prefix
, i
)] = getattr(obj
, i
)
33 for o
in ['ack', 'err', 'dat_r']:
34 res
['o_%s__%s' % (prefix
, o
)] = getattr(obj
, o
)
38 def make_jtag_ioconn(res
, pin
, cpupads
, iopads
):
39 (fn
, pin
, iotype
, pin_name
) = pin
40 #serial_tx__core__o, serial_rx__pad__i,
41 print ("cpupads", cpupads
)
42 print ("iopads", iopads
)
43 print ("pin", fn
, pin
, iotype
, pin_name
)
48 if iotype
== IOType
.Out
:
49 # output from the pad is routed through C4M JTAG and so
50 # is an *INPUT* into core. ls180soc connects this to "real" peripheral
51 res
['i_%s_%s_core__o' % (fn
, pin
)] = getattr(cpu
, pin
)
52 res
['o_%s_%s_pad__o' % (fn
, pin
)] = getattr(io
, pin
)
54 elif iotype
== IOType
.In
:
55 # input to the pad is routed through C4M JTAG and so
56 # is an *OUTPUT* into core. ls180soc connects this to "real" peripheral
57 res
['o_%s_%s_core__i' % (fn
, pin
)] = getattr(cpu
, pin
)
58 res
['i_%s_%s_pad__i' % (fn
, pin
)] = getattr(io
, pin
)
60 if iotype
in (IOType
.In
, IOType
.InTriOut
):
62 if iotype
in (IOType
.Out
, IOType
.TriOut
, IOType
.InTriOut
):
64 if iotype
in (IOType
.TriOut
, IOType
.InTriOut
):
65 sigs
.append(("oe", 1))
69 human_name
= "Libre-SoC"
70 variants
= CPU_VARIANTS
72 gcc_triple
= ("powerpc64le-linux", "powerpc64le-linux-gnu")
73 linker_output_format
= "elf64-powerpcle"
75 io_regions
= {0xc0000000: 0x10000000} # origin, length
79 return {"csr": 0xc0000000}
84 flags
+= "-mabi=elfv2 "
85 flags
+= "-msoft-float "
86 flags
+= "-mno-string "
87 flags
+= "-mno-multiple "
89 flags
+= "-mno-altivec "
90 flags
+= "-mlittle-endian "
91 flags
+= "-mstrict-align "
92 flags
+= "-fno-stack-protector "
93 flags
+= "-mcmodel=small "
94 flags
+= "-D__microwatt__ "
97 def __init__(self
, platform
, variant
="standard"):
98 self
.platform
= platform
99 self
.variant
= variant
100 self
.reset
= Signal()
101 self
.interrupt
= Signal(16)
103 if variant
== "standard32":
105 self
.dbus
= dbus
= wb
.Interface(data_width
=32, adr_width
=30)
107 self
.dbus
= dbus
= wb
.Interface(data_width
=64, adr_width
=29)
109 self
.ibus
= ibus
= wb
.Interface(data_width
=64, adr_width
=29)
111 self
.xics_icp
= icp
= wb
.Interface(data_width
=32, adr_width
=30)
112 self
.xics_ics
= ics
= wb
.Interface(data_width
=32, adr_width
=30)
114 jtag_en
= ('jtag' in variant
) or variant
== 'ls180'
116 if variant
!= "ls180":
117 self
.simple_gpio
= gpio
= wb
.Interface(data_width
=32, adr_width
=30)
119 self
.jtag_wb
= jtag_wb
= wb
.Interface(data_width
=64, adr_width
=29)
121 self
.periph_buses
= [ibus
, dbus
]
122 self
.memory_buses
= []
125 self
.periph_buses
.append(jtag_wb
)
126 self
.jtag_tck
= Signal(1)
127 self
.jtag_tms
= Signal(1)
128 self
.jtag_tdi
= Signal(1)
129 self
.jtag_tdo
= Signal(1)
131 self
.dmi_addr
= Signal(4)
132 self
.dmi_din
= Signal(64)
133 self
.dmi_dout
= Signal(64)
134 self
.dmi_wr
= Signal(1)
135 self
.dmi_ack
= Signal(1)
136 self
.dmi_req
= Signal(1)
140 self
.cpu_params
= dict(
142 i_clk
= ClockSignal(),
143 i_rst
= ResetSignal() | self
.reset
,
145 # Monitoring / Debugging
148 i_core_bigendian_i
= 0, # Signal(),
149 o_busy_o
= Signal(), # not connected
150 o_memerr_o
= Signal(), # not connected
151 o_pc_o
= Signal(64), # not connected
154 i_int_level_i
= self
.interrupt
,
159 self
.cpu_params
.update(dict(
161 o_TAP_bus__tdo
= self
.jtag_tdo
,
162 i_TAP_bus__tdi
= self
.jtag_tdi
,
163 i_TAP_bus__tms
= self
.jtag_tms
,
164 i_TAP_bus__tck
= self
.jtag_tck
,
167 self
.cpu_params
.update(dict(
169 i_dmi_addr_i
= self
.dmi_addr
,
170 i_dmi_din
= self
.dmi_din
,
171 o_dmi_dout
= self
.dmi_dout
,
172 i_dmi_req_i
= self
.dmi_req
,
173 i_dmi_we_i
= self
.dmi_wr
,
174 o_dmi_ack_o
= self
.dmi_ack
,
177 # add wishbone buses to cpu params
178 self
.cpu_params
.update(make_wb_bus("ibus", ibus
))
179 self
.cpu_params
.update(make_wb_bus("dbus", dbus
))
180 self
.cpu_params
.update(make_wb_slave("ics_wb", ics
))
181 self
.cpu_params
.update(make_wb_slave("icp_wb", icp
))
182 if variant
!= "ls180":
183 self
.cpu_params
.update(make_wb_slave("gpio_wb", gpio
))
185 self
.cpu_params
.update(make_wb_bus("jtag_wb", jtag_wb
, simple
=True))
187 # urr yuk. have to expose iopads / pins from core to litex
188 # then back again. cut _some_ of that out by connecting
189 self
.cpuresources
= (make_uart('serial', 0),
190 make_gpio('gpio', 0, 16))
191 self
.padresources
= (make_uart('serial', 0),
192 make_gpio('gpio', 0, 16))
193 self
.cpu_cm
= ConstraintManager(self
.cpuresources
, [])
194 self
.pad_cm
= ConstraintManager(self
.cpuresources
, [])
195 self
.cpupads
= {'serial': self
.cpu_cm
.request('serial', 0),
196 'gpio': self
.cpu_cm
.request('gpio', 0)}
197 self
.iopads
= {'serial': self
.pad_cm
.request('serial', 0),
198 'gpio': self
.pad_cm
.request('gpio', 0)}
202 make_jtag_ioconn(self
.cpu_params
, pin
, self
.cpupads
,
205 # add verilog sources
206 self
.add_sources(platform
)
208 def set_reset_address(self
, reset_address
):
209 assert not hasattr(self
, "reset_address")
210 self
.reset_address
= reset_address
211 assert reset_address
== 0x00000000
214 def add_sources(platform
):
215 cdir
= os
.path
.dirname(__file__
)
216 platform
.add_source(os
.path
.join(cdir
, "libresoc.v"))
218 def do_finalize(self
):
219 self
.specials
+= Instance("test_issuer", **self
.cpu_params
)