1 """Simple GPIO peripheral on wishbone
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
6 Modified for use with pinmux, will probably change the class name later.
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
18 from nmutil
.gtkw
import write_gtkw
22 from nmigen
.sim
.cxxsim
import Simulator
, Settle
24 from nmigen
.sim
import Simulator
, Settle
26 io_layout
= (("i", 1),
31 class IOMuxBlock(Elaboratable
):
36 self
.bank
= Signal(log2_int(self
.n_banks
))
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
)
44 self
.out_port
= Record(name
="IO", layout
=io_layout
)
46 #self.b0 = Record(name="b0", layout=io_layout)
47 #self.b1 = Record(name="b1", layout=io_layout)
49 def elaborate(self
, platform
):
51 comb
, sync
= m
.d
.comb
, m
.d
.sync
54 bank_ports
= self
.bank_ports
57 out_port
= self
.out_port
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
)
63 # Connect IO Pad output port to one of the peripheral IOs
64 # Connect peripheral inputs to the IO pad input
66 bank_range
= range(self
.n_banks
)
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
)
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)
85 """ Get member signals for Verilog form. """
86 for field
in self
.out_port
.fields
.values():
88 for bank
in range(len(self
.bank_ports
)):
89 for field
in self
.bank_ports
[bank
].fields
.values():
96 def gen_gtkw_doc(module_name
, n_banks
, filename
):
97 # GTKWave doc generation
100 'in': {'color': 'orange'},
101 'out': {'color': 'yellow'},
102 'debug': {'module': 'top', 'color': 'red'}
105 # Create a trace list, each block expected to be a tuple()
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')
113 traces
.append(temp_traces
)
116 write_gtkw(filename
+".gtkw", filename
+".vcd", traces
, style
,
120 filename
= "test_pinmux" # Doesn't include extension
122 vl
= rtlil
.convert(dut
, ports
=dut
.ports())
123 with
open(filename
+".il", "w") as f
:
127 m
.submodules
.pinmux
= dut
132 sim
.add_sync_process(wrap(test_iomux(dut
)))
133 sim_writer
= sim
.write_vcd(filename
+".vcd")
137 gen_gtkw_doc("top.pinmux", dut
.n_banks
, filename
)
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():
150 yield dut
.bank_ports
[0].o
.eq(1)
153 yield dut
.bank_ports
[0].o
.eq(1)
156 yield dut
.bank_ports
[1].o
.eq(1)
158 yield dut
.bank_ports
[0].oe
.eq(1)
163 yield dut
.bank_ports
[0].o
.eq(0)
165 yield dut
.bank_ports
[1].o
.eq(0)
167 yield dut
.bank_ports
[1].oe
.eq(1)
172 print("Finished the IO mux block test!")
174 if __name__
== '__main__':