4 from nmigen
.build
import *
5 from nmigen_soc
import wishbone
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
.periph
.sdram
import SDRAMPeripheral
13 from lambdasoc
.soc
.cpu
import CPUSoC
15 from lambdasoc
.cores
import litedram
18 __all__
= ["SDRAMSoC"]
21 class SDRAMSoC(CPUSoC
, Elaboratable
):
22 def __init__(self
, *, reset_addr
, clk_freq
,
25 uart_addr
, uart_divisor
, uart_pins
,
26 timer_addr
, timer_width
,
27 sdram_addr
, sdram_core
, sdram_cache_size
):
28 self
._arbiter
= wishbone
.Arbiter(addr_width
=30, data_width
=32, granularity
=8,
29 features
={"cti", "bte"})
30 self
._decoder
= wishbone
.Decoder(addr_width
=30, data_width
=32, granularity
=8,
31 features
={"cti", "bte"})
33 self
.cpu
= MinervaCPU(
34 reset_address
=reset_addr
,
35 with_icache
=True, icache_nlines
=64, icache_nwords
=4, icache_nways
=1,
36 icache_base
=sdram_addr
, icache_limit
=sdram_addr
+ sdram_core
.size
,
37 with_dcache
=True, dcache_nlines
=64, dcache_nwords
=4, dcache_nways
=1,
38 dcache_base
=sdram_addr
, dcache_limit
=sdram_addr
+ sdram_core
.size
,
41 self
._arbiter
.add(self
.cpu
.ibus
)
42 self
._arbiter
.add(self
.cpu
.dbus
)
44 self
.rom
= SRAMPeripheral(size
=rom_size
, writable
=False)
45 self
._decoder
.add(self
.rom
.bus
, addr
=rom_addr
)
47 self
.ram
= SRAMPeripheral(size
=ram_size
)
48 self
._decoder
.add(self
.ram
.bus
, addr
=ram_addr
)
50 self
.sdram
= SDRAMPeripheral(core
=sdram_core
, cache_size
=sdram_cache_size
)
51 self
._decoder
.add(self
.sdram
.bus
, addr
=sdram_addr
)
53 self
.uart
= AsyncSerialPeripheral(divisor
=uart_divisor
, pins
=uart_pins
)
54 self
._decoder
.add(self
.uart
.bus
, addr
=uart_addr
)
56 self
.timer
= TimerPeripheral(width
=timer_width
)
57 self
._decoder
.add(self
.timer
.bus
, addr
=timer_addr
)
59 self
.intc
= GenericInterruptController(width
=len(self
.cpu
.ip
))
60 self
.intc
.add_irq(self
.timer
.irq
, 0)
61 self
.intc
.add_irq(self
.uart
.irq
, 1)
63 self
.memory_map
= self
._decoder
.bus
.memory_map
65 self
.clk_freq
= clk_freq
67 def elaborate(self
, platform
):
71 ClockDomain("litedram_input"),
72 ClockDomain("litedram_user"),
77 ClockSignal("litedram_input").eq(platform
.request("clk100", 0).i
),
79 ClockSignal("sync").eq(ClockSignal("litedram_user")),
80 ResetSignal("sync").eq(ResetSignal("litedram_user")),
83 m
.submodules
.arbiter
= self
._arbiter
84 m
.submodules
.cpu
= self
.cpu
86 m
.submodules
.decoder
= self
._decoder
87 m
.submodules
.rom
= self
.rom
88 m
.submodules
.ram
= self
.ram
89 m
.submodules
.sdram
= self
.sdram
90 m
.submodules
.uart
= self
.uart
91 m
.submodules
.timer
= self
.timer
92 m
.submodules
.intc
= self
.intc
95 self
._arbiter
.bus
.connect(self
._decoder
.bus
),
96 self
.cpu
.ip
.eq(self
.intc
.ip
),
102 if __name__
== "__main__":
103 parser
= argparse
.ArgumentParser()
104 parser
.add_argument("--platform", type=str,
105 choices
=("arty_a7", "ecpix5_85"),
106 help="target platform")
107 parser
.add_argument("--baudrate", type=int,
109 help="UART baudrate (default: 9600)")
110 parser
.add_argument("--build-dir", type=str,
112 help="local build directory (default: 'build')")
113 args
= parser
.parse_args()
115 if args
.platform
== "arty_a7":
116 from nmigen_boards
.arty_a7
import ArtyA7_35Platform
117 platform
= ArtyA7_35Platform()
118 litedram_cfg
= litedram
.Artix7Config(
122 module_name
= "MT41K128M16",
128 input_clk_freq
= int(100e6
),
129 user_clk_freq
= int(100e6
),
130 iodelay_clk_freq
= int(200e6
),
132 elif args
.platform
== "ecpix5_85":
133 from nmigen_boards
.ecpix5
import ECPIX585Platform
134 platform
= ECPIX585Platform()
135 litedram_cfg
= litedram
.ECP5Config(
137 module_name
= "MT41K256M16",
140 input_clk_freq
= int(100e6
),
141 user_clk_freq
= int(70e6
),
142 init_clk_freq
= int(25e6
),
147 litedram_pins
= litedram_cfg
.request_pins(platform
, "ddr3", 0)
148 litedram_core
= litedram
.Core(litedram_cfg
, pins
=litedram_pins
)
150 litedram_builder
= litedram
.Builder()
151 litedram_build_dir
= f
"{args.build_dir}/litedram"
152 litedram_products
= litedram_core
.build(litedram_builder
, build_dir
=litedram_build_dir
)
154 litedram_core_v
= f
"{litedram_core.name}/{litedram_core.name}.v"
155 platform
.add_file(litedram_core_v
, litedram_products
.get(litedram_core_v
, mode
="t"))
158 reset_addr
=0x30000000, clk_freq
=litedram_cfg
.user_clk_freq
,
159 uart_addr
=0x00005000, uart_divisor
=int(litedram_cfg
.user_clk_freq
// args
.baudrate
),
160 uart_pins
=platform
.request("uart", 0),
161 timer_addr
=0x00006000, timer_width
=32,
163 rom_addr
=0x30000000, rom_size
=0x8000,
164 ram_addr
=0x30008000, ram_size
=0x1000,
165 sdram_addr
=0x40000000, sdram_core
=litedram_core
, sdram_cache_size
=8192,
168 soc
.build(build_dir
=f
"{args.build_dir}/soc", litedram_dir
=litedram_build_dir
, do_init
=True)
170 platform
.build(soc
, build_dir
=args
.build_dir
, do_program
=True)