3 pinmux documented here https://libre-soc.org/docs/pinmux/
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
13 from nmutil
.gtkw
import write_gtkw
17 from nmigen
.sim
.cxxsim
import Simulator
, Settle
, Delay
19 from nmigen
.sim
import Simulator
, Settle
, Delay
21 from iomux
import IOMuxBlockSingle
23 io_layout
= (("i", 1),
28 uart_layout
= (("rx", 1),
37 Really basic example, uart tx/rx and i2c sda/scl pinmux
39 class ManPinmux(Elaboratable
):
41 print("Test Manual Pinmux!")
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
)
51 self
.bank
= Signal(log2_int(self
.n_banks
))
53 def elaborate(self
, platform
):
55 comb
, sync
= m
.d
.comb
, m
.d
.sync
58 m
.submodules
.iomux1
= iomux1
59 m
.submodules
.iomux2
= iomux2
67 comb
+= iomux1
.bank
.eq(bank
)
68 comb
+= iomux2
.bank
.eq(bank
)
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
)
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
)
92 for field
in self
.pad1
.fields
.values():
94 for field
in self
.pad2
.fields
.values():
96 for field
in self
.uart
.fields
.values():
98 for field
in self
.i2c
["sda"].fields
.values():
100 for field
in self
.i2c
["scl"].fields
.values():
107 def set_bank(dut
, bank
, delay
=1e-6):
108 yield dut
.bank
.eq(bank
)
111 def uart_send(uart
, byte
, delay
=1e-6):
115 yield uart
.tx
.eq(0) # start bit
117 # send one byte, lsb first
118 for i
in range(0, 8):
119 bit
= (byte
>> i
) & 0x1
120 yield uart
.tx
.eq(bit
)
122 yield uart
.tx
.eq(1) # stop bit
126 def test_man_pinmux(dut
):
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)
134 def sim_man_pinmux():
135 filename
= "test_man_pinmux"
137 vl
= rtlil
.convert(dut
, ports
=dut
.ports())
138 with
open(filename
+".il", "w") as f
:
142 m
.submodules
.manpinmux
= dut
146 sim
.add_process(wrap(test_man_pinmux(dut
)))
147 sim_writer
= sim
.write_vcd(filename
+".vcd")
150 #gen_gtkw_doc("top.manpinmux", dut.n_banks, filename)
152 if __name__
== '__main__':