Created
February 12, 2024 14:22
-
-
Save antoinevg/f450610023b4d0d75974dc718713b199 to your computer and use it in GitHub Desktop.
Using Amaranth RFC #16 Registers
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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