("o", 1)
)
-# This block produces an N-to-1 mux with N 3-bit bank ports and one pad port.
-# The bank ports are intended to be wired to peripheral functions,
+# This block produces an N-to-1 mux with N 3-bit periph ports and one pad port.
+# The peripheral ports are intended to be wired to peripheral functions,
# while the pad port will connect to the I/O pad.
-# Each port has o/oe/i signals, and the bank signal is used to select
-# between the bank ports.
+# Peripheral and output ports have o/oe/i signals, and the port signal is used
+# to select between the peripheral ports.
class IOMuxBlockSingle(Elaboratable):
- def __init__(self, n_banks=4):
+ def __init__(self, n_ports=4):
print("1-bit IO Mux Block")
- self.n_banks = n_banks
- self.bank = Signal(log2_int(self.n_banks))
+ self.n_ports = n_ports
+ self.port = Signal(log2_int(self.n_ports))
temp = []
- for i in range(self.n_banks):
- name = "bank%d" % i
+ for i in range(self.n_ports):
+ name = "port%d" % i
temp.append(Record(name=name, layout=io_layout))
- self.bank_ports = Array(temp)
+ self.periph_ports = Array(temp)
self.out_port = Record(name="IO", layout=io_layout)
m = Module()
comb, sync = m.d.comb, m.d.sync
- bank = self.bank
- bank_ports = self.bank_ports
+ port = self.port
+ periph_ports = self.periph_ports
out_port = self.out_port
# Connect IO Pad output port to one of the peripheral IOs
# Connect peripheral inputs to the IO pad input
- comb += self.out_port.o.eq(self.bank_ports[bank].o)
- comb += self.out_port.oe.eq(self.bank_ports[bank].oe)
+ comb += self.out_port.o.eq(self.periph_ports[port].o)
+ comb += self.out_port.oe.eq(self.periph_ports[port].oe)
- comb += self.bank_ports[bank].i.eq(self.out_port.i)
+ comb += self.periph_ports[port].i.eq(self.out_port.i)
return m
- def connect_bank_to_io(self, domain, bank_arg):
- domain += self.out_port.o.eq(self.bank_ports[bank_arg].o)
- domain += self.out_port.oe.eq(self.bank_ports[bank_arg].oe)
- domain += self.bank_ports[bank_arg].i.eq(self.out_port.i)
+ def connect_port_to_io(self, domain, port_arg):
+ domain += self.out_port.o.eq(self.periph_ports[port_arg].o)
+ domain += self.out_port.oe.eq(self.periph_ports[port_arg].oe)
+ domain += self.periph_ports[port_arg].i.eq(self.out_port.i)
def __iter__(self):
""" Get member signals for Verilog form. """
for field in self.out_port.fields.values():
yield field
- for bank in range(self.n_banks):
- for field in self.bank_ports[bank].fields.values():
+ for port in range(self.n_ports):
+ for field in self.periph_ports[port].fields.values():
yield field
- yield self.bank
+ yield self.port
def ports(self):
return list(self)
-# Method to test a particular bank port
-# when rand_order is True, previous and consecutive banks are
-# random (but NOT equal to given bank)
-def test_single_bank(dut, bank, rand_order=True, delay=1e-6):
+# Method to test a particular peripheral port
+# when rand_order is True, previous and consecutive ports are
+# random (but NOT equal to given port)
+def test_single_port(dut, port, rand_order=True, delay=1e-6):
if rand_order:
- print("Randomising the prev and next banks")
- prev_bank=bank
- while(prev_bank == bank):
- prev_bank = randint(0, dut.n_banks-1)
- next_bank=bank
- while(next_bank == bank):
- next_bank = randint(0, dut.n_banks-1)
+ print("Randomising the prev and next ports")
+ prev_port=port
+ while(prev_port == port):
+ prev_port = randint(0, dut.n_ports-1)
+ next_port=port
+ while(next_port == port):
+ next_port = randint(0, dut.n_ports-1)
else:
- # Set the prev and next banks as consecutive banks
- if bank == 0:
- prev_bank = dut.n_banks - 1
+ # Set the prev and next ports as consecutive ports
+ if port == 0:
+ prev_port = dut.n_ports - 1
else:
- prev_bank = bank - 1
+ prev_port = port - 1
- if bank == dut.n_banks:
- next_bank = 0
+ if port == dut.n_ports:
+ next_port = 0
else:
- next_bank = bank + 1
+ next_port = port + 1
- print("Prev=%d, Given=%d, Next=%d" % (prev_bank, bank, next_bank))
+ print("Prev=%d, Given=%d, Next=%d" % (prev_port, port, next_port))
# Clear o/oe, delay, set port i
- # Set to previous bank, delay
- # Assert bank i == 0
- # Set to desired bank
- # Assert bank i == 1
+ # Set to previous port, delay
+ # Assert port i == 0
+ # Set to desired port
+ # Assert port i == 1
# Set o/oe, delay
# Assert o, oe == 1
- # Set to next bank, delay
- # Assert bank i == 0
- yield dut.bank_ports[bank].o.eq(0)
+ # Set to next port, delay
+ # Assert port i == 0
+ yield dut.periph_ports[port].o.eq(0)
yield Delay(delay)
- yield dut.bank_ports[bank].oe.eq(0)
+ yield dut.periph_ports[port].oe.eq(0)
yield Delay(delay)
yield dut.out_port.i.eq(1)
yield Delay(delay)
- yield dut.bank.eq(prev_bank)
+ yield dut.port.eq(prev_port)
yield Delay(delay)
- test_i = yield dut.bank_ports[bank].i
+ test_i = yield dut.periph_ports[port].i
assert(test_i == 0)
- yield dut.bank.eq(bank)
+ yield dut.port.eq(port)
yield Delay(delay)
test_o = yield dut.out_port.o
test_oe = yield dut.out_port.oe
- test_i = yield dut.bank_ports[bank].i
+ test_i = yield dut.periph_ports[port].i
assert(test_o == 0)
assert(test_oe == 0)
assert(test_i == 1)
- yield dut.bank_ports[bank].o.eq(1)
+ yield dut.periph_ports[port].o.eq(1)
yield Delay(delay)
- yield dut.bank_ports[bank].oe.eq(1)
+ yield dut.periph_ports[port].oe.eq(1)
yield Delay(delay)
test_o = yield dut.out_port.o
assert(test_o == 1)
assert(test_oe == 1)
- yield dut.bank.eq(next_bank)
+ yield dut.port.eq(next_port)
yield Delay(delay)
- test_i = yield dut.bank_ports[bank].i
+ test_i = yield dut.periph_ports[port].i
assert(test_i == 0)
def test_iomux(dut, rand_order=True):
print("------START----------------------")
- #print(dir(dut.bank_ports[0]))
- #print(dut.bank_ports[0].fields)
+ #print(dir(dut.periph_ports[0]))
+ #print(dut.periph_ports[0].fields)
- # Produce a test list of bank values
- test_bank_vec = list(range(0, dut.n_banks))
- #print(test_bank_vec)
+ # Produce a test list of port values
+ test_port_vec = list(range(0, dut.n_ports))
+ #print(test_port_vec)
# Randomise for wider testing
if rand_order:
- shuffle(test_bank_vec)
- #print(test_bank_vec)
- for i in range(dut.n_banks):
- yield from test_single_bank(dut, test_bank_vec[i], rand_order)
+ shuffle(test_port_vec)
+ #print(test_port_vec)
+ for i in range(dut.n_ports):
+ yield from test_single_port(dut, test_port_vec[i], rand_order)
print("Finished the 1-bit IO mux block test!")
-def gen_gtkw_doc(module_name, n_banks, filename):
+def gen_gtkw_doc(module_name, n_ports, filename):
# GTKWave doc generation
style = {
'': {'base': 'hex'},
# Create a trace list, each block expected to be a tuple()
traces = []
- for bank in range(0, n_banks):
- temp_traces = ('Bank%d' % bank, [
- ('bank%d__i' % bank, 'in'),
- ('bank%d__o' % bank, 'out'),
- ('bank%d__oe' % bank, 'out')
+ for port in range(0, n_ports):
+ temp_traces = ('Bank%d' % port, [
+ ('port%d__i' % port, 'in'),
+ ('port%d__o' % port, 'out'),
+ ('port%d__oe' % port, 'out')
])
traces.append(temp_traces)
temp_traces = ('Misc', [
- ('bank[%d:0]' % ((n_banks-1).bit_length()-1), 'in')
+ ('port[%d:0]' % ((n_ports-1).bit_length()-1), 'in')
])
traces.append(temp_traces)
temp_traces = ('IO port to pad', [
def sim_iomux(rand_order=True):
filename = "test_iomux" # Doesn't include extension
- n_banks = 8
- dut = IOMuxBlockSingle(n_banks)
+ n_ports = 8
+ dut = IOMuxBlockSingle(n_ports)
vl = rtlil.convert(dut, ports=dut.ports())
with open(filename+".il", "w") as f:
f.write(vl)
with sim_writer:
sim.run()
- gen_gtkw_doc("top.pinmux", dut.n_banks, filename)
+ gen_gtkw_doc("top.pinmux", dut.n_ports, filename)
def __init__(self, wb_wordsize, pinspec):
print("1-bit Pin Mux Block with JTAG")
- self.n_banks = 4
+ self.n_ports = 4
self.n_gpios = 1
self.wb_wordsize = wb_wordsize # 4 Bytes, 32-bits
spec.reg_wid = self.wb_wordsize*8
temp = []
- for i in range(1, self.n_banks):
+ for i in range(1, self.n_ports):
temp_str = "%s" % (pinspec["mux%d" % i])
temp.append(Record(name=temp_str, layout=io_layout))
self.periph_ports = Array(temp)
self.pad_port = Record(name=pinspec["name"], layout=io_layout)
- self.iomux = IOMuxBlockSingle(self.n_banks)
+ self.iomux = IOMuxBlockSingle(self.n_ports)
self.gpio = SimpleGPIO(self.wb_wordsize, self.n_gpios)
# This is probably easier to extend in future by bringing out WB
# interface to top-level
# gpio.bus.bte.eq(bus.bte) # Burst Type Extension
# ]
- m.d.comb += iomux.bank.eq(gpio.gpio_ports[0].bank)
+ m.d.comb += iomux.port.eq(gpio.gpio_ports[0].bank)
- # WB GPIO always bank0
- m.d.comb += iomux.bank_ports[0].o.eq(gpio.gpio_ports[0].o)
- m.d.comb += iomux.bank_ports[0].oe.eq(gpio.gpio_ports[0].oe)
- m.d.comb += gpio.gpio_ports[0].i.eq(iomux.bank_ports[0].i)
+ # WB GPIO always port0
+ m.d.comb += iomux.periph_ports[0].o.eq(gpio.gpio_ports[0].o)
+ m.d.comb += iomux.periph_ports[0].oe.eq(gpio.gpio_ports[0].oe)
+ m.d.comb += gpio.gpio_ports[0].i.eq(iomux.periph_ports[0].i)
- # banks1-3 external
- for bank in range(0, self.n_banks-1):
- m.d.comb += iomux.bank_ports[bank+1].o.eq(periph_ports[bank].o)
- m.d.comb += iomux.bank_ports[bank+1].oe.eq(periph_ports[bank].oe)
- m.d.comb += periph_ports[bank].i.eq(iomux.bank_ports[bank+1].i)
+ # ports1-3 external
+ for port in range(0, self.n_ports-1):
+ m.d.comb += iomux.periph_ports[port+1].o.eq(periph_ports[port].o)
+ m.d.comb += iomux.periph_ports[port+1].oe.eq(periph_ports[port].oe)
+ m.d.comb += periph_ports[port].i.eq(iomux.periph_ports[port+1].i)
m.d.comb += pad_port.o.eq(iomux.out_port.o)
m.d.comb += pad_port.oe.eq(iomux.out_port.oe)
yield field
for field in self.bus.fields.values():
yield field
- for bank in range(len(self.periph_ports)):
- for field in self.periph_ports[bank].fields.values():
+ for port in range(len(self.periph_ports)):
+ for field in self.periph_ports[port].fields.values():
yield field
def ports(self):
return list(self)
-def gen_gtkw_doc(module_name, wordsize, n_banks, filename, pinspec):
+def gen_gtkw_doc(module_name, wordsize, n_ports, filename, pinspec):
# GTKWave doc generation
style = {
'': {'base': 'hex'},
])
traces.append(wb_traces)
- for bank in range(0, n_banks):
- temp_traces = ('mux%d' % bank, [
- ('%s__i' % (pinspec["mux%d" % bank]), 'in'),
- ('%s__o' % (pinspec["mux%d" % bank]), 'in'),
- ('%s__oe' % (pinspec["mux%d" % bank]), 'in')
+ for port in range(0, n_ports):
+ temp_traces = ('mux%d' % port, [
+ ('%s__i' % (pinspec["mux%d" % port]), 'in'),
+ ('%s__o' % (pinspec["mux%d" % port]), 'in'),
+ ('%s__oe' % (pinspec["mux%d" % port]), 'in')
])
traces.append(temp_traces)
temp_traces = ('Misc', [
- ('bank[%d:0]' % ((n_banks-1).bit_length()-1), 'in')
+ ('port[%d:0]' % ((n_ports-1).bit_length()-1), 'in')
])
traces.append(temp_traces)
temp_traces = ('IO port to pad named: %s' % pinspec["name"], [
with sim_writer:
sim.run()
- gen_gtkw_doc("top.pinmux", wb_wordsize, dut.n_banks, filename,
+ gen_gtkw_doc("top.pinmux", wb_wordsize, dut.n_ports, filename,
dummy_pinspec)
def test_gpio_pinmux(dut):
print("------START----------------------")
- #print(dir(dut.bank_ports[0]))
- #print(dut.bank_ports[0].fields)
+ #print(dir(dut.periph_ports[0]))
+ #print(dut.periph_ports[0].fields)
gpios = GPIOManager(dut.gpio, csrbus_layout, dut.bus)
puen = 0
pden = 1
outval = 0
- bank = 0
+ port = 0
yield from gpios.config("0", oe=1, ie=0, puen=0, pden=1, outval=0, bank=0)
yield from gpios.set_out("0", outval=1)
uart_tx_layout = (("o", 1),
("oe", 1)
)
-GPIO_BANK = 0
-UART_BANK = 1
-I2C_BANK = 2
+GPIO_MUX = 0
+UART_MUX = 1
+I2C_MUX = 2
"""
Really basic example, uart tx/rx and i2c sda/scl pinmux
print("Test Manual Pinmux!")
self.requested = requested
- self.n_banks = 4
- self.bank = Signal(log2_int(self.n_banks))
+ self.n_ports = 4
+ self.port = Signal(log2_int(self.n_ports))
self.pads = {}
self.muxes = {}
# Automatically create the necessary periph/pad Records/Signals
for pad in self.requested.keys():
self.pads[pad] = {}
self.pads[pad]["pad"] = Record(name=pad, layout=io_layout)
- self.muxes[pad] = IOMuxBlockSingle(self.n_banks)
+ self.muxes[pad] = IOMuxBlockSingle(self.n_ports)
for mux in self.requested[pad].keys():
periph = self.requested[pad][mux][0]
unit = self.requested[pad][mux][1]
m = Module()
comb, sync = m.d.comb, m.d.sync
muxes = self.muxes
- bank = self.bank
+ port = self.port
pads = self.pads
for pad in pads.keys():
m.submodules[pad+"_mux"] = muxes[pad]
# all muxes controlled by the same multi-bit signal
- comb += muxes[pad].bank.eq(bank)
+ comb += muxes[pad].port.eq(port)
# print(self.requested)
# print(self.pads)
# ---------------------------
- # This section connects the periphs to the assigned banks
+ # This section connects the periphs to the assigned ports
# ---------------------------
for pad in pads.keys():
for mux in self.requested[pad].keys():
sig = self.requested[pad][mux][2][:-1]
sig_type = iotypes[self.requested[pad][mux][2][-1]]
if sig_type == iotypes['*']:
- comb += muxes[pad].bank_ports[num].o.eq(pads[pad][mux].o)
- comb += muxes[pad].bank_ports[num].oe.eq(pads[pad][mux].oe)
- comb += pads[pad][mux].i.eq(muxes[pad].bank_ports[num].i)
+ comb += muxes[pad].periph_ports[num].o.eq(pads[pad][mux].o)
+ comb += muxes[pad].periph_ports[num].oe.eq(
+ pads[pad][mux].oe)
+ comb += pads[pad][mux].i.eq(muxes[pad].periph_ports[num].i)
elif sig_type == iotypes['+']:
- comb += muxes[pad].bank_ports[num].o.eq(pads[pad][mux])
+ comb += muxes[pad].periph_ports[num].o.eq(pads[pad][mux])
elif sig_type == iotypes['-']:
- comb += pads[pad][mux].eq(muxes[pad].bank_ports[num].i)
+ comb += pads[pad][mux].eq(muxes[pad].periph_ports[num].i)
# ---------------------------
# Here is where the muxes are assigned to the actual pads
# ---------------------------
else:
for field in self.pads[pad][mux].fields.values():
yield field
- yield self.bank
+ yield self.port
def ports(self):
return list(self)
-def set_bank(dut, bank, delay=1e-6):
- yield dut.bank.eq(bank)
+def set_port(dut, port, delay=1e-6):
+ yield dut.port.eq(port)
yield Delay(delay)
"""
# Test the GPIO/UART/I2C connectivity
def test_man_pinmux(dut, requested):
# TODO: Convert to automatic
- # [{"pad":%s, "bank":%d}, {"pad":%s, "bank":%d},...]
- #gpios = [{"padname":"N1", "bank":GPIO_BANK},
- # {"padname":"N2", "bank":GPIO_BANK}]
- # [[txPAD, MUXx, rxPAD, MUXx],...] - diff banks not supported yet
- uarts = [{"txpadname":"N1", "rxpadname":"N2", "bank":UART_BANK}]
- # [[sdaPAD, MUXx, sclPAD, MUXx],...] - diff banks not supported yet
- i2cs = [{"sdapadname":"N1", "sclpadname":"N2", "bank":I2C_BANK}]
+ # [{"pad":%s, "port":%d}, {"pad":%s, "port":%d},...]
+ #gpios = [{"padname":"N1", "port":GPIO_MUX},
+ # {"padname":"N2", "port":GPIO_MUX}]
+ # [[txPAD, MUXx, rxPAD, MUXx],...] - diff ports not supported yet
+ uarts = [{"txpadname":"N1", "rxpadname":"N2", "mux":UART_MUX}]
+ # [[sdaPAD, MUXx, sclPAD, MUXx],...] - diff ports not supported yet
+ i2cs = [{"sdapadname":"N1", "sclpadname":"N2", "mux":I2C_MUX}]
gpios = []
delay = 1e-6
periph = requested[pad][mux][0]
if periph == "gpio":
- # [{"padname":%s, "bank": %d}, ...]
- gpios.append({"padname":pad, "bank": int(mux[3])})
+ # [{"padname":%s, "port": %d}, ...]
+ gpios.append({"padname":pad, "mux": int(mux[3])})
if periph == "uart":
# TODO:
pass
# GPIO test
for gpio_periph in gpios:
padname = gpio_periph["padname"]
- gpio_bank = gpio_periph["bank"]
- gp = dut.pads[padname]["mux%d" % gpio_bank]
+ gpio_port = gpio_periph["mux"]
+ gp = dut.pads[padname]["mux%d" % gpio_port]
pad = dut.pads[padname]["pad"]
- yield from set_bank(dut, gpio_bank)
+ yield from set_port(dut, gpio_port)
yield from gpio(gp, pad, 0x5a5)
# UART test
for uart_periph in uarts:
txpadname = uart_periph["txpadname"]
rxpadname = uart_periph["rxpadname"]
- uart_bank = uart_periph["bank"]
- tx = dut.pads[txpadname]["mux%d" % uart_bank]
- rx = dut.pads[rxpadname]["mux%d" % uart_bank]
+ uart_port = uart_periph["mux"]
+ tx = dut.pads[txpadname]["mux%d" % uart_port]
+ rx = dut.pads[rxpadname]["mux%d" % uart_port]
txpad = dut.pads[txpadname]["pad"]
rxpad = dut.pads[rxpadname]["pad"]
- yield from set_bank(dut, UART_BANK)
+ yield from set_port(dut, UART_MUX)
yield from uart_send(tx, rx, txpad, rxpad, 0x42)
# I2C test
for i2c_periph in i2cs:
sdapadname = i2c_periph["sdapadname"]
sclpadname = i2c_periph["sclpadname"]
- i2c_bank = i2c_periph["bank"]
- sda = dut.pads[sdapadname]["mux%d" % i2c_bank]
- scl = dut.pads[sclpadname]["mux%d" % i2c_bank]
+ i2c_port = i2c_periph["mux"]
+ sda = dut.pads[sdapadname]["mux%d" % i2c_port]
+ scl = dut.pads[sclpadname]["mux%d" % i2c_port]
sdapad = dut.pads[sdapadname]["pad"]
- yield from set_bank(dut, I2C_BANK)
+ yield from set_port(dut, I2C_MUX)
yield from i2c_send(sda, scl, sdapad, 0x67)
def gen_gtkw_doc(module_name, requested, filename):
# Create a trace list, each block expected to be a tuple()
traces = []
temp = 0
- n_banks = 0
+ n_ports = 0
for pad in requested.keys():
temp = len(requested[pad].keys())
- if n_banks < temp:
- n_banks = temp
+ if n_ports < temp:
+ n_ports = temp
temp_traces = ("Pad %s" % pad, [])
# Pad signals
temp_traces[1].append(('%s__i' % pad, 'in'))
temp_traces[1].append(('%s%d__oe' % (pin, unit_num), 'out'))
traces.append(temp_traces)
- # master bank signal
+ # master port signal
temp_traces = ('Misc', [
- ('bank[%d:0]' % ((n_banks-1).bit_length()-1), 'in')
+ ('port[%d:0]' % ((n_ports-1).bit_length()-1), 'in')
])
traces.append(temp_traces)
def sim_man_pinmux():
filename = "test_man_pinmux"
- requested = {"N1": {"mux%d" % GPIO_BANK: ["gpio", 0, '0*'],
- "mux%d" % UART_BANK: ["uart", 0, 'tx+'],
- "mux%d" % I2C_BANK: ["i2c", 0, 'sda*']},
- "N2": {"mux%d" % GPIO_BANK: ["gpio", 1, '*'],
- "mux%d" % UART_BANK: ["uart", 0, 'rx-'],
- "mux%d" % I2C_BANK: ["i2c", 0, 'scl*']},
- "N3": {"mux%d" % GPIO_BANK: ["gpio", 2, '0*']},
- "N4": {"mux%d" % GPIO_BANK: ["gpio", 3, '0*']}
+ requested = {"N1": {"mux%d" % GPIO_MUX: ["gpio", 0, '0*'],
+ "mux%d" % UART_MUX: ["uart", 0, 'tx+'],
+ "mux%d" % I2C_MUX: ["i2c", 0, 'sda*']},
+ "N2": {"mux%d" % GPIO_MUX: ["gpio", 1, '*'],
+ "mux%d" % UART_MUX: ["uart", 0, 'rx-'],
+ "mux%d" % I2C_MUX: ["i2c", 0, 'scl*']},
+ "N3": {"mux%d" % GPIO_MUX: ["gpio", 2, '0*']},
+ "N4": {"mux%d" % GPIO_MUX: ["gpio", 3, '0*']}
}
dut = ManPinmux(requested)
vl = rtlil.convert(dut, ports=dut.ports())
#function_names = []
#testspec = PinSpec()
pinbanks = {
- 'A': (4, 4), # (num of pads, num of banks)?
+ 'A': (4, 4), # bankname: (num of pins, muxwidth)
#'B': (18, 4),
#'C': (24, 1),
#'D': (93, 1),
print(dir(ps.gpio))
#print(ps.gpio.pinouts, ps.gpio.bankspec, ps.gpio.pinfn, ps.gpio.fname)
"""
- desc_dict_keys = ['UART0', 'TWI0', 'GPIOA_A0', 'GPIOA_A1', 'GPIOA_A2', 'GPIOA_A3']
+ desc_dict_keys = ['UART0', 'TWI0', 'GPIOA_A0', 'GPIOA_A1', 'GPIOA_A2',
+ 'GPIOA_A3']
eint = []
pwm = []
desc = {'UART0': 'Basic serial TX/RX serial port',