Skip to content

Instantly share code, notes, and snippets.

@antoinevg
Created February 12, 2024 14:22
Show Gist options
  • Save antoinevg/f450610023b4d0d75974dc718713b199 to your computer and use it in GitHub Desktop.
Save antoinevg/f450610023b4d0d75974dc718713b199 to your computer and use it in GitHub Desktop.
Using Amaranth RFC #16 Registers
import sys
from amaranth import *
from amaranth.build import Attrs, Pins, Platform, Resource, Subsignal
from amaranth.utils import bits_for
from amaranth.lib.wiring import Component, In, Out, connect
from amaranth_soc import csr, wishbone
from amaranth_soc.csr.wishbone import WishboneCSRBridge
from amaranth_soc.memory import MemoryMap
from luna import top_level_cli
from luna.gateware.platform import NullPin
from luna.gateware.architecture.car import LunaECP5DomainGenerator
from tutorials.gateware.usb_bridge import UsbBridge
# - component: SimpleRegister ----------------------------------------------------
class LedRegister(csr.reg.Register, access="rw"):
def __init__(self, reset=0):
super().__init__({
"led0": csr.Field(csr.action.RW, 1, reset=reset),
"led1": csr.Field(csr.action.RW, 1, reset=reset),
"led2": csr.Field(csr.action.RW, 1, reset=reset),
"led3": csr.Field(csr.action.RW, 1, reset=reset),
"led4": csr.Field(csr.action.RW, 1, reset=reset),
"led5": csr.Field(csr.action.RW, 1, reset=reset),
})
# - component: WishbonePeripheral ---------------------------------------------
class WishbonePeripheral(Component):
def __init__(self, *, pads=None):
self.pads = pads
super().__init__({
"bus": In(wishbone.Signature(addr_width=4, data_width=8))
})
# registers
registers = csr.Builder(addr_width=4, data_width=8, name="bob")
self.reg_leds = registers.add("leds", LedRegister(reset=1))
# csr bridge
self.csr_bridge = csr.Bridge(registers.as_memory_map())
self.bus.memory_map = self.csr_bridge.bus.memory_map
# add wishbone bridge
self.wb_bridge = WishboneCSRBridge(self.csr_bridge.bus)
def elaborate(self, platform):
m = Module()
m.submodules += [self.csr_bridge, self.wb_bridge]
# state
state = Signal(8, reset=0x33)
m.d.comb += [
self.pads.eq(state)
]
# connect registers to state
combined = Cat([field.data for name, field in self.reg_leds.fields.flatten()])
m.d.comb += [
state[0:3].eq(combined[0:3]),
state[3].eq(self.reg_leds.f.led3.data),
state[4].eq(self.reg_leds.f.led4.data),
state[5].eq(self.reg_leds.f.led5.data),
]
return m
# - module: Top ---------------------------------------------------------------
class Top(Elaboratable):
def __init__(self):
pass
def elaborate(self, platform):
m = Module()
# domain clocks/resets
clocking = LunaECP5DomainGenerator()
m.submodules += clocking
# resources
leds = Cat(platform.request_optional("led", i, default=NullPin()).o for i in range(0, 8))
# usb bridge
usb_bridge = UsbBridge()
m.submodules += usb_bridge
# wishbone componet
wishbone_component = DomainRenamer("usb")(WishbonePeripheral(pads=leds))
m.submodules += wishbone_component
# wishbone bus decoder
decoder = wishbone.Decoder(addr_width=8, data_width=16)
decoder.add(wishbone_component.wb_bridge.wb_bus, addr=0x10, sparse=True)
m.submodules += decoder
# connect our usb bridge device's vendor request handler to the wishbone decoder
connect(m, usb_bridge.vendor_request_handler.bus, decoder.bus)
return m
if __name__ == "__main__":
top_level_cli(Top)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment