litex/milkymist/minimac3/__init__.py

107 lines
3.2 KiB
Python

from migen.fhdl.structure import *
from migen.bank.description import *
from migen.bank.eventmanager import *
from migen.bank import csrgen
from migen.bus import wishbone
_count_width = 11
class MiniMAC:
def __init__(self, address):
# PHY signals
self.phy_tx_clk = Signal()
self.phy_tx_data = Signal(BV(4))
self.phy_tx_en = Signal()
self.phy_tx_er = Signal()
self.phy_rx_clk = Signal()
self.phy_rx_data = Signal(BV(4))
self.phy_dv = Signal()
self.phy_rx_er = Signal()
self.phy_col = Signal()
self.phy_crs = Signal()
self.phy_rst_n = Signal()
# CPU interface
self._phy_reset = RegisterField("phy_reset", reset=1)
self._rx_count_0 = RegisterField("rx_count_0", _count_width, access_bus=READ_ONLY, access_dev=WRITE_ONLY)
self._rx_count_1 = RegisterField("rx_count_1", _count_width, access_bus=READ_ONLY, access_dev=WRITE_ONLY)
self._tx_count = RegisterField("tx_count", _count_width, access_dev=READ_WRITE)
self._tx_start = RegisterField("tx_start", access_bus=WRITE_ONLY)
regs = [self._phy_reset, self._rx_count_0, self._rx_count_1, self._tx_count, self._tx_start]
self._rx_event_0 = EventSourcePulse()
self._rx_event_1 = EventSourcePulse()
self._tx_event = EventSourcePulse()
self.events = EventManager(self._rx_event_0, self._rx_event_1, self._tx_event)
self.bank = csrgen.Bank(regs + self.events.get_registers(), address=address)
self.membus = wishbone.Interface()
def get_fragment(self):
init = Signal(reset=1)
rx_ready_0 = Signal()
rx_ready_1 = Signal()
rx_pending_0 = self._rx_event_0.pending
rx_pending_1 = self._rx_event_1.pending
rx_pending_0_r = Signal()
rx_pending_1_r = Signal()
comb = [
self.phy_rst_n.eq(~self._phy_reset.field.r),
rx_ready_0.eq(init | (rx_pending_0_r & ~rx_pending_0)),
rx_ready_1.eq(init | (rx_pending_1_r & ~rx_pending_1)),
self._tx_count.field.w.eq(0),
self._tx_count.field.we.eq(self._tx_event.trigger)
]
sync = [
init.eq(0),
rx_pending_0_r.eq(rx_pending_0),
rx_pending_1_r.eq(rx_pending_1)
]
inst = [
Instance("minimac3",
[
("rx_done_0", self._rx_event_0.trigger),
("rx_count_0", self._rx_count_0.field.w),
("rx_done_1", self._rx_event_1.trigger),
("rx_count_1", self._rx_count_1.field.w),
("tx_done", self._tx_event.trigger),
("wb_dat_o", self.membus.dat_r),
("wb_ack_o", self.membus.ack),
("phy_tx_data", self.phy_tx_data),
("phy_tx_en", self.phy_tx_en),
("phy_tx_er", self.phy_tx_er),
], [
("rx_ready_0", rx_ready_0),
("rx_ready_1", rx_ready_1),
("tx_start", self._tx_start.re),
("tx_count", self._tx_count.field.r),
("wb_adr_i", self.membus.adr),
("wb_dat_i", self.membus.dat_w),
("wb_sel_i", self.membus.sel),
("wb_stb_i", self.membus.stb),
("wb_cyc_i", self.membus.cyc),
("wb_we_i", self.membus.we),
("phy_tx_clk", self.phy_tx_clk),
("phy_rx_clk", self.phy_rx_clk),
("phy_rx_data", self.phy_rx_data),
("phy_dv", self.phy_dv),
("phy_rx_er", self.phy_rx_er),
("phy_col", self.phy_col),
("phy_crs", self.phy_crs)
],
clkport="sys_clk",
rstport="sys_rst"
)
]
return Fragment(comb, sync, instances=inst) \
+ self.events.get_fragment() \
+ self.bank.get_fragment()