Adding first manual mux experiment
[pinmux.git] / src / spec / stage2.py
1 #!/usr/bin/env python3
2 """
3 pinmux documented here https://libre-soc.org/docs/pinmux/
4 """
5 from nmigen import Elaboratable, Module, Signal, Record, Array, Cat
6 from nmigen.hdl.rec import Layout
7 from nmigen.utils import log2_int
8 from nmigen.cli import rtlil
9 from soc.minerva.wishbone import make_wb_layout
10 from nmutil.util import wrap
11 #from soc.bus.test.wb_rw import wb_read, wb_write
12
13 from nmutil.gtkw import write_gtkw
14
15 cxxsim = False
16 if cxxsim:
17 from nmigen.sim.cxxsim import Simulator, Settle, Delay
18 else:
19 from nmigen.sim import Simulator, Settle, Delay
20
21 from iomux import IOMuxBlockSingle
22
23 io_layout = (("i", 1),
24 ("oe", 1),
25 ("o", 1)
26 )
27
28 uart_layout = (("rx", 1),
29 ("tx", 1),
30 ("oe", 1)
31 )
32
33 UART_BANK = 0
34 I2C_BANK = 1
35
36 """
37 Really basic example, uart tx/rx and i2c sda/scl pinmux
38 """
39 class ManPinmux(Elaboratable):
40 def __init__(self):
41 print("Test Manual Pinmux!")
42 self.n_banks = 2
43 self.iomux1 = IOMuxBlockSingle(self.n_banks)
44 self.iomux2 = IOMuxBlockSingle(self.n_banks)
45 self.pad1 = Record(name="Pad1", layout=io_layout)
46 self.pad2 = Record(name="Pad2", layout=io_layout)
47 self.uart = Record(name="uart", layout=uart_layout)
48 self.i2c = {"sda": Record(name="sda", layout=io_layout),
49 "scl": Record(name="scl", layout=io_layout)
50 }
51 self.bank = Signal(log2_int(self.n_banks))
52
53 def elaborate(self, platform):
54 m = Module()
55 comb, sync = m.d.comb, m.d.sync
56 iomux1 = self.iomux1
57 iomux2 = self.iomux2
58 m.submodules.iomux1 = iomux1
59 m.submodules.iomux2 = iomux2
60
61 pad1 = self.pad1
62 pad2 = self.pad2
63 uart = self.uart
64 i2c = self.i2c
65 bank = self.bank
66
67 comb += iomux1.bank.eq(bank)
68 comb += iomux2.bank.eq(bank)
69
70 # uart connected to bank 0 - Pad 1 tx, Pad 2 rx
71 comb += iomux1.bank_ports[UART_BANK].o.eq(uart.tx)
72 comb += iomux1.bank_ports[UART_BANK].oe.eq(uart.oe)
73 comb += uart.rx.eq(iomux2.bank_ports[UART_BANK].i)
74 # i2c connected to bank 1 - Pad 1 sda, Pad 2 scl
75 comb += iomux1.bank_ports[I2C_BANK].o.eq(i2c["sda"].o)
76 comb += iomux1.bank_ports[I2C_BANK].oe.eq(i2c["sda"].oe)
77 comb += i2c["sda"].i.eq(iomux1.bank_ports[I2C_BANK].i)
78 comb += iomux2.bank_ports[I2C_BANK].o.eq(i2c["scl"].o)
79 comb += iomux2.bank_ports[I2C_BANK].oe.eq(i2c["scl"].oe)
80 comb += i2c["scl"].i.eq(iomux2.bank_ports[I2C_BANK].i)
81
82 comb += pad1.o.eq(iomux1.out_port.o)
83 comb += pad1.oe.eq(iomux1.out_port.oe)
84 comb += iomux1.out_port.i.eq(pad1.i)
85 comb += pad2.o.eq(iomux2.out_port.o)
86 comb += pad2.oe.eq(iomux2.out_port.oe)
87 comb += iomux2.out_port.i.eq(pad2.i)
88
89 return m
90
91 def __iter__(self):
92 for field in self.pad1.fields.values():
93 yield field
94 for field in self.pad2.fields.values():
95 yield field
96 for field in self.uart.fields.values():
97 yield field
98 for field in self.i2c["sda"].fields.values():
99 yield field
100 for field in self.i2c["scl"].fields.values():
101 yield field
102 yield self.bank
103
104 def ports(self):
105 return list(self)
106
107 def set_bank(dut, bank, delay=1e-6):
108 yield dut.bank.eq(bank)
109 yield Delay(delay)
110
111 def uart_send(uart, byte, delay=1e-6):
112 yield uart.oe.eq(1)
113 yield uart.tx.eq(1)
114 yield Delay(2*delay)
115 yield uart.tx.eq(0) # start bit
116 yield Delay(delay)
117 # send one byte, lsb first
118 for i in range(0, 8):
119 bit = (byte >> i) & 0x1
120 yield uart.tx.eq(bit)
121 yield Delay(delay)
122 yield uart.tx.eq(1) # stop bit
123 yield Delay(delay)
124
125
126 def test_man_pinmux(dut):
127 delay = 1e-6
128 yield from set_bank(dut, UART_BANK)
129 yield from uart_send(dut.uart, 0x42)
130 yield dut.pad1.i.eq(1)
131 yield dut.pad2.i.eq(1)
132
133
134 def sim_man_pinmux():
135 filename = "test_man_pinmux"
136 dut = ManPinmux()
137 vl = rtlil.convert(dut, ports=dut.ports())
138 with open(filename+".il", "w") as f:
139 f.write(vl)
140
141 m = Module()
142 m.submodules.manpinmux = dut
143
144 sim = Simulator(m)
145
146 sim.add_process(wrap(test_man_pinmux(dut)))
147 sim_writer = sim.write_vcd(filename+".vcd")
148 with sim_writer:
149 sim.run()
150 #gen_gtkw_doc("top.manpinmux", dut.n_banks, filename)
151
152 if __name__ == '__main__':
153 sim_man_pinmux()