|
| 1 | +from migen.fhdl.structure import * |
| 2 | +from migen.bank.description import * |
| 3 | +from migen.bank.eventmanager import * |
| 4 | +from migen.bank import csrgen |
| 5 | +from migen.bus import wishbone |
| 6 | + |
| 7 | +_count_width = 11 |
| 8 | + |
| 9 | +class MiniMAC: |
| 10 | + def __init__(self, address): |
| 11 | + # PHY signals |
| 12 | + self.phy_tx_clk = Signal() |
| 13 | + self.phy_tx_data = Signal(BV(4)) |
| 14 | + self.phy_tx_en = Signal() |
| 15 | + self.phy_tx_er = Signal() |
| 16 | + self.phy_rx_clk = Signal() |
| 17 | + self.phy_rx_data = Signal(BV(4)) |
| 18 | + self.phy_dv = Signal() |
| 19 | + self.phy_rx_er = Signal() |
| 20 | + self.phy_col = Signal() |
| 21 | + self.phy_crs = Signal() |
| 22 | + self.phy_rst_n = Signal() |
| 23 | + |
| 24 | + # CPU interface |
| 25 | + self._phy_reset = RegisterField("phy_reset", reset=1) |
| 26 | + self._rx_count_0 = RegisterField("rx_count_0", _count_width, access_bus=READ_ONLY, access_dev=WRITE_ONLY) |
| 27 | + self._rx_count_1 = RegisterField("rx_count_1", _count_width, access_bus=READ_ONLY, access_dev=WRITE_ONLY) |
| 28 | + self._tx_count = RegisterField("tx_count", _count_width, access_dev=READ_WRITE) |
| 29 | + regs = [self._phy_reset, self._rx_count_0, self._rx_count_1, self._tx_count] |
| 30 | + |
| 31 | + self._rx_event_0 = EventSourcePulse() |
| 32 | + self._rx_event_1 = EventSourcePulse() |
| 33 | + self._tx_event = EventSourcePulse() |
| 34 | + self.events = EventManager(self._rx_event_0, self._rx_event_1, self._tx_event) |
| 35 | + |
| 36 | + self.bank = csrgen.Bank(regs + self.events.get_registers(), address=address) |
| 37 | + self.membus = wishbone.Interface() |
| 38 | + |
| 39 | + def get_fragment(self): |
| 40 | + init = Signal(reset=1) |
| 41 | + rx_ready_0 = Signal() |
| 42 | + rx_ready_1 = Signal() |
| 43 | + rx_pending_0 = self._rx_event_0.pending |
| 44 | + rx_pending_1 = self._rx_event_1.pending |
| 45 | + rx_pending_0_r = Signal() |
| 46 | + rx_pending_1_r = Signal() |
| 47 | + comb = [ |
| 48 | + self.phy_rst_n.eq(~self._phy_reset.field.r), |
| 49 | + |
| 50 | + rx_ready_0.eq(init | (rx_pending_0_r & ~rx_pending_0)), |
| 51 | + rx_ready_1.eq(init | (rx_pending_1_r & ~rx_pending_1)), |
| 52 | + |
| 53 | + self._tx_count.field.w.eq(0), |
| 54 | + self._tx_count.field.we.eq(self._tx_event.trigger) |
| 55 | + ] |
| 56 | + sync = [ |
| 57 | + init.eq(0), |
| 58 | + rx_pending_0_r.eq(rx_pending_0), |
| 59 | + rx_pending_1_r.eq(rx_pending_1) |
| 60 | + ] |
| 61 | + inst = [ |
| 62 | + Instance("minimac3", |
| 63 | + [ |
| 64 | + ("rx_done_0", self._rx_event_0.trigger), |
| 65 | + ("rx_count_0", self._rx_count_0.field.w), |
| 66 | + ("rx_done_1", self._rx_event_1.trigger), |
| 67 | + ("rx_count_1", self._rx_count_1.field.w), |
| 68 | + |
| 69 | + ("tx_done", self._tx_event.trigger), |
| 70 | + |
| 71 | + ("wb_dat_o", self.membus.dat_r), |
| 72 | + ("wb_ack_o", self.membus.ack), |
| 73 | + |
| 74 | + ("phy_tx_data", self.phy_tx_data), |
| 75 | + ("phy_tx_en", self.phy_tx_en), |
| 76 | + ("phy_tx_er", self.phy_tx_er), |
| 77 | + ], [ |
| 78 | + ("rx_ready_0", rx_ready_0), |
| 79 | + ("rx_ready_1", rx_ready_1), |
| 80 | + |
| 81 | + ("tx_start", self._tx_count.re), |
| 82 | + ("tx_count", self._tx_count.field.r), |
| 83 | + |
| 84 | + ("wb_adr_i", self.membus.adr), |
| 85 | + ("wb_dat_i", self.membus.dat_w), |
| 86 | + ("wb_sel_i", self.membus.sel), |
| 87 | + ("wb_stb_i", self.membus.stb), |
| 88 | + ("wb_cyc_i", self.membus.cyc), |
| 89 | + ("wb_we_i", self.membus.we), |
| 90 | + |
| 91 | + ("phy_tx_clk", self.phy_tx_clk), |
| 92 | + ("phy_rx_clk", self.phy_rx_clk), |
| 93 | + ("phy_rx_data", self.phy_rx_data), |
| 94 | + ("phy_dv", self.phy_dv), |
| 95 | + ("phy_rx_er", self.phy_rx_er), |
| 96 | + ("phy_col", self.phy_col), |
| 97 | + ("phy_crs", self.phy_crs) |
| 98 | + ], |
| 99 | + clkport="sys_clk", |
| 100 | + rstport="sys_rst" |
| 101 | + ) |
| 102 | + ] |
| 103 | + return Fragment(comb, sync, instances=inst) \ |
| 104 | + + self.events.get_fragment() \ |
| 105 | + + self.bank.get_fragment() |
0 commit comments