c4m iopad integration working
[soc.git] / src / soc / litex / florent / libresoc / core.py
1 import os
2
3 from migen import ClockSignal, ResetSignal, Signal, Instance, Cat
4
5 from litex.soc.interconnect import wishbone as wb
6 from litex.soc.cores.cpu import CPU
7
8 from soc.debug.jtag import Pins # TODO move to suitable location
9 from c4m.nmigen.jtag.tap import IOType
10
11 from libresoc.ls180io import make_uart, make_gpio
12 from litex.build.generic_platform import ConstraintManager
13
14
15 CPU_VARIANTS = ["standard", "standard32", "standardjtag", "ls180"]
16
17
18 def make_wb_bus(prefix, obj, simple=False):
19 res = {}
20 outpins = ['stb', 'cyc', 'we', 'adr', 'dat_w', 'sel']
21 if not simple:
22 outpins += ['cti', 'bte']
23 for o in outpins:
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)
27 return res
28
29 def make_wb_slave(prefix, obj):
30 res = {}
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)
35 return res
36
37
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)
44 cpu = cpupads[fn]
45 io = iopads[fn]
46 sigs = []
47
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)
53
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)
59
60 if iotype in (IOType.In, IOType.InTriOut):
61 sigs.append(("i", 1))
62 if iotype in (IOType.Out, IOType.TriOut, IOType.InTriOut):
63 sigs.append(("o", 1))
64 if iotype in (IOType.TriOut, IOType.InTriOut):
65 sigs.append(("oe", 1))
66
67 class LibreSoC(CPU):
68 name = "libre_soc"
69 human_name = "Libre-SoC"
70 variants = CPU_VARIANTS
71 endianness = "little"
72 gcc_triple = ("powerpc64le-linux", "powerpc64le-linux-gnu")
73 linker_output_format = "elf64-powerpcle"
74 nop = "nop"
75 io_regions = {0xc0000000: 0x10000000} # origin, length
76
77 @property
78 def mem_map(self):
79 return {"csr": 0xc0000000}
80
81 @property
82 def gcc_flags(self):
83 flags = "-m64 "
84 flags += "-mabi=elfv2 "
85 flags += "-msoft-float "
86 flags += "-mno-string "
87 flags += "-mno-multiple "
88 flags += "-mno-vsx "
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__ "
95 return flags
96
97 def __init__(self, platform, variant="standard"):
98 self.platform = platform
99 self.variant = variant
100 self.reset = Signal()
101 self.interrupt = Signal(16)
102
103 if variant == "standard32":
104 self.data_width = 32
105 self.dbus = dbus = wb.Interface(data_width=32, adr_width=30)
106 else:
107 self.dbus = dbus = wb.Interface(data_width=64, adr_width=29)
108 self.data_width = 64
109 self.ibus = ibus = wb.Interface(data_width=64, adr_width=29)
110
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)
113
114 jtag_en = ('jtag' in variant) or variant == 'ls180'
115
116 if variant != "ls180":
117 self.simple_gpio = gpio = wb.Interface(data_width=32, adr_width=30)
118 if jtag_en:
119 self.jtag_wb = jtag_wb = wb.Interface(data_width=64, adr_width=29)
120
121 self.periph_buses = [ibus, dbus]
122 self.memory_buses = []
123
124 if jtag_en:
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)
130 else:
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)
137
138 # # #
139
140 self.cpu_params = dict(
141 # Clock / Reset
142 i_clk = ClockSignal(),
143 i_rst = ResetSignal() | self.reset,
144
145 # Monitoring / Debugging
146 i_pc_i = 0,
147 i_pc_i_ok = 0,
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
152
153 # interrupts
154 i_int_level_i = self.interrupt,
155
156 )
157
158 if jtag_en:
159 self.cpu_params.update(dict(
160 # JTAG Debug bus
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,
165 ))
166 else:
167 self.cpu_params.update(dict(
168 # DMI Debug bus
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,
175 ))
176
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))
184 if jtag_en:
185 self.cpu_params.update(make_wb_bus("jtag_wb", jtag_wb, simple=True))
186
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)}
199
200 p = Pins()
201 for pin in list(p):
202 make_jtag_ioconn(self.cpu_params, pin, self.cpupads,
203 self.iopads)
204
205 # add verilog sources
206 self.add_sources(platform)
207
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
212
213 @staticmethod
214 def add_sources(platform):
215 cdir = os.path.dirname(__file__)
216 platform.add_source(os.path.join(cdir, "libresoc.v"))
217
218 def do_finalize(self):
219 self.specials += Instance("test_issuer", **self.cpu_params)
220