Finally got iomux test running (but block not working yet)
[pinmux.git] / src / spec / iomux.py
1 """Simple GPIO peripheral on wishbone
2
3 This is an extremely simple GPIO peripheral intended for use in XICS
4 testing, however it could also be used as an actual GPIO peripheral
5
6 Modified for use with pinmux, will probably change the class name later.
7 """
8 from random import randint
9 from math import ceil, floor
10 from nmigen import Elaboratable, Module, Signal, Record, Array, Cat
11 from nmigen.hdl.rec import Layout
12 from nmigen.utils import log2_int
13 from nmigen.cli import rtlil
14 from soc.minerva.wishbone import make_wb_layout
15 from nmutil.util import wrap
16 from soc.bus.test.wb_rw import wb_read, wb_write
17
18 from nmutil.gtkw import write_gtkw
19
20 cxxsim = False
21 if cxxsim:
22 from nmigen.sim.cxxsim import Simulator, Settle
23 else:
24 from nmigen.sim import Simulator, Settle
25
26 io_layout = (("i", 1),
27 ("oe", 1),
28 ("o", 1)
29 )
30
31 class IOMuxBlock(Elaboratable):
32
33 def __init__(self):
34 print("IO Mux Block")
35 self.n_banks = 4
36 self.bank = Signal(log2_int(self.n_banks))
37
38 temp = []
39 for i in range(self.n_banks):
40 temp_str = "bank{}".format(i)
41 temp.append(Record(name=temp_str, layout=io_layout))
42 self.bank_ports = Array(temp)
43
44 self.out_port = Record(name="IO", layout=io_layout)
45
46 #self.b0 = Record(name="b0", layout=io_layout)
47 #self.b1 = Record(name="b1", layout=io_layout)
48
49 def elaborate(self, platform):
50 m = Module()
51 comb, sync = m.d.comb, m.d.sync
52
53 bank = self.bank
54 bank_ports = self.bank_ports
55 #b0 = self.b0
56 #b1 = self.b1
57 out_port = self.out_port
58
59 sync += out_port.o.eq(bank_ports[0].o)
60 sync += out_port.oe.eq(bank_ports[0].oe)
61 sync += bank_ports[0].i.eq(out_port.i)
62
63 # Connect IO Pad output port to one of the peripheral IOs
64 # Connect peripheral inputs to the IO pad input
65
66 bank_range = range(self.n_banks)
67
68 #with m.Switch(bank):
69
70 for cur_bank in bank_range:
71 sync += out_port.o.eq(bank_ports[cur_bank].o)
72 sync += out_port.oe.eq(bank_ports[cur_bank].oe)
73 sync += bank_ports[cur_bank].i.eq(out_port.i)
74
75 temp_list = list(bank_range)
76 temp_list.pop(temp_list.index(cur_bank))
77 print("Banks with input hardwired to zero: {}".format(temp_list))
78 for j in range(len(temp_list)):
79 unused_bank = temp_list[j]
80 sync += bank_ports[unused_bank].i.eq(0)
81
82 return m
83
84 def __iter__(self):
85 """ Get member signals for Verilog form. """
86 for field in self.out_port.fields.values():
87 yield field
88 for bank in range(len(self.bank_ports)):
89 for field in self.bank_ports[bank].fields.values():
90 yield field
91 yield self.bank
92
93 def ports(self):
94 return list(self)
95
96 def gen_gtkw_doc(module_name, n_banks, filename):
97 # GTKWave doc generation
98 style = {
99 '': {'base': 'hex'},
100 'in': {'color': 'orange'},
101 'out': {'color': 'yellow'},
102 'debug': {'module': 'top', 'color': 'red'}
103 }
104
105 # Create a trace list, each block expected to be a tuple()
106 traces = []
107 for bank in range(0, n_banks):
108 temp_traces = ('Bank{}'.format(bank), [
109 ('bank{}__i'.format(bank), 'in'),
110 ('bank{}__o'.format(bank), 'out'),
111 ('bank{}__oe'.format(bank), 'out')
112 ])
113 traces.append(temp_traces)
114 #print(traces)
115
116 write_gtkw(filename+".gtkw", filename+".vcd", traces, style,
117 module=module_name)
118
119 def sim_iomux():
120 filename = "test_pinmux" # Doesn't include extension
121 dut = IOMuxBlock()
122 vl = rtlil.convert(dut, ports=dut.ports())
123 with open(filename+".il", "w") as f:
124 f.write(vl)
125
126 m = Module()
127 m.submodules.pinmux = dut
128
129 sim = Simulator(m)
130 sim.add_clock(1e-6)
131
132 sim.add_sync_process(wrap(test_iomux(dut)))
133 sim_writer = sim.write_vcd(filename+".vcd")
134 with sim_writer:
135 sim.run()
136
137 gen_gtkw_doc("top.pinmux", dut.n_banks, filename)
138
139 def test_iomux(dut):
140 print("------START----------------------")
141 #print(dir(dut.bank_ports[0]))
142 #print(dut.bank_ports[0].fields)
143 #for (name, signal) in dut.b0.fields.items():
144 # print(name, signal)
145 #print(dir(dut.bank_ports))
146 #print(dut.bank_ports.__len__())
147 #for bank in range(len(dut.bank_ports)):
148 # for values in dut.bank_ports[bank].fields.values():
149 # print(values)
150 yield dut.bank_ports[0].o.eq(1)
151 yield dut.bank.eq(0)
152 yield
153 yield dut.bank_ports[0].o.eq(1)
154 yield
155 yield
156 yield dut.bank_ports[1].o.eq(1)
157 yield
158 yield dut.bank_ports[0].oe.eq(1)
159 yield
160 yield dut.bank.eq(1)
161 yield
162
163 yield dut.bank_ports[0].o.eq(0)
164 yield
165 yield dut.bank_ports[1].o.eq(0)
166 yield
167 yield dut.bank_ports[1].oe.eq(1)
168 yield
169 yield dut.bank.eq(0)
170 yield
171
172 print("Finished the IO mux block test!")
173
174 if __name__ == '__main__':
175 sim_iomux()
176