from nmigen_soc.memory import MemoryMap
from nmigen.utils import log2_int
from nmigen.cli import rtlil, verilog
+from nmutil.byterev import byte_reverse
import os
__all__ = ["Tercel"]
# TODO, sort this out.
assert clk_freq is not None
clk_freq = round(clk_freq)
- self.clk_freq = Const(clk_freq, clk_freq.bit_length())
+ self.clk_freq = Const(clk_freq, 32) #clk_freq.bit_length())
# set up the wishbone busses
if features is None:
+ #features = frozenset({'err'}) # sigh
features = frozenset()
if bus is None:
bus = Interface(addr_width=spi_region_addr_width,
self.dq_in = Signal(4)
self.cs_n_out = Signal() # Slave select
self.spi_clk = Signal() # Clock
+ self.dbg_port = Signal(8) # debug info
# pins resource
self.pins = pins
# wb address is in words, offset is in bytes
comb += spi_bus_adr.eq(bus.adr - (self.adr_offset >> 2))
+ # urrr.... byte-reverse the config bus and data bus read/write
+ cdat_w = Signal.like(cfg_bus.dat_w)
+ cdat_r = Signal.like(cfg_bus.dat_r)
+ dat_w = Signal.like(bus.dat_w)
+ dat_r = Signal.like(bus.dat_r)
+ comb += cdat_w.eq(byte_reverse(m, "rv_cdat_w", cfg_bus.dat_w, 4))
+ comb += cfg_bus.dat_r.eq(byte_reverse(m, "rv_cdat_r", cdat_r, 4))
+ comb += dat_w.eq(byte_reverse(m, "rv_dat_w", bus.dat_w, 4))
+ comb += bus.dat_r.eq(byte_reverse(m, "rv_dat_r", dat_r, 4))
+
# create definition of external verilog Tercel code here, so that
# nmigen understands I/O directions (defined by i_ and o_ prefixes)
idx, bus = self.idx, self.bus
i_peripheral_reset=ResetSignal(),
# SPI region Wishbone bus signals
- i_wishbone_adr_i=spi_bus_adr,
- i_wishbone_dat_i=bus.dat_w,
- i_wishbone_sel_i=bus.sel,
- o_wishbone_dat_o=bus.dat_r,
- i_wishbone_we_i=bus.we,
- i_wishbone_stb_i=bus.stb,
- i_wishbone_cyc_i=bus.cyc,
- o_wishbone_ack_o=bus.ack,
+ i_wishbone_adr=spi_bus_adr,
+ i_wishbone_dat_w=dat_w,
+ i_wishbone_sel=bus.sel,
+ o_wishbone_dat_r=dat_r,
+ i_wishbone_we=bus.we,
+ i_wishbone_stb=bus.stb,
+ i_wishbone_cyc=bus.cyc,
+ o_wishbone_ack=bus.ack,
+ #o_wishbone_err=bus.err,
# Configuration region Wishbone bus signals
- i_cfg_wishbone_adr_i=cfg_bus.adr,
- i_cfg_wishbone_dat_i=cfg_bus.dat_w,
- i_cfg_wishbone_sel_i=cfg_bus.sel,
- o_cfg_wishbone_dat_o=cfg_bus.dat_r,
- i_cfg_wishbone_we_i=cfg_bus.we,
- i_cfg_wishbone_stb_i=cfg_bus.stb,
- i_cfg_wishbone_cyc_i=cfg_bus.cyc,
- o_cfg_wishbone_ack_o=cfg_bus.ack,
+ i_cfg_wishbone_adr=cfg_bus.adr,
+ i_cfg_wishbone_dat_w=cdat_w,
+ i_cfg_wishbone_sel=cfg_bus.sel,
+ o_cfg_wishbone_dat_r=cdat_r,
+ i_cfg_wishbone_we=cfg_bus.we,
+ i_cfg_wishbone_stb=cfg_bus.stb,
+ i_cfg_wishbone_cyc=cfg_bus.cyc,
+ o_cfg_wishbone_ack=cfg_bus.ack,
+ #o_cfg_wishbone_err=cfg_bus.err,
# QSPI signals
o_spi_d_out=self.dq_out,
o_spi_d_direction=self.dq_direction,
i_spi_d_in=self.dq_in,
o_spi_ss_n=self.cs_n_out,
- o_spi_clock=self.spi_clk
+ o_spi_clock=self.spi_clk,
+
+ # debug port
+ o_debug_port=self.dbg_port
);
m.submodules['tercel_%d' % self.idx] = tercel
comb += pins.cs.eq(~self.cs_n_out)
# ECP5 needs special handling for the SPI clock, sigh.
if self.lattice_ecp5_usrmclk:
- self.specials += Instance("USRMCLK",
+ m.submodules += Instance("USRMCLK",
i_USRMCLKI = self.spi_clk,
i_USRMCLKTS = 0
)
return m
+ def ports(self):
+ return [self.bus.cyc, self.bus.stb, self.bus.ack,
+ self.bus.dat_r, self.bus.dat_w, self.bus.adr,
+ self.bus.we, self.bus.sel,
+ self.cfg_bus.cyc, self.cfg_bus.stb,
+ self.cfg_bus.ack,
+ self.cfg_bus.dat_r, self.cfg_bus.dat_w,
+ self.cfg_bus.adr,
+ self.cfg_bus.we, self.cfg_bus.sel,
+ self.dq_out, self.dq_direction, self.dq_in,
+ self.cs_n_out, self.spi_clk
+ ]
+
def create_ilang(dut, ports, test_name):
vl = rtlil.convert(dut, name=test_name, ports=ports)
if __name__ == "__main__":
tercel = Tercel(name="spi_0", data_width=32, clk_freq=100e6)
- create_ilang(tercel, [tercel.bus.cyc, tercel.bus.stb, tercel.bus.ack,
- tercel.bus.dat_r, tercel.bus.dat_w, tercel.bus.adr,
- tercel.bus.we, tercel.bus.sel,
- tercel.cfg_bus.cyc, tercel.cfg_bus.stb,
- tercel.cfg_bus.ack,
- tercel.cfg_bus.dat_r, tercel.cfg_bus.dat_w,
- tercel.cfg_bus.adr,
- tercel.cfg_bus.we, tercel.cfg_bus.sel,
- tercel.dq_out, tercel.dq_direction, tercel.dq_in,
- tercel.cs_n_out, tercel.spi_clk
- ], "spi_0")
+ create_ilang(tercel, tercel.ports(), "spi_0")