add yosys-nowidelut command-option
[libresoc-litex.git] / versa_ecp5.py
1 #!/usr/bin/env python3
2
3 import os
4 import argparse
5 import sys
6
7 import litex_boards.targets.versa_ecp5 as versa_ecp5
8 import litex_boards.targets.ulx3s as ulx3s
9 from litex.build.lattice.trellis import trellis_args, trellis_argdict
10
11 from litex.soc.integration.soc_sdram import (soc_sdram_args,
12 soc_sdram_argdict)
13 from litex.soc.integration.builder import (Builder, builder_args,
14 builder_argdict)
15
16 from libresoc import LibreSoC
17 #from microwatt import Microwatt
18
19 # HACK!
20 from litex.soc.integration.soc import SoCCSRHandler
21 SoCCSRHandler.supported_address_width.append(12)
22
23
24 # TestSoC
25 # ----------------------------------------------------------------------------
26
27 from litex.build.generic_platform import Subsignal, Pins, IOStandard
28
29 class VersaECP5TestSoC(versa_ecp5.BaseSoC):
30 def __init__(self, sys_clk_freq=int(16e6), **kwargs):
31 kwargs["integrated_rom_size"] = 0x10000
32 #kwargs["integrated_main_ram_size"] = 0x1000
33 kwargs["csr_data_width"] = 32
34 kwargs['csr_address_width'] = 15 # limit to 0x8000
35 kwargs["l2_size"] = 0
36 #bus_data_width = 16,
37
38 versa_ecp5.BaseSoC.__init__(self,
39 sys_clk_freq = sys_clk_freq,
40 cpu_type = "external",
41 cpu_cls = LibreSoC,
42 cpu_variant = "standardjtagnoirq",
43 #cpu_cls = Microwatt,
44 device = "LFE5UM",
45 **kwargs)
46
47 # (thanks to daveshah for this tip)
48 # use platform.add_extension to first define the pins
49 # https://github.com/daveshah1/linux-on-litex-vexriscv/commit/dc97bac3aeb04cfbf5116a6c7e324ce849391770#diff-2353956cb1116676bd6b96769c8ebf7b4b86c16c47511eb2888d0dd2a979e09eR117-R134
50
51 # define the pins, add as an extension, *then* request it
52 jtag_ios = [
53 ("jtag", 0,
54 Subsignal("tdi", Pins("B19"), IOStandard("LVCMOS33")),
55 Subsignal("tms", Pins("B12"), IOStandard("LVCMOS33")),
56 Subsignal("tck", Pins("B9"), IOStandard("LVCMOS33")),
57 Subsignal("tdo", Pins("E6"), IOStandard("LVCMOS33")),
58 )
59 ]
60 self.platform.add_extension(jtag_ios)
61 jtag = self.platform.request("jtag")
62
63 # wire the pins up to CPU JTAG
64 self.comb += self.cpu.jtag_tck.eq(jtag.tck)
65 self.comb += self.cpu.jtag_tms.eq(jtag.tms)
66 self.comb += self.cpu.jtag_tdi.eq(jtag.tdi)
67 self.comb += jtag.tdo.eq(self.cpu.jtag_tdo)
68
69
70 #self.add_constant("MEMTEST_BUS_SIZE", 256//16)
71 #self.add_constant("MEMTEST_DATA_SIZE", 256//16)
72 #self.add_constant("MEMTEST_ADDR_SIZE", 256//16)
73
74 #self.add_constant("MEMTEST_BUS_DEBUG", 1)
75 #self.add_constant("MEMTEST_ADDR_DEBUG", 1)
76 #self.add_constant("MEMTEST_DATA_DEBUG", 1)
77
78
79 class ULX3S85FTestSoC(ulx3s.BaseSoC):
80 def __init__(self, sys_clk_freq=int(16e6), **kwargs):
81 kwargs["integrated_rom_size"] = 0x10000
82 #kwargs["integrated_main_ram_size"] = 0x1000
83 kwargs["csr_data_width"] = 32
84 kwargs["l2_size"] = 0
85 #bus_data_width = 16,
86
87 ulx3s.BaseSoC.__init__(self,
88 sys_clk_freq = sys_clk_freq,
89 cpu_type = "external",
90 cpu_cls = LibreSoC,
91 cpu_variant = "standardjtag",
92 #cpu_cls = Microwatt,
93 device = "LFE5U-85F",
94 **kwargs)
95
96 # get 4 arbitrarily assinged logical pins, each gpio has
97 # 2 distinct physical single non-differential pins p and n
98 gpio0 = self.platform.request("gpio", 0)
99 gpio1 = self.platform.request("gpio", 1)
100
101 # assign p, n litex 'subsignals' of each gpio to jtag pins
102 jtag_tdi = gpio0.n
103 jtag_tms = gpio0.p
104 jtag_tck = gpio1.n
105 jtag_tdo = gpio1.p
106
107 # wire the pins up to CPU JTAG
108 self.comb += self.cpu.jtag_tdi.eq(jtag_tdi)
109 self.comb += self.cpu.jtag_tms.eq(jtag_tms)
110 self.comb += self.cpu.jtag_tdi.eq(jtag_tdi)
111 self.comb += jtag_tdo.eq(self.cpu.jtag_tdo)
112
113 # Build
114 # ----------------------------------------------------------------------------
115
116 def main():
117 parser = argparse.ArgumentParser(description="LiteX SoC with LibreSoC " \
118 "CPU on Versa ECP5 or ULX3S LFE5U85F")
119 parser.add_argument("--build", action="store_true", help="Build bitstream")
120 parser.add_argument("--load", action="store_true", help="Load bitstream")
121 parser.add_argument("--sys-clk-freq", default=int(16e6),
122 help="System clock frequency (default=16MHz)")
123 parser.add_argument("--fpga", default="versa_ecp5", help="FPGA target " \
124 "to build for/load to")
125 parser.add_argument("--load-from", default=None, help="svf to load, disables build")
126 parser.add_argument("--toolchain", default="trellis", help="Gateware toolchain to use, trellis (default) or diamond")
127
128 builder_args(parser)
129 trellis_args(parser)
130 soc_sdram_args(parser)
131 args = parser.parse_args()
132
133 if args.fpga == "versa_ecp5":
134 soc = VersaECP5TestSoC(sys_clk_freq=int(float(args.sys_clk_freq)),
135 **soc_sdram_argdict(args))
136
137 elif args.fpga == "ulx3s85f":
138 soc = ULX3S85FTestSoC(sys_clk_freq=int(float(args.sys_clk_freq)),
139 **soc_sdram_argdict(args))
140
141 else:
142 soc = VersaECP5TestSoC(sys_clk_freq=int(float(args.sys_clk_freq)),
143 **soc_sdram_argdict(args))
144
145 if args.load_from == None:
146 builder = Builder(soc, **builder_argdict(args))
147 builder_kargs = trellis_argdict(args) \
148 if args.toolchain == "trellis" else {}
149 builder.build(run=args.build)
150
151 if args.load:
152 prog = soc.platform.create_programmer()
153 prog.load_bitstream(os.path.join(builder.gateware_dir,
154 soc.build_name + ".svf"))
155 else:
156 if args.load or args.build:
157 print("--load-from is incompatible with --load and --build", file=sys.stderr)
158 sys.exit(1)
159 prog = soc.platform.create_programmer()
160 prog.load_bitstream(args.load_from)
161
162 if __name__ == "__main__":
163 main()