get litex sim to kick off a "STEP" via the DMI interface every N cycles
[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 uart_name = "sim",
36 integrated_rom_size = 0x10000,
37 integrated_main_ram_size = 0x10000000) # 256MB
38 self.platform.name = "sim"
39
40 # CRG -----------------------------------------------------------------
41 self.submodules.crg = CRG(platform.request("sys_clk"))
42
43 # Debug ---------------------------------------------------------------
44 if not debug:
45 return
46
47 # setup running of DMI FSM
48 dmi_addr = Signal(3)
49 dmi_din = Signal(64)
50 dmi_dout = Signal(64)
51 dmi_wen = Signal(1)
52 dmi_req = Signal(1)
53
54 uptime = Signal(64)
55 # increment counter, Stop after 100000 cycles
56 uptime = Signal(64)
57 self.sync += uptime.eq(uptime + 1)
58 self.sync += If(uptime == 100000, Finish())
59
60 dmifsm = FSM()
61 self.submodules += dmifsm
62
63 # DMI FSM
64 dmifsm.act("START",
65 If(dmi_req & dmi_wen,
66 (self.cpu.dmi_addr.eq(dmi_addr), # DMI Addr
67 self.cpu.dmi_din.eq(dmi_din), # DMI in
68 self.cpu.dmi_req.eq(1), # DMI request
69 self.cpu.dmi_wr.eq(1), # DMI write
70 If(self.cpu.dmi_ack,
71 (NextState("IDLE"),
72 )
73 ),
74 ),
75 )
76 )
77
78 dmifsm.act("IDLE",
79 (NextValue(dmi_req, 0),
80 NextValue(dmi_addr, 0),
81 NextValue(dmi_din, 0),
82 NextValue(dmi_wen, 0),
83 NextState("START"), # back to start on next cycle
84 )
85 )
86
87 # kick off a "stop"
88 self.sync += If(uptime == 0,
89 (dmi_addr.eq(0), # CTRL
90 dmi_din.eq(1<<0), # STOP
91 dmi_req.eq(1),
92 dmi_wen.eq(1),
93 )
94 )
95
96 # loop every 1<<N cycles
97 cyclewid = 7
98
99 # kick off a "step"
100 self.sync += If(uptime[0:cyclewid] == 4,
101 (dmi_addr.eq(0), # CTRL
102 dmi_din.eq(1<<3), # STEP
103 dmi_req.eq(1),
104 dmi_wen.eq(1),
105 )
106 )
107
108 # monitor ibus write
109 self.sync += If(self.cpu.ibus.stb & self.cpu.ibus.ack &
110 self.cpu.ibus.we,
111 Display("[%06x] iadr: %8x, s %01x w %016x",
112 uptime,
113 self.cpu.ibus.adr,
114 self.cpu.ibus.sel,
115 self.cpu.ibus.dat_w,
116 )
117 )
118 # monitor ibus read
119 self.sync += If(self.cpu.ibus.stb & self.cpu.ibus.ack &
120 ~self.cpu.ibus.we,
121 Display("[%06x] iadr: %8x, s %01x r %016x",
122 uptime,
123 self.cpu.ibus.adr,
124 self.cpu.ibus.sel,
125 self.cpu.ibus.dat_r
126 )
127 )
128
129 # monitor bbus read/write
130 self.sync += If(self.cpu.dbus.stb & self.cpu.dbus.ack,
131 Display("[%06x] dadr: %8x, we %d s %01x w %016x r: %016x",
132 uptime,
133 self.cpu.dbus.adr,
134 self.cpu.dbus.we,
135 self.cpu.dbus.sel,
136 self.cpu.dbus.dat_w,
137 self.cpu.dbus.dat_r
138 )
139 )
140
141 # Build -----------------------------------------------------------------------
142
143 def main():
144 parser = argparse.ArgumentParser(description="LiteX LibreSoC CPU Sim")
145 parser.add_argument("--cpu", default="libresoc",
146 help="CPU to use: libresoc (default) or microwatt")
147 parser.add_argument("--debug", action="store_true",
148 help="Enable debug traces")
149 parser.add_argument("--trace", action="store_true",
150 help="Enable tracing")
151 parser.add_argument("--trace-start", default=0,
152 help="Cycle to start FST tracing")
153 parser.add_argument("--trace-end", default=-1,
154 help="Cycle to end FST tracing")
155 args = parser.parse_args()
156
157 sim_config = SimConfig(default_clk="sys_clk")
158 sim_config.add_module("serial2console", "serial")
159
160 for i in range(2):
161 soc = LibreSoCSim(cpu=args.cpu, debug=args.debug)
162 builder = Builder(soc,compile_gateware = i!=0)
163 builder.build(sim_config=sim_config,
164 run = i!=0,
165 trace = args.trace,
166 trace_start = int(args.trace_start),
167 trace_end = int(args.trace_end),
168 trace_fst = 0)
169 os.chdir("../")
170
171 if __name__ == "__main__":
172 main()