|
|
|
from enum import Enum, unique
|
|
|
|
|
|
|
|
from nmigen import Signal, Elaboratable, Module, Cat
|
|
|
|
from nmigen.back import verilog
|
|
|
|
from nmigen_soc.wishbone import Interface as WishboneInterface
|
|
|
|
|
|
|
|
from .io_space import IOSpace
|
|
|
|
from .lpc2wb import lpc2wb
|
|
|
|
from .lpc_ctrl import LPC_Ctrl
|
|
|
|
|
|
|
|
|
|
|
|
@unique
|
|
|
|
class StateEnum(Enum):
|
|
|
|
IDLE = 0
|
|
|
|
ACK = 1
|
|
|
|
|
|
|
|
|
|
|
|
class LPCPeripheral(Elaboratable):
|
|
|
|
"""
|
|
|
|
Parameters
|
|
|
|
----------
|
|
|
|
|
|
|
|
Attributes
|
|
|
|
----------
|
|
|
|
"""
|
|
|
|
def __init__(self):
|
|
|
|
# BMC wishbone. We dont use a Record because we want predictable
|
|
|
|
# signal names so we can hook it up to VHDL/Verilog
|
|
|
|
self.adr = Signal(14)
|
|
|
|
self.dat_w = Signal(8)
|
|
|
|
self.dat_r = Signal(8)
|
|
|
|
self.sel = Signal()
|
|
|
|
self.cyc = Signal()
|
|
|
|
self.stb = Signal()
|
|
|
|
self.we = Signal()
|
|
|
|
self.ack = Signal()
|
|
|
|
|
|
|
|
# DMA wishbone
|
|
|
|
self.dma_adr = Signal(30)
|
|
|
|
self.dma_dat_w = Signal(32)
|
|
|
|
self.dma_dat_r = Signal(32)
|
|
|
|
self.dma_sel = Signal(4)
|
|
|
|
self.dma_cyc = Signal()
|
|
|
|
self.dma_stb = Signal()
|
|
|
|
self.dma_we = Signal()
|
|
|
|
self.dma_ack = Signal()
|
|
|
|
|
|
|
|
# LPC bus
|
|
|
|
self.lclk = Signal()
|
|
|
|
self.lframe = Signal()
|
|
|
|
self.lad_in = Signal(4)
|
|
|
|
self.lad_out = Signal(4)
|
|
|
|
self.lad_en = Signal()
|
|
|
|
self.lreset = Signal()
|
|
|
|
|
|
|
|
# Interrupts
|
|
|
|
self.bmc_vuart_irq = Signal()
|
|
|
|
self.bmc_ipmi_irq = Signal()
|
|
|
|
|
|
|
|
self.target_vuart_irq = Signal()
|
|
|
|
self.target_ipmi_irq = Signal()
|
|
|
|
|
|
|
|
def elaborate(self, platform):
|
|
|
|
m = Module()
|
|
|
|
|
|
|
|
m.submodules.io = io = IOSpace()
|
|
|
|
m.submodules.lpc = lpc = lpc2wb()
|
|
|
|
m.submodules.lpc_ctrl = lpc_ctrl = LPC_Ctrl()
|
|
|
|
|
|
|
|
m.d.comb += [
|
|
|
|
# BMC wishbone
|
|
|
|
io.bmc_wb.adr.eq(self.adr),
|
|
|
|
io.bmc_wb.dat_w.eq(self.dat_w),
|
|
|
|
io.bmc_wb.sel.eq(self.sel),
|
|
|
|
io.bmc_wb.cyc.eq(self.cyc),
|
|
|
|
io.bmc_wb.stb.eq(self.stb),
|
|
|
|
io.bmc_wb.we.eq(self.we),
|
|
|
|
self.dat_r.eq(io.bmc_wb.dat_r),
|
|
|
|
self.ack.eq(io.bmc_wb.ack),
|
|
|
|
|
|
|
|
# target wishbone
|
|
|
|
io.target_wb.adr.eq(lpc.io_wb.adr),
|
|
|
|
io.target_wb.dat_w.eq(lpc.io_wb.dat_w),
|
|
|
|
io.target_wb.sel.eq(lpc.io_wb.sel),
|
|
|
|
io.target_wb.cyc.eq(lpc.io_wb.cyc),
|
|
|
|
io.target_wb.stb.eq(lpc.io_wb.stb),
|
|
|
|
io.target_wb.we.eq(lpc.io_wb.we),
|
|
|
|
lpc.io_wb.dat_r.eq(io.target_wb.dat_r),
|
|
|
|
lpc.io_wb.ack.eq(io.target_wb.ack),
|
|
|
|
lpc.io_wb.err.eq(io.target_wb.err),
|
|
|
|
|
|
|
|
# LPC CTRL to DMA wishbone
|
|
|
|
self.dma_adr.eq(lpc_ctrl.dma_wb.adr),
|
|
|
|
self.dma_dat_w.eq(lpc_ctrl.dma_wb.dat_w),
|
|
|
|
self.dma_sel.eq(lpc_ctrl.dma_wb.sel),
|
|
|
|
self.dma_cyc.eq(lpc_ctrl.dma_wb.cyc),
|
|
|
|
self.dma_stb.eq(lpc_ctrl.dma_wb.stb),
|
|
|
|
self.dma_we.eq(lpc_ctrl.dma_wb.we),
|
|
|
|
lpc_ctrl.dma_wb.dat_r.eq(self.dma_dat_r),
|
|
|
|
lpc_ctrl.dma_wb.ack.eq(self.dma_ack),
|
|
|
|
|
|
|
|
# LPC to LPC CTRL wishbone
|
|
|
|
lpc.fw_wb.connect(lpc_ctrl.lpc_wb),
|
|
|
|
|
|
|
|
# LPC
|
|
|
|
lpc.lclk.eq(self.lclk),
|
|
|
|
lpc.lframe.eq(self.lframe),
|
|
|
|
lpc.lad_in.eq(self.lad_in),
|
|
|
|
self.lad_out.eq(lpc.lad_out),
|
|
|
|
self.lad_en.eq(lpc.lad_en),
|
|
|
|
lpc.lreset.eq(self.lreset),
|
|
|
|
|
|
|
|
# Interrupts
|
|
|
|
self.bmc_vuart_irq.eq(io.bmc_vuart_irq),
|
|
|
|
self.bmc_ipmi_irq.eq(io.bmc_ipmi_irq),
|
|
|
|
self.target_vuart_irq.eq(io.target_vuart_irq),
|
|
|
|
self.target_ipmi_irq.eq(io.target_ipmi_irq),
|
|
|
|
]
|
|
|
|
|
|
|
|
return m
|
|
|
|
|
|
|
|
|
|
|
|
if __name__ == "__main__":
|
|
|
|
top = LPCPeripheral()
|
|
|
|
with open("lpcperipheral.v", "w") as f:
|
|
|
|
f.write(verilog.convert(top, ports=[
|
|
|
|
top.adr, top.dat_w, top.dat_r, top.sel, top.cyc, top.stb,
|
|
|
|
top.we, top.ack, top.dma_adr, top.dma_dat_w, top.dma_dat_r,
|
|
|
|
top.dma_sel, top.dma_cyc, top.dma_stb, top.dma_we, top.dma_ack,
|
|
|
|
top.lclk, top.lframe, top.lad_in,
|
|
|
|
top.lad_out, top.lad_en, top.lreset, top.bmc_vuart_irq,
|
|
|
|
top.bmc_ipmi_irq, top.target_vuart_irq, top.target_ipmi_irq], name="lpc_top"))
|