minimac: add tx start register
[litex.git] / milkymist / minimac3 / __init__.py
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 self._tx_start = RegisterField("tx_start", access_bus=WRITE_ONLY)
30 regs = [self._phy_reset, self._rx_count_0, self._rx_count_1, self._tx_count, self._tx_start]
31
32 self._rx_event_0 = EventSourcePulse()
33 self._rx_event_1 = EventSourcePulse()
34 self._tx_event = EventSourcePulse()
35 self.events = EventManager(self._rx_event_0, self._rx_event_1, self._tx_event)
36
37 self.bank = csrgen.Bank(regs + self.events.get_registers(), address=address)
38 self.membus = wishbone.Interface()
39
40 def get_fragment(self):
41 init = Signal(reset=1)
42 rx_ready_0 = Signal()
43 rx_ready_1 = Signal()
44 rx_pending_0 = self._rx_event_0.pending
45 rx_pending_1 = self._rx_event_1.pending
46 rx_pending_0_r = Signal()
47 rx_pending_1_r = Signal()
48 comb = [
49 self.phy_rst_n.eq(~self._phy_reset.field.r),
50
51 rx_ready_0.eq(init | (rx_pending_0_r & ~rx_pending_0)),
52 rx_ready_1.eq(init | (rx_pending_1_r & ~rx_pending_1)),
53
54 self._tx_count.field.w.eq(0),
55 self._tx_count.field.we.eq(self._tx_event.trigger)
56 ]
57 sync = [
58 init.eq(0),
59 rx_pending_0_r.eq(rx_pending_0),
60 rx_pending_1_r.eq(rx_pending_1)
61 ]
62 inst = [
63 Instance("minimac3",
64 [
65 ("rx_done_0", self._rx_event_0.trigger),
66 ("rx_count_0", self._rx_count_0.field.w),
67 ("rx_done_1", self._rx_event_1.trigger),
68 ("rx_count_1", self._rx_count_1.field.w),
69
70 ("tx_done", self._tx_event.trigger),
71
72 ("wb_dat_o", self.membus.dat_r),
73 ("wb_ack_o", self.membus.ack),
74
75 ("phy_tx_data", self.phy_tx_data),
76 ("phy_tx_en", self.phy_tx_en),
77 ("phy_tx_er", self.phy_tx_er),
78 ], [
79 ("rx_ready_0", rx_ready_0),
80 ("rx_ready_1", rx_ready_1),
81
82 ("tx_start", self._tx_start.re),
83 ("tx_count", self._tx_count.field.r),
84
85 ("wb_adr_i", self.membus.adr),
86 ("wb_dat_i", self.membus.dat_w),
87 ("wb_sel_i", self.membus.sel),
88 ("wb_stb_i", self.membus.stb),
89 ("wb_cyc_i", self.membus.cyc),
90 ("wb_we_i", self.membus.we),
91
92 ("phy_tx_clk", self.phy_tx_clk),
93 ("phy_rx_clk", self.phy_rx_clk),
94 ("phy_rx_data", self.phy_rx_data),
95 ("phy_dv", self.phy_dv),
96 ("phy_rx_er", self.phy_rx_er),
97 ("phy_col", self.phy_col),
98 ("phy_crs", self.phy_crs)
99 ],
100 clkport="sys_clk",
101 rstport="sys_rst"
102 )
103 ]
104 return Fragment(comb, sync, instances=inst) \
105 + self.events.get_fragment() \
106 + self.bank.get_fragment()