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