98 lines
3.4 KiB
Python
98 lines
3.4 KiB
Python
import argparse
|
|
import struct
|
|
|
|
from nmigen import *
|
|
from nmigen_boards.versa_ecp5 import VersaECP5Platform_USRMCLK
|
|
|
|
from heavycomps.cores import *
|
|
from heavycomps.cfgs.ecp5 import *
|
|
|
|
from minerva.core import Minerva
|
|
from nmigen_soc import wishbone
|
|
|
|
from nmigen.utils import *
|
|
|
|
|
|
class Top(Elaboratable):
|
|
def __init__(self, firmware):
|
|
self.firmware = firmware
|
|
|
|
def elaborate(self, platform):
|
|
m = Module()
|
|
|
|
# Referring to simplesoc_ecp5.py
|
|
cd_sync = ClockDomain()
|
|
m.domains += cd_sync
|
|
m.d.comb += cd_sync.clk.eq(platform.request("clk100").i)
|
|
|
|
io_user_led = [platform.request("led", i).o for i in range(8)]
|
|
io_uart = platform.request("uart")
|
|
io_spiflash = platform.request("spi_flash_1x")
|
|
io_eth = platform.request("eth_rgmii", number=0)
|
|
|
|
# FIXME: Without an sync stmt, clk100 must be checked...
|
|
dummy = Signal()
|
|
m.d.sync += dummy.eq(0)
|
|
|
|
m.submodules.cpu = cpu = Minerva(with_icache=False, with_dcache=False, with_muldiv=False)
|
|
m.submodules.ram = ram = wishbone.SRAM(Memory(width=32, depth=2**15, init=self.firmware),
|
|
granularity=8, features={"err","cti","bte"})
|
|
|
|
m.submodules.timer = timer = TimerCore(width=32,
|
|
bus_data_width=32, bus_granularity=8)
|
|
m.submodules.led = led = GPIOOutput(io_user_led, count=8,
|
|
bus_data_width=32, bus_granularity=8, invert=True)
|
|
m.submodules.uart = uart = UARTCore(io_uart, sys_clk_freq=100e6,
|
|
bus_data_width=32, bus_granularity=8)
|
|
m.submodules.spi = spi = SPIFlashCore(io_spiflash, spi_protocol="standard", read_type="slow",
|
|
addr_width=24, sys_clk_freq=100e6, freq=10e6,
|
|
data_width=32, granularity=8)
|
|
m.submodules += SPIFlashCoreCfg(spi)
|
|
m.submodules.eth = eth = EthRGMIICore(rx=True, tx=False,
|
|
bus_data_width=32, bus_granularity=8)
|
|
m.submodules += EthRGMIICoreCfg(eth, io_eth, rx=True, tx=False)
|
|
|
|
m.submodules.con = con = wishbone.InterconnectShared(
|
|
addr_width=30, data_width=32, granularity=8,
|
|
features={"err","cti","bte"},
|
|
itors=[cpu.ibus, cpu.dbus],
|
|
targets=[
|
|
( ram.bus, 0x00000000 ),
|
|
( uart.csr_bus, 0x02000000 ),
|
|
( timer.csr_bus, 0x02000020 ),
|
|
( led.csr_bus, 0x02000010 ),
|
|
( spi.bus, 0x03000000 ),
|
|
( spi.csr_bus, 0x02000100 ),
|
|
( eth.csr_bus, 0x02000200 ),
|
|
( eth.rxdat_bus, 0x02000204 )
|
|
]
|
|
)
|
|
|
|
return m
|
|
|
|
|
|
def read_firmware(file):
|
|
firmware = []
|
|
with open(file, "rb") as f:
|
|
while True:
|
|
word = f.read(4)
|
|
if len(word) < 4:
|
|
break
|
|
firmware.append(struct.unpack("<I", word)[0])
|
|
return firmware
|
|
|
|
|
|
def main():
|
|
parser = argparse.ArgumentParser()
|
|
parser.add_argument("firmware_bin")
|
|
parser.add_argument("build_dir")
|
|
args = parser.parse_args()
|
|
|
|
firmware = read_firmware(args.firmware_bin)
|
|
top = Top(firmware)
|
|
|
|
VersaECP5Platform_USRMCLK().build(top, build_dir=args.build_dir)
|
|
|
|
if __name__ == "__main__":
|
|
main()
|