Litex Migen design patterns - TomKeddie/prj-litex GitHub Wiki

Declaration

cfg = Signal(32)

Combinatorial

self.comb += pll.reset.eq(platform.request("cpu_reset"))

Clocked

self.sync += boot_1d.eq(boot)

Logic

Inversion

self.comb += pll.reset.eq(~platform.request("cpu_reset"))

And

boot.eq(self.ctrl.storage[2] & self.ctrl.storage[3] & ~self.ctrl.storage[4] & self.ctrl.storage[5] & ~self.ctrl.storage[6] & self.ctrl.storage[7])

Or

reset.eq(ResetSignal() | self.reset)

Concatentation

Cat(rgbleddirect.r, rgbleddirect.g, rgbleddirect.b)

generates

assign {rgb_led1_b, rgb_led1_g, rgb_led1_r} = rgbdirect_storage;

State Machine

fsm = FSM(reset_state="IDLE")
self.submodules += fsm
fsm.act("IDLE",
        If(boot & ~boot_1d, NextState("DUMMY")))
fsm.act("DUMMY",
        icape2_input.eq(c_dummy_word),
        icape2_wr.eq(1),
        icape2_cs.eq(1),
        NextState("SYNC"))
 fsm.act("SYNC",
        icape2_input.eq(c_sync_word),
        icape2_wr.eq(1),
        icape2_cs.eq(1),
        NextState("NOOP1"))
.
.

IO

Simple Input

self.comb += self.cpu.reset.eq(platform.request("user_btn", 3))

Simple Output

TBD

CSR GPIO Output

led_pad = platform.request("rgb_led", 0)
soc.submodules.leds = gpio.GPIOOut(led_pad.g)
soc.add_csr("leds")

CSR GPIO Input

TBD

SubSignals

_usb_pmod = [
    ("usb", 0,
     Subsignal("d_p", Pins("pmoda:0")),
     Subsignal("d_n", Pins("pmoda:1")),
     Subsignal("pullup", Pins("pmoda:2")),
     Subsignal("led", Pins("pmoda:3")),
     IOStandard("LVCMOS33")
    ),
]
.
.
platform.add_extension(_usb_pmod)
usb_pads = platform.request("usb")
usb_iobuf = usbio.IoBuf(usb_pads.d_p, usb_pads.d_n, usb_pads.pullup)

CSR Status

self.stat1 = CSRStatus(size=8)
.
.
self.stat1.status.eq(cfg_out[0:8])

CSR Control

self.cfg1 = CSRStorage(size=8)
.
.
cfg.eq(self.cfg1.storage)

Local Clock

clk = ClockSignal()

Primitive instantiation

self.specials += [
    Instance("BUFR", p_BUFR_DIVIDE="4", i_CE=1, i_CLR=0, i_I=self.cd_clk100.clk, o_O=eth_clk),
]

Debug

Ethernet Debug Bridge

# Ethernet PHY and UDP/IP stack
self.submodules.ethphy = LiteEthPHYMII(self.platform.request("eth_clocks"),
                                       self.platform.request("eth"))
self.add_csr("ethphy")
self.submodules.ethcore = LiteEthUDPIPCore(self.ethphy,
                                           mac_address,
                                           common.convert_ip(ip_address),
                                           self.clk_freq,
                                           with_icmp=True)

# Etherbone bridge
self.submodules.etherbone = LiteEthEtherbone(self.ethcore.udp, 20000)       self.add_wb_master(self.etherbone.wishbone.bus)

self.ethphy.crg.cd_eth_rx.clk.attr.add("keep")
self.ethphy.crg.cd_eth_tx.clk.attr.add("keep")
self.platform.add_period_constraint(self.crg.cd_sys.clk, 10.0)
self.platform.add_period_constraint(self.ethphy.crg.cd_eth_rx.clk, 40.0)
self.platform.add_period_constraint(self.ethphy.crg.cd_eth_tx.clk, 40.0)

self.platform.add_false_path_constraints(
    self.crg.cd_sys.clk,
    self.ethphy.crg.cd_eth_rx.clk,
    self.ethphy.crg.cd_eth_tx.clk)

self.register_mem("vexriscv_debug", 0xf00f0000, self.cpu.debug_bus, 0x10)

Server for Ethernet Debug Bridge

litex_server --udp --udp-ip 192.168.1.50 --udp-port 20000

Serial Debug Bridge

soc.submodules.uartbridge = UARTWishboneBridge(platform.request("serial2"), int(sys_clk_freq), baudrate=115200)
soc.add_wb_master(soc.uartbridge.wishbone)
soc.register_mem("vexriscv_debug", 0xf00f0000, soc.cpu.debug_bus, 0x10)

Server for Serial Debug Bridge

litex_server --uart --uart-port /dev/ttyUSB3

Xilinx IP instantiation

ILA

platform.add_source("ila_0/ila_0.xci")
probe0 = Signal(6)
self.comb += probe0.eq(Cat(spi_pads.clk, spi_pads.cs_n, spi_pads.wp, spi_pads.hold, spi_pads.miso, spi_pads.mosi))
self.specials += [
    Instance("ila_0", i_clk=ClockSignal(), i_probe0=probe0, i_probe1=debugreg),
]
platform.toolchain.additional_commands +=  [
    "write_debug_probes -force {build_name}.ltx",
]