HeavyX/examples/simplesoc_ecp5.py

75 lines
2.1 KiB
Python

from nmigen import *
from nmigen.back import rtlil
from heavycomps import uart, wishbone
from minerva.core import Minerva
class SimpleWishboneSerial(Elaboratable):
def __init__(self, tx, sys_clk_freq, baudrate=115200):
self.tx = tx
self.bus = wishbone.Interface()
self.ftw = round(2**32*baudrate/sys_clk_freq)
def elaborate(self, platform):
m = Module()
m.submodules.tx = tx = uart.RS232TX(self.ftw)
m.d.comb += [
tx.stb.eq(self.bus.cyc & self.bus.stb & self.bus.we),
tx.data.eq(self.bus.dat_w),
self.bus.ack.eq(tx.ack),
self.tx.eq(tx.tx)
]
return m
class Top(Elaboratable):
def __init__(self):
self.clk100 = Signal()
self.serial_tx = Signal()
def elaborate(self, platform):
m = Module()
cd_sync = ClockDomain(reset_less=True)
m.domains += cd_sync
m.d.comb += cd_sync.clk.eq(self.clk100)
m.submodules.cpu = cpu = Minerva(with_icache=False, with_dcache=False)
m.submodules.ram = ram = wishbone.SRAM(Memory(32, 1024))
m.submodules.uart = uart = SimpleWishboneSerial(self.serial_tx, 100e6)
m.submodules.con = con = wishbone.InterconnectShared(
[cpu.ibus, cpu.dbus],
[
(lambda a: ~a[20], ram.bus),
(lambda a: a[20], uart.bus)
], register=True)
# work around https://github.com/m-labs/nmigen/issues/30
m.d.comb += [
cpu.external_interrupt.eq(0),
cpu.timer_interrupt.eq(0),
cpu.fetch.ibus.dat_w.eq(0),
cpu.fetch.ibus.sel.eq(0b1111),
cpu.fetch.ibus.we.eq(0),
cpu.fetch.ibus.cti.eq(0),
cpu.fetch.ibus.bte.eq(0),
cpu.loadstore.dbus.cti.eq(0),
cpu.loadstore.dbus.bte.eq(0),
ram.bus.err.eq(0),
uart.bus.err.eq(0),
uart.bus.dat_r.eq(0)
]
return m
def main():
top = Top()
output = rtlil.convert(Fragment.get(top, None),
ports=(top.clk100, top.serial_tx))
print(output)
if __name__ == "__main__":
main()