examples/{sram,sdram}_soc: add --build-dir parameter.
[lambdasoc.git] / examples / sram_soc.py
1 import argparse
2 import importlib
3
4 from nmigen import *
5 from nmigen_soc import wishbone
6
7 from lambdasoc.cpu.minerva import MinervaCPU
8 from lambdasoc.periph.intc import GenericInterruptController
9 from lambdasoc.periph.serial import AsyncSerialPeripheral
10 from lambdasoc.periph.sram import SRAMPeripheral
11 from lambdasoc.periph.timer import TimerPeripheral
12 from lambdasoc.soc.cpu import CPUSoC
13
14
15 __all__ = ["SRAMSoC"]
16
17
18 class SRAMSoC(CPUSoC, Elaboratable):
19 def __init__(self, *, reset_addr, clk_freq,
20 rom_addr, rom_size,
21 ram_addr, ram_size,
22 uart_addr, uart_divisor, uart_pins,
23 timer_addr, timer_width):
24 self._arbiter = wishbone.Arbiter(addr_width=30, data_width=32, granularity=8,
25 features={"cti", "bte"})
26 self._decoder = wishbone.Decoder(addr_width=30, data_width=32, granularity=8,
27 features={"cti", "bte"})
28
29 self.cpu = MinervaCPU(reset_address=reset_addr)
30 self._arbiter.add(self.cpu.ibus)
31 self._arbiter.add(self.cpu.dbus)
32
33 self.rom = SRAMPeripheral(size=rom_size, writable=False)
34 self._decoder.add(self.rom.bus, addr=rom_addr)
35
36 self.ram = SRAMPeripheral(size=ram_size)
37 self._decoder.add(self.ram.bus, addr=ram_addr)
38
39 self.uart = AsyncSerialPeripheral(divisor=uart_divisor, pins=uart_pins)
40 self._decoder.add(self.uart.bus, addr=uart_addr)
41
42 self.timer = TimerPeripheral(width=timer_width)
43 self._decoder.add(self.timer.bus, addr=timer_addr)
44
45 self.intc = GenericInterruptController(width=len(self.cpu.ip))
46 self.intc.add_irq(self.timer.irq, 0)
47 self.intc.add_irq(self.uart .irq, 1)
48
49 self.memory_map = self._decoder.bus.memory_map
50
51 self.clk_freq = clk_freq
52
53 def elaborate(self, platform):
54 m = Module()
55
56 m.submodules.arbiter = self._arbiter
57 m.submodules.cpu = self.cpu
58
59 m.submodules.decoder = self._decoder
60 m.submodules.rom = self.rom
61 m.submodules.ram = self.ram
62 m.submodules.uart = self.uart
63 m.submodules.timer = self.timer
64 m.submodules.intc = self.intc
65
66 m.d.comb += [
67 self._arbiter.bus.connect(self._decoder.bus),
68 self.cpu.ip.eq(self.intc.ip),
69 ]
70
71 return m
72
73
74 if __name__ == "__main__":
75 parser = argparse.ArgumentParser()
76 parser.add_argument("platform", type=str,
77 help="target platform (e.g. 'nmigen_boards.arty_a7.ArtyA7Platform')")
78 parser.add_argument("--baudrate", type=int,
79 default=9600,
80 help="UART baudrate (default: 9600)")
81 parser.add_argument("--build-dir", type=str,
82 default="build",
83 help="local build directory (default: 'build')")
84 args = parser.parse_args()
85
86 def get_platform(platform_name):
87 module_name, class_name = platform_name.rsplit(".", 1)
88 module = importlib.import_module(name=module_name)
89 platform_class = getattr(module, class_name)
90 return platform_class()
91
92 platform = get_platform(args.platform)
93
94 uart_divisor = int(platform.default_clk_frequency // args.baudrate)
95 uart_pins = platform.request("uart", 0)
96
97 soc = SRAMSoC(
98 reset_addr=0x00000000, clk_freq=int(platform.default_clk_frequency),
99 rom_addr=0x00000000, rom_size=0x4000,
100 ram_addr=0x00004000, ram_size=0x1000,
101 uart_addr=0x00005000, uart_divisor=uart_divisor, uart_pins=uart_pins,
102 timer_addr=0x00006000, timer_width=32,
103 )
104
105 soc.build(build_dir=f"{args.build_dir}/soc", do_init=True)
106
107 platform.build(soc, build_dir=args.build_dir, do_program=True)