Merge branch 'master' of git.libre-soc.org:soc
[soc.git] / src / soc / litex / florent / sim.py
1 #!/usr/bin/env python3
2
3 import os
4 import argparse
5
6 from migen import (Signal, FSM, If, Display, Finish, NextValue, NextState)
7
8 from litex.build.generic_platform import Pins, Subsignal
9 from litex.build.sim import SimPlatform
10 from litex.build.io import CRG
11 from litex.build.sim.config import SimConfig
12
13 from litex.soc.integration.soc import SoCRegion
14 from litex.soc.integration.soc_core import SoCCore
15 from litex.soc.integration.builder import Builder
16
17 from litex.tools.litex_sim import Platform
18
19 from libresoc import LibreSoC
20 from microwatt import Microwatt
21
22 # LibreSoCSim -----------------------------------------------------------------
23
24 class LibreSoCSim(SoCCore):
25 def __init__(self, cpu="libresoc", debug=False):
26 assert cpu in ["libresoc", "microwatt"]
27 platform = Platform()
28 sys_clk_freq = int(1e6)
29
30 # SoCCore -------------------------------------------------------------
31 SoCCore.__init__(self, platform, clk_freq=sys_clk_freq,
32 cpu_type = "microwatt",
33 cpu_cls = LibreSoC if cpu == "libresoc" \
34 else Microwatt,
35 #bus_data_width = 64,
36 uart_name = "sim",
37 integrated_rom_size = 0x10000,
38 integrated_main_ram_size = 0x10000000) # 256MB
39 self.platform.name = "sim"
40
41 # CRG -----------------------------------------------------------------
42 self.submodules.crg = CRG(platform.request("sys_clk"))
43
44 # Debug ---------------------------------------------------------------
45 if not debug:
46 return
47
48 # setup running of DMI FSM
49 dmi_addr = Signal(3)
50 dmi_din = Signal(64)
51 dmi_dout = Signal(64)
52 dmi_wen = Signal(1)
53 dmi_req = Signal(1)
54
55 # debug log out
56 dbg_addr = Signal(3)
57 dbg_dout = Signal(64)
58 dbg_msg = Signal(1)
59
60 uptime = Signal(64)
61 # increment counter, Stop after 100000 cycles
62 uptime = Signal(64)
63 self.sync += uptime.eq(uptime + 1)
64 self.sync += If(uptime == 100000, Finish())
65
66 dmifsm = FSM()
67 self.submodules += dmifsm
68
69 # DMI FSM
70 dmifsm.act("START",
71 If(dmi_req & dmi_wen,
72 (self.cpu.dmi_addr.eq(dmi_addr), # DMI Addr
73 self.cpu.dmi_din.eq(dmi_din), # DMI in
74 self.cpu.dmi_req.eq(1), # DMI request
75 self.cpu.dmi_wr.eq(1), # DMI write
76 If(self.cpu.dmi_ack,
77 (NextState("IDLE"),
78 )
79 ),
80 ),
81 ),
82 If(dmi_req & ~dmi_wen,
83 (self.cpu.dmi_addr.eq(dmi_addr), # DMI Addr
84 self.cpu.dmi_req.eq(1), # DMI request
85 self.cpu.dmi_wr.eq(0), # DMI read
86 If(self.cpu.dmi_ack,
87 (NextState("IDLE"),
88 NextValue(dbg_addr, dmi_addr),
89 NextValue(dbg_dout, self.cpu.dmi_dout),
90 NextValue(dbg_msg, 1),
91 )
92 ),
93 ),
94 )
95 )
96
97 dmifsm.act("IDLE",
98 (NextValue(dmi_req, 0),
99 NextValue(dmi_addr, 0),
100 NextValue(dmi_din, 0),
101 NextValue(dmi_wen, 0),
102 NextState("START"), # back to start on next cycle
103 )
104 )
105
106 # debug messages out
107 self.sync += If(dbg_msg,
108 (If(dbg_addr == 0b10, # PC
109 Display("pc : %016x", dbg_dout),
110 ),
111 If(dbg_addr == 0b11, # PC
112 Display(" msr: %016x", dbg_dout),
113 ),
114 If(dbg_addr == 0b101, # GPR
115 Display(" gpr: %016x", dbg_dout),
116 ),
117 dbg_msg.eq(0)
118 )
119 )
120
121 # kick off a "stop"
122 self.sync += If(uptime == 0,
123 (dmi_addr.eq(0), # CTRL
124 dmi_din.eq(1<<0), # STOP
125 dmi_req.eq(1),
126 dmi_wen.eq(1),
127 )
128 )
129
130 # loop every 1<<N cycles
131 cyclewid = 9
132
133 # get the PC
134 self.sync += If(uptime[0:cyclewid] == 4,
135 (dmi_addr.eq(0b10), # NIA
136 dmi_req.eq(1),
137 dmi_wen.eq(0),
138 )
139 )
140
141 # kick off a "step"
142 self.sync += If(uptime[0:cyclewid] == 8,
143 (dmi_addr.eq(0), # CTRL
144 dmi_din.eq(1<<3), # STEP
145 dmi_req.eq(1),
146 dmi_wen.eq(1),
147 )
148 )
149
150 # get the MSR
151 self.sync += If(uptime[0:cyclewid] == 28,
152 (dmi_addr.eq(0b11), # MSR
153 dmi_req.eq(1),
154 dmi_wen.eq(0),
155 )
156 )
157
158 # read all 32 GPRs
159 for i in range(32):
160 self.sync += If(uptime[0:cyclewid] == 30+(i*8),
161 (dmi_addr.eq(0b100), # GSPR addr
162 dmi_din.eq(i), # r1
163 dmi_req.eq(1),
164 dmi_wen.eq(1),
165 )
166 )
167
168 self.sync += If(uptime[0:cyclewid] == 34+(i*8),
169 (dmi_addr.eq(0b101), # GSPR data
170 dmi_req.eq(1),
171 dmi_wen.eq(0),
172 )
173 )
174
175 # monitor ibus write
176 self.sync += If(self.cpu.ibus.stb & self.cpu.ibus.ack &
177 self.cpu.ibus.we,
178 Display(" [%06x] iadr: %8x, s %01x w %016x",
179 uptime,
180 self.cpu.ibus.adr,
181 self.cpu.ibus.sel,
182 self.cpu.ibus.dat_w,
183 )
184 )
185 # monitor ibus read
186 self.sync += If(self.cpu.ibus.stb & self.cpu.ibus.ack &
187 ~self.cpu.ibus.we,
188 Display(" [%06x] iadr: %8x, s %01x r %016x",
189 uptime,
190 self.cpu.ibus.adr,
191 self.cpu.ibus.sel,
192 self.cpu.ibus.dat_r
193 )
194 )
195
196 # monitor bbus read/write
197 self.sync += If(self.cpu.dbus.stb & self.cpu.dbus.ack,
198 Display(" [%06x] dadr: %8x, we %d s %01x w %016x r: %016x",
199 uptime,
200 self.cpu.dbus.adr,
201 self.cpu.dbus.we,
202 self.cpu.dbus.sel,
203 self.cpu.dbus.dat_w,
204 self.cpu.dbus.dat_r
205 )
206 )
207
208 # Build -----------------------------------------------------------------------
209
210 def main():
211 parser = argparse.ArgumentParser(description="LiteX LibreSoC CPU Sim")
212 parser.add_argument("--cpu", default="libresoc",
213 help="CPU to use: libresoc (default) or microwatt")
214 parser.add_argument("--debug", action="store_true",
215 help="Enable debug traces")
216 parser.add_argument("--trace", action="store_true",
217 help="Enable tracing")
218 parser.add_argument("--trace-start", default=0,
219 help="Cycle to start FST tracing")
220 parser.add_argument("--trace-end", default=-1,
221 help="Cycle to end FST tracing")
222 args = parser.parse_args()
223
224 sim_config = SimConfig(default_clk="sys_clk")
225 sim_config.add_module("serial2console", "serial")
226
227 for i in range(2):
228 soc = LibreSoCSim(cpu=args.cpu, debug=args.debug)
229 builder = Builder(soc,compile_gateware = i!=0)
230 builder.build(sim_config=sim_config,
231 run = i!=0,
232 trace = args.trace,
233 trace_start = int(args.trace_start),
234 trace_end = int(args.trace_end),
235 trace_fst = 0)
236 os.chdir("../")
237
238 if __name__ == "__main__":
239 main()