|
| 1 | +import os |
| 2 | + |
| 3 | +from chipflow_lib.platforms.sim import SimPlatform |
| 4 | + |
| 5 | +from amaranth import Module, Instance, ClockSignal, ResetSignal |
| 6 | +from amaranth.lib import wiring |
| 7 | +from amaranth.lib.wiring import In, Out, flipped, connect |
| 8 | + |
| 9 | +from chipflow_lib.platforms import InputIOSignature, OutputIOSignature, BidirIOSignature |
| 10 | + |
| 11 | +__all__ = ["MySoC"] |
| 12 | + |
| 13 | +# Define signatures for the top level interface types |
| 14 | +class _QSPISignature(wiring.Signature): |
| 15 | + def __init__(self): |
| 16 | + super().__init__({ |
| 17 | + "clk": Out(OutputIOSignature(1)), |
| 18 | + "csn": Out(OutputIOSignature(1)), |
| 19 | + "d": Out(BidirIOSignature(4, individual_oe=True)), |
| 20 | + }) |
| 21 | + |
| 22 | +class _UARTSignature(wiring.Signature): |
| 23 | + def __init__(self): |
| 24 | + super().__init__({ |
| 25 | + "tx": Out(OutputIOSignature(1)), |
| 26 | + "rx": Out(InputIOSignature(1)), |
| 27 | + }) |
| 28 | + |
| 29 | +class _GPIOSignature(wiring.Signature): |
| 30 | + def __init__(self, pin_count=1): |
| 31 | + if pin_count > 32: |
| 32 | + raise ValueError(f"Pin pin_count must be lesser than or equal to 32, not {pin_count}") |
| 33 | + super().__init__({ |
| 34 | + "gpio": Out(BidirIOSignature(pin_count, individual_oe=True)) |
| 35 | + }) |
| 36 | + |
| 37 | +class MySoC(wiring.Component): |
| 38 | + def __init__(self): |
| 39 | + # Top level interfaces |
| 40 | + |
| 41 | + super().__init__({ |
| 42 | + "flash": Out(_QSPISignature()), |
| 43 | + "uart_0": Out(_UARTSignature()), |
| 44 | + "gpio_0": Out(_GPIOSignature(pin_count=8)), |
| 45 | + }) |
| 46 | + |
| 47 | + def elaborate(self, platform): |
| 48 | + m = Module() |
| 49 | + |
| 50 | + base = os.path.dirname(__file__) |
| 51 | + |
| 52 | + verilog_sources = [ |
| 53 | + f"{base}/picosoc_asic_top.v", |
| 54 | + f"{base}/picorv32/picosoc/spimemio.v", |
| 55 | + f"{base}/picorv32/picosoc/simpleuart.v", |
| 56 | + f"{base}/picorv32/picosoc/picosoc.v", |
| 57 | + f"{base}/picorv32/picorv32.v", |
| 58 | + ] |
| 59 | + |
| 60 | + for verilog_file in verilog_sources: |
| 61 | + with open(verilog_file, 'r') as f: |
| 62 | + platform.add_file(verilog_file, f) |
| 63 | + |
| 64 | + m.submodules.soc = soc = Instance("picosoc_asic_top", |
| 65 | + # Clock and reset |
| 66 | + i_clk=ClockSignal(), |
| 67 | + i_resetn=~ResetSignal(), |
| 68 | + |
| 69 | + # UART |
| 70 | + o_ser_tx=self.uart_0.tx.o, |
| 71 | + i_ser_rx=self.uart_0.rx.i, |
| 72 | + |
| 73 | + # SPI flash |
| 74 | + o_flash_csb=self.flash.csn.o, |
| 75 | + o_flash_clk=self.flash.clk.o, |
| 76 | + |
| 77 | + o_flash_io0_oe=self.flash.d.oe[0], |
| 78 | + o_flash_io1_oe=self.flash.d.oe[1], |
| 79 | + o_flash_io2_oe=self.flash.d.oe[2], |
| 80 | + o_flash_io3_oe=self.flash.d.oe[3], |
| 81 | + |
| 82 | + o_flash_io0_do=self.flash.d.o[0], |
| 83 | + o_flash_io1_do=self.flash.d.o[1], |
| 84 | + o_flash_io2_do=self.flash.d.o[2], |
| 85 | + o_flash_io3_do=self.flash.d.o[3], |
| 86 | + |
| 87 | + i_flash_io0_di=self.flash.d.i[0], |
| 88 | + i_flash_io1_di=self.flash.d.i[1], |
| 89 | + i_flash_io2_di=self.flash.d.i[2], |
| 90 | + i_flash_io3_di=self.flash.d.i[3], |
| 91 | + |
| 92 | + # LEDs |
| 93 | + o_leds=self.gpio_0.gpio.o |
| 94 | + ) |
| 95 | + |
| 96 | + # Hardwire GPIO to output enabled |
| 97 | + m.d.comb += self.gpio_0.gpio.oe.eq(0xFF) |
| 98 | + |
| 99 | + return m |
0 commit comments