61e772b990b034c7ef74e8ff9a66c0cf045e9982
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
, Delay
24 from nmigen
.sim
import Simulator
, Settle
, Delay
26 io_layout
= (("i", 1),
31 class IOMuxBlockSingle(Elaboratable
):
34 print("1-bit IO Mux Block")
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 def elaborate(self
, platform
):
48 comb
, sync
= m
.d
.comb
, m
.d
.sync
51 bank_ports
= self
.bank_ports
52 out_port
= self
.out_port
54 # Connect IO Pad output port to one of the peripheral IOs
55 # Connect peripheral inputs to the IO pad input
64 with m
.Case(BANK0_WB
):
65 self
.connect_bank_to_io(comb
, BANK0_WB
)
66 with m
.Case(BANK1_P1
):
67 self
.connect_bank_to_io(comb
, BANK1_P1
)
68 with m
.Case(BANK2_P2
):
69 self
.connect_bank_to_io(comb
, BANK2_P2
)
70 with m
.Case(BANK3_P3
):
71 self
.connect_bank_to_io(comb
, BANK3_P3
)
74 def connect_bank_to_io(self
, domain
, bank_arg
):
75 domain
+= self
.out_port
.o
.eq(self
.bank_ports
[bank_arg
].o
)
76 domain
+= self
.out_port
.oe
.eq(self
.bank_ports
[bank_arg
].oe
)
77 domain
+= self
.bank_ports
[bank_arg
].i
.eq(self
.out_port
.i
)
80 """ Get member signals for Verilog form. """
81 for field
in self
.out_port
.fields
.values():
83 for bank
in range(len(self
.bank_ports
)):
84 for field
in self
.bank_ports
[bank
].fields
.values():
91 def gen_gtkw_doc(module_name
, n_banks
, filename
):
92 # GTKWave doc generation
95 'in': {'color': 'orange'},
96 'out': {'color': 'yellow'},
97 'debug': {'module': 'top', 'color': 'red'}
100 # Create a trace list, each block expected to be a tuple()
102 for bank
in range(0, n_banks
):
103 temp_traces
= ('Bank{}'.format(bank
), [
104 ('bank{}__i'.format(bank
), 'in'),
105 ('bank{}__o'.format(bank
), 'out'),
106 ('bank{}__oe'.format(bank
), 'out')
108 traces
.append(temp_traces
)
110 temp_traces
= ('Misc', [
113 traces
.append(temp_traces
)
114 temp_traces
= ('IO port to pad', [
119 traces
.append(temp_traces
)
122 write_gtkw(filename
+".gtkw", filename
+".vcd", traces
, style
,
126 filename
= "test_pinmux" # Doesn't include extension
127 dut
= IOMuxBlockSingle()
128 vl
= rtlil
.convert(dut
, ports
=dut
.ports())
129 with
open(filename
+".il", "w") as f
:
133 m
.submodules
.pinmux
= dut
137 sim
.add_process(wrap(test_iomux(dut
)))
138 sim_writer
= sim
.write_vcd(filename
+".vcd")
142 gen_gtkw_doc("top.pinmux", dut
.n_banks
, filename
)
144 # Method for toggling i/o/oe of a particular bank port,
145 # while bank_sel has three different values:
146 # value before, given value, value after
147 # when rand is True, previous and consecutive values are
148 # random (but NOT equal to given bank_sel)
149 def test_single_bank(dut
, bank
, rand
=True):
151 print("Randomising the prev and next banks")
153 while(prev_bank
== bank
):
154 prev_bank
= randint(0, dut
.n_banks
-1)
156 while(next_bank
== bank
):
157 next_bank
= randint(0, dut
.n_banks
-1)
160 prev_bank
= dut
.n_banks
164 if bank
== dut
.n_banks
:
169 print("Prev={}, Given={}, Next={}".format(prev_bank
, bank
, next_bank
))
171 yield dut
.bank
.eq(prev_bank
)
173 yield dut
.bank_ports
[bank
].o
.eq(0)
174 yield dut
.bank_ports
[bank
].oe
.eq(0)
175 yield dut
.out_port
.i
.eq(0)
178 yield dut
.bank
.eq(bank
)
181 test_o
= yield dut
.out_port
.o
182 test_oe
= yield dut
.out_port
.oe
183 test_i
= yield dut
.bank_ports
[bank
].i
188 yield dut
.bank_ports
[bank
].o
.eq(1)
190 yield dut
.bank_ports
[bank
].oe
.eq(1)
192 yield dut
.out_port
.i
.eq(1)
195 test_o
= yield dut
.out_port
.o
196 test_oe
= yield dut
.out_port
.oe
197 test_i
= yield dut
.bank_ports
[bank
].i
198 #print(test_o, test_oe, test_i)
203 yield dut
.bank
.eq(next_bank
)
205 yield dut
.bank_ports
[bank
].o
.eq(0)
206 yield dut
.bank_ports
[bank
].oe
.eq(0)
207 yield dut
.out_port
.i
.eq(0)
211 print("------START----------------------")
212 #print(dir(dut.bank_ports[0]))
213 #print(dut.bank_ports[0].fields)
215 yield from test_single_bank(dut
, 0)
216 yield from test_single_bank(dut
, 1)
217 yield from test_single_bank(dut
, 2)
218 yield from test_single_bank(dut
, 3)
220 print("Finished the 1-bit IO mux block test!")
222 if __name__
== '__main__':