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
=128, icache_nwords
=4, icache_nways
=1,
36 icache_base
=sdram_addr
, icache_limit
=sdram_addr
+ sdram_core
.size
,
37 with_dcache
=True, dcache_nlines
=128, 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 args
= parser
.parse_args()
112 if args
.platform
== "arty_a7":
113 from nmigen_boards
.arty_a7
import ArtyA7_35Platform
114 platform
= ArtyA7_35Platform()
115 litedram_cfg
= litedram
.Artix7Config(
119 module_name
= "MT41K128M16",
125 input_clk_freq
= int(100e6
),
126 user_clk_freq
= int(100e6
),
127 iodelay_clk_freq
= int(200e6
),
129 elif args
.platform
== "ecpix5_85":
130 from nmigen_boards
.ecpix5
import ECPIX585Platform
131 platform
= ECPIX585Platform()
132 litedram_cfg
= litedram
.ECP5Config(
134 module_name
= "MT41K256M16",
137 input_clk_freq
= int(100e6
),
138 user_clk_freq
= int(70e6
),
139 init_clk_freq
= int(25e6
),
144 litedram_pins
= litedram_cfg
.request_pins(platform
, "ddr3", 0)
145 litedram_core
= litedram
.Core(litedram_cfg
, pins
=litedram_pins
)
147 litedram_builder
= litedram
.Builder()
148 litedram_products
= litedram_core
.build(litedram_builder
, do_build
=True)
150 litedram_core_v
= f
"{litedram_core.name}/{litedram_core.name}.v"
151 platform
.add_file(litedram_core_v
, litedram_products
.get(litedram_core_v
, mode
="t"))
154 reset_addr
=0x30000000, clk_freq
=litedram_cfg
.user_clk_freq
,
155 uart_addr
=0x00005000, uart_divisor
=int(litedram_cfg
.user_clk_freq
// args
.baudrate
),
156 uart_pins
=platform
.request("uart", 0),
157 timer_addr
=0x00006000, timer_width
=32,
159 rom_addr
=0x30000000, rom_size
=0x8000,
160 ram_addr
=0x30008000, ram_size
=0x1000,
161 sdram_addr
=0x40000000, sdram_core
=litedram_core
, sdram_cache_size
=8192,
163 soc
.build(do_build
=True, do_init
=True)
165 platform
.build(soc
, do_program
=True)