tools: move from litex.soc.tools to litex.tools and fix usb.core import
[litex.git] / litex / tools / litex_sim.py
1 #!/usr/bin/env python3
2
3 import argparse
4
5 from migen import *
6 from migen.genlib.io import CRG
7
8 from litex.build.generic_platform import *
9 from litex.build.sim import SimPlatform
10 from litex.build.sim.config import SimConfig
11
12 from litex.soc.integration.soc_core import *
13 from litex.soc.integration.soc_sdram import *
14 from litex.soc.integration.builder import *
15 from litex.soc.cores import uart
16 from litex.soc.integration.soc_core import mem_decoder
17
18 from litedram.common import PhySettings
19 from litedram.modules import MT48LC16M16
20 from litedram.phy.model import SDRAMPHYModel
21
22 from liteeth.common import convert_ip
23 from liteeth.phy.model import LiteEthPHYModel
24 from liteeth.core.mac import LiteEthMAC
25 from liteeth.core import LiteEthUDPIPCore
26 from liteeth.frontend.etherbone import LiteEthEtherbone
27
28 from litescope import LiteScopeAnalyzer
29
30
31 class SimPins(Pins):
32 def __init__(self, n=1):
33 Pins.__init__(self, "s "*n)
34
35
36 _io = [
37 ("sys_clk", 0, SimPins(1)),
38 ("sys_rst", 0, SimPins(1)),
39 ("serial", 0,
40 Subsignal("source_valid", SimPins()),
41 Subsignal("source_ready", SimPins()),
42 Subsignal("source_data", SimPins(8)),
43
44 Subsignal("sink_valid", SimPins()),
45 Subsignal("sink_ready", SimPins()),
46 Subsignal("sink_data", SimPins(8)),
47 ),
48 ("eth_clocks", 0,
49 Subsignal("none", SimPins()),
50 ),
51 ("eth", 0,
52 Subsignal("source_valid", SimPins()),
53 Subsignal("source_ready", SimPins()),
54 Subsignal("source_data", SimPins(8)),
55
56 Subsignal("sink_valid", SimPins()),
57 Subsignal("sink_ready", SimPins()),
58 Subsignal("sink_data", SimPins(8)),
59 ),
60 ("eth_clocks", 1,
61 Subsignal("none", SimPins()),
62 ),
63 ("eth", 1,
64 Subsignal("source_valid", SimPins()),
65 Subsignal("source_ready", SimPins()),
66 Subsignal("source_data", SimPins(8)),
67
68 Subsignal("sink_valid", SimPins()),
69 Subsignal("sink_ready", SimPins()),
70 Subsignal("sink_data", SimPins(8)),
71 ),
72 ]
73
74
75 class Platform(SimPlatform):
76 default_clk_name = "sys_clk"
77 default_clk_period = 1000 # ~ 1MHz
78
79 def __init__(self):
80 SimPlatform.__init__(self, "SIM", _io)
81
82 def do_finalize(self, fragment):
83 pass
84
85
86 class SimSoC(SoCSDRAM):
87 csr_peripherals = [
88 "ethphy",
89 "ethmac",
90
91 "etherbonephy",
92 "etherbonecore",
93
94 "analyzer",
95 ]
96 csr_map_update(SoCSDRAM.csr_map, csr_peripherals)
97
98 interrupt_map = {
99 "ethmac": 3,
100 }
101 interrupt_map.update(SoCSDRAM.interrupt_map)
102
103 mem_map = {
104 "ethmac": 0x30000000, # (shadow @0xb0000000)
105 }
106 mem_map.update(SoCSDRAM.mem_map)
107
108 def __init__(self,
109 with_sdram=False,
110 with_ethernet=False,
111 with_etherbone=False, etherbone_mac_address=0x10e2d5000000, etherbone_ip_address="192.168.1.50",
112 with_analyzer=False,
113 **kwargs):
114 platform = Platform()
115 sys_clk_freq = int(1e6)
116 SoCSDRAM.__init__(self, platform, clk_freq=sys_clk_freq,
117 integrated_rom_size=0x8000,
118 ident="LiteX Simulation", ident_version=True,
119 with_uart=False,
120 **kwargs)
121 # crg
122 self.submodules.crg = CRG(platform.request("sys_clk"))
123
124 # serial
125 self.submodules.uart_phy = uart.RS232PHYModel(platform.request("serial"))
126 self.submodules.uart = uart.UART(self.uart_phy)
127
128 # sdram
129 if with_sdram:
130 sdram_module = MT48LC16M16(100e6, "1:1") # use 100MHz timings
131 phy_settings = PhySettings(
132 memtype="SDR",
133 dfi_databits=16,
134 nphases=1,
135 rdphase=0,
136 wrphase=0,
137 rdcmdphase=0,
138 wrcmdphase=0,
139 cl=2,
140 read_latency=4,
141 write_latency=0
142 )
143 self.submodules.sdrphy = SDRAMPHYModel(sdram_module, phy_settings)
144 self.register_sdram(
145 self.sdrphy,
146 sdram_module.geom_settings,
147 sdram_module.timing_settings)
148 # reduce memtest size for simulation speedup
149 self.add_constant("MEMTEST_DATA_SIZE", 8*1024)
150 self.add_constant("MEMTEST_ADDR_SIZE", 8*1024)
151
152 assert not (with_ethernet and with_etherbone) # FIXME: fix simulator with 2 ethernet interfaces
153
154 # ethernet
155 if with_ethernet:
156 # eth phy
157 self.submodules.ethphy = LiteEthPHYModel(self.platform.request("eth", 0))
158 # eth mac
159 ethmac = LiteEthMAC(phy=self.ethphy, dw=32,
160 interface="wishbone", endianness=self.cpu.endianness)
161 if with_etherbone:
162 ethmac = ClockDomainsRenamer({"eth_tx": "ethphy_eth_tx", "eth_rx": "ethphy_eth_rx"})(ethmac)
163 self.submodules.ethmac = ethmac
164 self.add_wb_slave(mem_decoder(self.mem_map["ethmac"]), self.ethmac.bus)
165 self.add_memory_region("ethmac", self.mem_map["ethmac"] | self.shadow_base, 0x2000)
166
167 # etherbone
168 if with_etherbone:
169 # eth phy
170 self.submodules.etherbonephy = LiteEthPHYModel(self.platform.request("eth", 0)) # FIXME
171 # eth core
172 etherbonecore = LiteEthUDPIPCore(self.etherbonephy,
173 etherbone_mac_address, convert_ip(etherbone_ip_address), sys_clk_freq)
174 if with_ethernet:
175 etherbonecore = ClockDomainsRenamer({"eth_tx": "etherbonephy_eth_tx", "eth_rx": "etherbonephy_eth_rx"})(etherbonecore)
176 self.submodules.etherbonecore = etherbonecore
177 # etherbone
178 self.submodules.etherbone = LiteEthEtherbone(self.etherbonecore.udp, 1234, mode="master")
179 self.add_wb_master(self.etherbone.wishbone.bus)
180
181 # analyzer
182 if with_analyzer:
183 analyzer_signals = [
184 # FIXME: find interesting signals to probe
185 self.cpu.ibus,
186 self.cpu.dbus
187 ]
188 self.submodules.analyzer = LiteScopeAnalyzer(analyzer_signals, 512)
189
190
191 def main():
192 parser = argparse.ArgumentParser(description="Generic LiteX SoC Simulation")
193 builder_args(parser)
194 soc_sdram_args(parser)
195 parser.add_argument("--threads", default=1,
196 help="set number of threads (default=1)")
197 parser.add_argument("--rom-init", default=None,
198 help="rom_init file")
199 parser.add_argument("--ram-init", default=None,
200 help="ram_init file")
201 parser.add_argument("--with-sdram", action="store_true",
202 help="enable SDRAM support")
203 parser.add_argument("--with-ethernet", action="store_true",
204 help="enable Ethernet support")
205 parser.add_argument("--with-etherbone", action="store_true",
206 help="enable Etherbone support")
207 parser.add_argument("--with-analyzer", action="store_true",
208 help="enable Analyzer support")
209 parser.add_argument("--trace", action="store_true",
210 help="enable VCD tracing")
211 args = parser.parse_args()
212
213 soc_kwargs = soc_sdram_argdict(args)
214 builder_kwargs = builder_argdict(args)
215
216 sim_config = SimConfig(default_clk="sys_clk")
217 sim_config.add_module("serial2console", "serial")
218
219 cpu_endianness = "big"
220 if "cpu_type" in soc_kwargs:
221 if soc_kwargs["cpu_type"] in ["picorv32", "vexriscv"]:
222 cpu_endianness = "little"
223
224 if args.rom_init:
225 soc_kwargs["integrated_rom_init"] = get_mem_data(args.rom_init, cpu_endianness)
226 if not args.with_sdram:
227 soc_kwargs["integrated_main_ram_size"] = 0x10000000 # 256 MB
228 if args.ram_init is not None:
229 soc_kwargs["integrated_main_ram_init"] = get_mem_data(args.ram_init, cpu_endianness)
230 else:
231 assert args.ram_init is None
232 soc_kwargs["integrated_main_ram_size"] = 0x0
233 if args.with_ethernet:
234 sim_config.add_module("ethernet", "eth", args={"interface": "tap0", "ip": "192.168.1.100"})
235 if args.with_etherbone:
236 sim_config.add_module('ethernet', "eth", args={"interface": "tap1", "ip": "192.168.1.101"})
237
238 soc = SimSoC(
239 with_sdram=args.with_sdram,
240 with_ethernet=args.with_ethernet,
241 with_etherbone=args.with_etherbone,
242 with_analyzer=args.with_analyzer,
243 **soc_kwargs)
244 if args.ram_init is not None:
245 soc.add_constant("ROM_BOOT_ADDRESS", 0x40000000)
246 builder_kwargs["csr_csv"] = "csr.csv"
247 builder = Builder(soc, **builder_kwargs)
248 vns = builder.build(run=False, threads=args.threads, sim_config=sim_config, trace=args.trace)
249 if args.with_analyzer:
250 soc.analyzer.export_csv(vns, "analyzer.csv")
251 builder.build(build=False, threads=args.threads, sim_config=sim_config, trace=args.trace)
252
253
254 if __name__ == "__main__":
255 main()