def __init__(self, bits_sign=None, name=None, variable=False, reset=0, name_override=None, min=None, max=None, related=None): from migen.fhdl.bitcontainer import bits_for Value.__init__(self) # determine number of bits and signedness if bits_sign is None: if min is None: min = 0 if max is None: max = 2 max -= 1 # make both bounds inclusive assert(min < max) self.signed = min < 0 or max < 0 self.nbits = builtins.max(bits_for(min, self.signed), bits_for(max, self.signed)) else: assert(min is None and max is None) if isinstance(bits_sign, tuple): self.nbits, self.signed = bits_sign else: self.nbits, self.signed = bits_sign, False if not isinstance(self.nbits, int) or self.nbits <= 0: raise ValueError("Signal width must be a strictly positive integer") self.variable = variable # deprecated self.reset = reset self.name_override = name_override self.backtrace = tracer.trace_back(name) self.related = related
def _printintbool(node): if isinstance(node, bool): if node: return "1'd1", False else: return "1'd0", False elif isinstance(node, int): if node >= 0: return str(bits_for(node)) + "'d" + str(node), False else: nbits = bits_for(node) return str(nbits) + "'sd" + str(2**nbits + node), True else: raise TypeError
def __init__(self, bits_sign=None, name=None, variable=False, reset=0, name_override=None, min=None, max=None, related=None, attr=None): from migen.fhdl.bitcontainer import bits_for _Value.__init__(self) # determine number of bits and signedness if bits_sign is None: if min is None: min = 0 if max is None: max = 2 max -= 1 # make both bounds inclusive assert (min < max) self.signed = min < 0 or max < 0 self.nbits = _builtins.max(bits_for(min, self.signed), bits_for(max, self.signed)) else: assert (min is None and max is None) if isinstance(bits_sign, tuple): self.nbits, self.signed = bits_sign else: self.nbits, self.signed = bits_sign, False if isinstance(reset, (bool, int)): reset = Constant(reset, (self.nbits, self.signed)) if not isinstance(self.nbits, int) or self.nbits <= 0: raise ValueError( "Signal width must be a strictly positive integer") if attr is None: attr = set() self.variable = variable # deprecated self.reset = reset self.name_override = name_override self.backtrace = _tracer.trace_back(name) self.related = related self.attr = attr
def __init__(self, bits_sign=None, name=None, variable=False, reset=0, reset_less=False, name_override=None, min=None, max=None, related=None, attr=None): from migen.fhdl.bitcontainer import bits_for super().__init__() for n in [name, name_override]: if n is not None and not self._name_re.match(n): raise ValueError( "Signal name {} is not a valid Python identifier" .format(repr(n))) # determine number of bits and signedness if bits_sign is None: if min is None: min = 0 if max is None: max = 2 max -= 1 # make both bounds inclusive assert(min < max) self.signed = min < 0 or max < 0 self.nbits = _builtins.max( bits_for(min, self.signed), bits_for(max, self.signed)) else: assert(min is None and max is None) if isinstance(bits_sign, tuple): self.nbits, self.signed = bits_sign else: self.nbits, self.signed = bits_sign, False if isinstance(reset, (bool, int)): reset = Constant(reset, (self.nbits, self.signed)) if not isinstance(self.nbits, int) or self.nbits <= 0: raise ValueError( "Signal width must be a strictly positive integer") if attr is None: attr = set() self.variable = variable # deprecated self.reset = reset self.reset_less = reset_less self.name_override = name_override self.backtrace = _tracer.trace_back(name) self.related = related self.attr = attr
def __init__(self, t): self.wait = Signal() self.done = Signal() # # # count = Signal(bits_for(t), reset=t) self.comb += self.done.eq(count == 0) self.sync += \ If(self.wait, If(~self.done, count.eq(count - 1)) ).Else(count.eq(count.reset))
def __init__(self, value, bits_sign=None): from migen.fhdl.bitcontainer import bits_for super().__init__() self.value = int(value) if bits_sign is None: bits_sign = bits_for(self.value), self.value < 0 elif isinstance(bits_sign, int): bits_sign = bits_sign, self.value < 0 self.nbits, self.signed = bits_sign if not isinstance(self.nbits, int) or self.nbits <= 0: raise TypeError("Width must be a strictly positive integer")
def __init__(self, bits_sign=None, name=None, variable=False, reset=0, name_override=None, min=None, max=None, related=None): from migen.fhdl.bitcontainer import bits_for Value.__init__(self) # determine number of bits and signedness if bits_sign is None: if min is None: min = 0 if max is None: max = 2 max -= 1 # make both bounds inclusive assert (min < max) self.signed = min < 0 or max < 0 self.nbits = builtins.max(bits_for(min, self.signed), bits_for(max, self.signed)) else: assert (min is None and max is None) if isinstance(bits_sign, tuple): self.nbits, self.signed = bits_sign else: self.nbits, self.signed = bits_sign, False assert (isinstance(self.nbits, int)) self.variable = variable # deprecated self.reset = reset self.name_override = name_override self.backtrace = tracer.trace_back(name) self.related = related
def __init__(self): class PORT(Module): def __init__(self, aw, dw): self.adr = Signal(aw) self.dat_w = Signal(dw) self.we = Signal(1) import array self.mem = array.array('B', [0] * 2**aw) def do_simulation(self, s): writing, w_addr, w_data = s.multiread( [self.we, self.adr, self.dat_w]) if writing: assert w_addr < 1024 self.mem[w_addr] = w_data self.submodules.port = PORT(bits_for(1024), 8) def _deferred_source_gen(): yield yield from self.src_gen def _deferred_sink_gen(): yield yield from self.sink_gen class SimSource(SimActor): def __init__(self): self.source = Source(ULPI_DATA_TAG) SimActor.__init__(self, _deferred_source_gen()) class SimDMASink(SimActor): def __init__(self): self.sink = Sink(dmatpl(1024)) SimActor.__init__(self, _deferred_sink_gen()) self.consume_watermark = Signal(max=1024) self.submodules.src = SimSource() self.submodules.p = Producer(self.port, 1024, self.consume_watermark, 1) self.comb += self.p.ulpi_sink.connect(self.src.source) self.comb += self.src.busy.eq(0) self.submodules.dmp = SimDMASink() self.comb += self.p.out_addr.connect(self.dmp.sink) self.comb += self.dmp.busy.eq(0)
def __init__(self): class PORT(Module): def __init__(self, aw, dw): self.adr = Signal(aw) self.dat_w = Signal(dw) self.we = Signal(1) import array self.mem = array.array('B', [0] * 2**aw) def do_simulation(self, selfp): writing, w_addr, w_data = selfp.we, selfp.adr, selfp.dat_w if writing: assert w_addr < 1024 self.mem[w_addr] = w_data self.submodules.port = PORT(bits_for(1024), 8) def _deferred_source_gen(): yield yield from self.src_gen def _deferred_sink_gen(): yield yield from self.sink_gen class SimSource(SimActor): def __init__(self): self.source = Source(ULPI_DATA_TAG) SimActor.__init__(self, _deferred_source_gen()) class SimDMASink(SimActor): def __init__(self): self.sink = Sink(dmatpl(1024)) SimActor.__init__(self, _deferred_sink_gen()) self.consume_watermark =Signal(max=1024) self.submodules.src = SimSource() self.submodules.p = Producer(self.port, 1024, self.consume_watermark, 1) self.comb += self.p.ulpi_sink.connect(self.src.source) self.comb += self.src.busy.eq(0) self.submodules.dmp = SimDMASink() self.comb += self.p.out_addr.connect(self.dmp.sink) self.comb += self.dmp.busy.eq(0)
def emit_verilog(memory, ns, add_data_file): r = "" def gn(e): if isinstance(e, Memory): return ns.get_name(e) else: return verilog_printexpr(ns, e)[0] adrbits = bits_for(memory.depth-1) r += "reg [" + str(memory.width-1) + ":0] " \ + gn(memory) \ + "[0:" + str(memory.depth-1) + "];\n" adr_regs = {} data_regs = {} for port in memory.ports: if not port.async_read: if port.mode == WRITE_FIRST: adr_reg = Signal(name_override="memadr") r += "reg [" + str(adrbits-1) + ":0] " \ + gn(adr_reg) + ";\n" adr_regs[id(port)] = adr_reg else: data_reg = Signal(name_override="memdat") r += "reg [" + str(memory.width-1) + ":0] " \ + gn(data_reg) + ";\n" data_regs[id(port)] = data_reg for port in memory.ports: r += "always @(posedge " + gn(port.clock) + ") begin\n" if port.we is not None: if port.we_granularity: n = memory.width//port.we_granularity for i in range(n): m = i*port.we_granularity M = (i+1)*port.we_granularity-1 sl = "[" + str(M) + ":" + str(m) + "]" r += "\tif (" + gn(port.we) + "[" + str(i) + "])\n" r += "\t\t" + gn(memory) + "[" + gn(port.adr) + "]" + sl + " <= " + gn(port.dat_w) + sl + ";\n" else: r += "\tif (" + gn(port.we) + ")\n" r += "\t\t" + gn(memory) + "[" + gn(port.adr) + "] <= " + gn(port.dat_w) + ";\n" if not port.async_read: if port.mode == WRITE_FIRST: rd = "\t" + gn(adr_regs[id(port)]) + " <= " + gn(port.adr) + ";\n" else: bassign = gn(data_regs[id(port)]) + " <= " + gn(memory) + "[" + gn(port.adr) + "];\n" if port.mode == READ_FIRST: rd = "\t" + bassign elif port.mode == NO_CHANGE: rd = "\tif (!" + gn(port.we) + ")\n" \ + "\t\t" + bassign if port.re is None: r += rd else: r += "\tif (" + gn(port.re) + ")\n" r += "\t" + rd.replace("\n\t", "\n\t\t") r += "end\n\n" for port in memory.ports: if port.async_read: r += "assign " + gn(port.dat_r) + " = " + gn(memory) + "[" + gn(port.adr) + "];\n" else: if port.mode == WRITE_FIRST: r += "assign " + gn(port.dat_r) + " = " + gn(memory) + "[" + gn(adr_regs[id(port)]) + "];\n" else: r += "assign " + gn(port.dat_r) + " = " + gn(data_regs[id(port)]) + ";\n" r += "\n" if memory.init is not None: content = "" for d in memory.init: content += "{:x}\n".format(d) memory_filename = add_data_file(gn(memory) + ".init", content) r += "initial begin\n" r += "\t$readmemh(\"" + memory_filename + "\", " + gn(memory) + ");\n" r += "end\n\n" return r
def __init__(self, platform, pads, size=2 * 1024 * 1024): self.intro = ModuleDoc( "See https://github.com/cliffordwolf/picorv32/tree/master/picosoc#spi-flash-controller-config-register" ) self.size = size self.bus = bus = wishbone.Interface() self.reset = Signal() self.cfg1 = CSRStorage(size=8) self.cfg2 = CSRStorage(size=8) self.cfg3 = CSRStorage( size=8, reset=0x24 ) # set 1 for qspi (bit 21); lower 4 bits is "dummy" cycles self.cfg4 = CSRStorage(size=8) self.stat = CSRStatus(size=32) cfg = Signal(32) cfg_we = Signal(4) cfg_out = Signal(32) # Add pulse the cfg_we line after reset reset_counter = Signal(2, reset=3) ic_reset = Signal(reset=1) self.sync += \ If(reset_counter != 0, reset_counter.eq(reset_counter - 1) ).Else( ic_reset.eq(0) ) self.comb += [ cfg.eq( Cat(self.cfg1.storage, self.cfg2.storage, self.cfg3.storage, self.cfg4.storage)), cfg_we.eq( Cat(self.cfg1.re, self.cfg2.re, self.cfg3.re | ic_reset, self.cfg4.re)), self.stat.status.eq(cfg_out), ] copi_pad = TSTriple() cipo_pad = TSTriple() cs_n_pad = TSTriple() clk_pad = TSTriple() wp_pad = TSTriple() hold_pad = TSTriple() self.specials += copi_pad.get_tristate(pads.copi) self.specials += cipo_pad.get_tristate(pads.cipo) self.specials += cs_n_pad.get_tristate(pads.cs_n) self.specials += clk_pad.get_tristate(pads.clk) self.specials += wp_pad.get_tristate(pads.wp) self.specials += hold_pad.get_tristate(pads.hold) reset = Signal() self.comb += [ reset.eq(ResetSignal() | self.reset), cs_n_pad.oe.eq(~reset), clk_pad.oe.eq(~reset), ] flash_addr = Signal(24) # size/4 because data bus is 32 bits wide, -1 for base 0 mem_bits = bits_for(int(size / 4) - 1) pad = Signal(2) self.comb += flash_addr.eq(Cat(pad, bus.adr[0:mem_bits - 1])) read_active = Signal() spi_ready = Signal() self.sync += [ If( bus.stb & bus.cyc & ~read_active, read_active.eq(1), bus.ack.eq(0), ).Elif( read_active & spi_ready, read_active.eq(0), bus.ack.eq(1), ).Else( bus.ack.eq(0), read_active.eq(0), ) ] o_rdata = Signal(32) self.comb += bus.dat_r.eq(o_rdata) self.specials += Instance( "spimemio", o_flash_io0_oe=copi_pad.oe, o_flash_io1_oe=cipo_pad.oe, o_flash_io2_oe=wp_pad.oe, o_flash_io3_oe=hold_pad.oe, o_flash_io0_do=copi_pad.o, o_flash_io1_do=cipo_pad.o, o_flash_io2_do=wp_pad.o, o_flash_io3_do=hold_pad.o, o_flash_csb=cs_n_pad.o, o_flash_clk=clk_pad.o, i_flash_io0_di=copi_pad.i, i_flash_io1_di=cipo_pad.i, i_flash_io2_di=wp_pad.i, i_flash_io3_di=hold_pad.i, i_resetn=~reset, i_clk=ClockSignal(), i_valid=bus.stb & bus.cyc, o_ready=spi_ready, i_addr=flash_addr, o_rdata=o_rdata, i_cfgreg_we=cfg_we, i_cfgreg_di=cfg, o_cfgreg_do=cfg_out, ) platform.add_source("rtl/spimemio.v")
def __init__(self, platform, pads, size=16 * 1024 * 1024): self.size = size self.bus = bus = wishbone.Interface() self.reset = Signal() self.cfg1 = CSRStorage(fields=[ CSRField( "bb_out", size=4, description="Output bits in bit-bang mode"), CSRField("bb_clk", description="Serial clock line in bit-bang mode"), CSRField("bb_cs", description="Chip select line in bit-bang mode"), ]) self.cfg2 = CSRStorage(fields=[ CSRField("bb_oe", size=4, description="Output Enable bits in bit-bang mode"), ]) self.cfg3 = CSRStorage(fields=[ CSRField( "rlat", size=4, description="Read latency/dummy cycle count"), CSRField("crm", description="Continuous Read Mode enable bit"), CSRField("qspi", description="Quad-SPI enable bit"), CSRField("ddr", description="Double Data Rate enable bit"), ]) self.cfg4 = CSRStorage(fields=[ CSRField( "memio", offset=7, reset=1, description= "Enable memory-mapped mode (set to 0 to enable bit-bang mode)") ]) self.stat1 = CSRStatus(fields=[ CSRField( "bb_in", size=4, description="Input bits in bit-bang mode"), ]) self.stat2 = CSRStatus(8, description="Reserved") self.stat3 = CSRStatus(8, description="Reserved") self.stat4 = CSRStatus(8, description="Reserved") cfg = Signal(32) cfg_we = Signal(4) cfg_out = Signal(32) self.comb += [ cfg.eq( Cat(self.cfg1.storage, self.cfg2.storage, self.cfg3.storage, self.cfg4.storage)), cfg_we.eq( Cat(self.cfg1.re, self.cfg2.re, self.cfg3.re, self.cfg4.re)), self.stat1.status.eq(cfg_out[0:4]), self.stat2.status.eq(0), self.stat3.status.eq(0), self.stat4.status.eq(0), ] reset = Signal() mosi_pad = TSTriple() miso_pad = TSTriple() cs_n_pad = TSTriple() clk_pad = TSTriple() wp_pad = TSTriple() hold_pad = TSTriple() clk = Signal() if hasattr(pads, "clk"): clk = pads.clk self.specials += clk_pad.get_tristate(clk) self.comb += clk_pad.oe.eq(~reset) else: self.specials += Instance("USRMCLK", i_USRMCLKI=clk, i_USRMCLKTS=0) self.specials += mosi_pad.get_tristate(pads.mosi) self.specials += miso_pad.get_tristate(pads.miso) self.specials += cs_n_pad.get_tristate(pads.cs_n) self.specials += wp_pad.get_tristate(pads.wp) self.specials += hold_pad.get_tristate(pads.hold) self.comb += [ reset.eq(ResetSignal() | self.reset), cs_n_pad.oe.eq(~reset), ] flash_addr = Signal(24) # size/4 because data bus is 32 bits wide, -1 for base 0 mem_bits = bits_for(int(size / 4) - 1) pad = Signal(2) self.comb += flash_addr.eq(Cat(pad, bus.adr[0:mem_bits - 1])) read_active = Signal() spi_ready = Signal() self.sync += [ If( bus.stb & bus.cyc & ~read_active, read_active.eq(1), bus.ack.eq(0), ).Elif( read_active & spi_ready, read_active.eq(0), bus.ack.eq(1), ).Else( bus.ack.eq(0), read_active.eq(0), ) ] o_rdata = Signal(32) self.comb += bus.dat_r.eq(o_rdata) self.specials += Instance( "spimemio", o_flash_io0_oe=mosi_pad.oe, o_flash_io1_oe=miso_pad.oe, o_flash_io2_oe=wp_pad.oe, o_flash_io3_oe=hold_pad.oe, o_flash_io0_do=mosi_pad.o, o_flash_io1_do=miso_pad.o, o_flash_io2_do=wp_pad.o, o_flash_io3_do=hold_pad.o, o_flash_csb=cs_n_pad.o, o_flash_clk=clk, i_flash_io0_di=mosi_pad.i, i_flash_io1_di=miso_pad.i, i_flash_io2_di=wp_pad.i, i_flash_io3_di=hold_pad.i, i_resetn=~reset, i_clk=ClockSignal(), i_valid=bus.stb & bus.cyc, o_ready=spi_ready, i_addr=flash_addr, o_rdata=o_rdata, i_cfgreg_we=cfg_we, i_cfgreg_di=cfg, o_cfgreg_do=cfg_out, ) platform.add_source("rtl/spimemio.v")
def __init__(self, platform, pads, size=2*1024*1024): self.intro = ModuleDoc("See https://github.com/cliffordwolf/picorv32/tree/master/picosoc#spi-flash-controller-config-register; used with modifications") self.size = size self.bus = bus = wishbone.Interface() self.reset = Signal() cfg = Signal(32) cfg_we = Signal(4) cfg_out = Signal(32) # Add pulse the cfg_we line after reset reset_counter = Signal(2, reset=3) ic_reset = Signal(reset=1) self.sync += \ If(reset_counter != 0, reset_counter.eq(reset_counter - 1) ).Else( ic_reset.eq(0) ) self.rdata = CSRStatus(fields=[ CSRField("data", size=4, description="Data bits from SPI [3:hold, 2:wp, 1:cipo, 0:copi]"), ]) self.mode = CSRStorage(fields=[ CSRField("bitbang", size=1, description="Turn on bitbang mode", reset = 0), CSRField("csn", size=1, description="Chip select (set to `0` to select the chip)"), ]) self.wdata = CSRStorage(description="Writes to this field automatically pulse CLK", fields=[ CSRField("data", size=4, description="Data bits to SPI [3:hold, 2:wp, 1:cipo, 0:copi]"), CSRField("oe", size=4, description="Output enable for data pins"), ]) bb_clk = Signal() self.sync += [ bb_clk.eq(self.wdata.re), # auto-clock the SPI chip whenever wdata is written. Delay a cycle for setup/hold. ] copi_pad = TSTriple() cipo_pad = TSTriple() cs_n_pad = TSTriple() clk_pad = TSTriple() wp_pad = TSTriple() hold_pad = TSTriple() self.specials += copi_pad.get_tristate(pads.copi) self.specials += cipo_pad.get_tristate(pads.cipo) self.specials += cs_n_pad.get_tristate(pads.cs_n) self.specials += clk_pad.get_tristate(pads.clk) self.specials += wp_pad.get_tristate(pads.wp) self.specials += hold_pad.get_tristate(pads.hold) reset = Signal() self.comb += [ reset.eq(ResetSignal() | self.reset), cs_n_pad.oe.eq(~reset), clk_pad.oe.eq(~reset), ] flash_addr = Signal(24) # size/4 because data bus is 32 bits wide, -1 for base 0 mem_bits = bits_for(int(size/4)-1) pad = Signal(2) self.comb += flash_addr.eq(Cat(pad, bus.adr[0:mem_bits-1])) read_active = Signal() spi_ready = Signal() self.sync += [ If(bus.stb & bus.cyc & ~read_active, read_active.eq(1), bus.ack.eq(0), ) .Elif(read_active & spi_ready, read_active.eq(0), bus.ack.eq(1), ) .Else( bus.ack.eq(0), read_active.eq(0), ) ] o_rdata = Signal(32) self.comb += bus.dat_r.eq(o_rdata) self.specials += Instance("spimemio", o_flash_io0_oe = copi_pad.oe, o_flash_io1_oe = cipo_pad.oe, o_flash_io2_oe = wp_pad.oe, o_flash_io3_oe = hold_pad.oe, o_flash_io0_do = copi_pad.o, o_flash_io1_do = cipo_pad.o, o_flash_io2_do = wp_pad.o, o_flash_io3_do = hold_pad.o, o_flash_csb = cs_n_pad.o, o_flash_clk = clk_pad.o, i_flash_io0_di = copi_pad.i, i_flash_io1_di = cipo_pad.i, i_flash_io2_di = wp_pad.i, i_flash_io3_di = hold_pad.i, i_resetn = ~reset, i_clk = ClockSignal(), i_valid = bus.stb & bus.cyc, o_ready = spi_ready, i_addr = flash_addr, o_rdata = o_rdata, i_bb_oe = self.wdata.fields.oe, i_bb_wd = self.wdata.fields.data, i_bb_clk = bb_clk, i_bb_csb = self.mode.fields.csn, o_bb_rd = self.rdata.fields.data, i_config_update = self.mode.re | ic_reset, i_memio_enable = ~self.mode.fields.bitbang, ) platform.add_source("rtl/spimemio.v")
def memory_emit_verilog(memory, ns, add_data_file): r = "" def gn(e): if isinstance(e, Memory): return ns.get_name(e) else: return verilog_printexpr(ns, e)[0] adrbits = bits_for(memory.depth - 1) for i in range(memory.width // 8): r += "reg [" + str((memory.width//4)-1) + ":0] " \ + gn(memory) + '_efx_' + str(i) \ + "[0:" + str(memory.depth-1) + "];\n" adr_regs = {} data_regs = {} for port in memory.ports: if not port.async_read: if port.mode == WRITE_FIRST: adr_reg = Signal(name_override="memadr") r += "reg [" + str(adrbits-1) + ":0] " \ + gn(adr_reg) + ";\n" adr_regs[id(port)] = adr_reg else: data_reg = Signal(name_override="memdat") r += "reg [" + str(memory.width-1) + ":0] " \ + gn(data_reg) + ";\n" data_regs[id(port)] = data_reg for port in memory.ports: r += "always @(posedge " + gn(port.clock) + ") begin\n" if port.we is not None: if port.we_granularity: n = memory.width // port.we_granularity for i in range(n): if (i > 0): r += "always @(posedge " + gn(port.clock) + ") begin\n" m = i * port.we_granularity M = (i + 1) * port.we_granularity - 1 sl = "[" + str(M) + ":" + str(m) + "]" r += "\tif (" + gn(port.we) + "[" + str(i) + "])\n" r += "\t\t" + gn(memory) + '_efx_' + str(i) + "[" + gn( port.adr) + "]" + " <= " + gn(port.dat_w) + sl + ";\n" r += "end\n" else: r += "\tif (" + gn(port.we) + ")\n" r += "\t\t" + gn(memory) + "[" + gn(port.adr) + "] <= " + gn( port.dat_w) + ";\n" if not port.async_read: if port.mode == WRITE_FIRST: r += "always @(posedge " + gn(port.clock) + ") begin\n" rd = "\t" + gn(adr_regs[id(port)]) + " <= " + gn( port.adr) + ";\n" else: bassign = "" for i in range(memory.width // 8): m = i * port.we_granularity M = (i + 1) * port.we_granularity - 1 sl = "[" + str(M) + ":" + str(m) + "]" bassign += gn(data_regs[id(port)]) + sl + " <= " + gn( memory) + "_efx_" + str(i) + "[" + gn( port.adr) + "];\n" if port.mode == READ_FIRST: rd = "\t" + bassign elif port.mode == NO_CHANGE: rd = "\tif (!" + gn(port.we) + ")\n" \ + "\t\t" + bassign if port.re is None: r += rd else: r += "\tif (" + gn(port.re) + ")\n" r += "\t" + rd.replace("\n\t", "\n\t\t") r += "end\n\n" for port in memory.ports: if port.async_read: r += "assign " + gn(port.dat_r) + " = " + gn(memory) + "[" + gn( port.adr) + "];\n" else: if port.mode == WRITE_FIRST: for i in range(memory.width // 8): m = i * port.we_granularity M = (i + 1) * port.we_granularity - 1 sl = "[" + str(M) + ":" + str(m) + "]" r += "assign " + gn(port.dat_r) + sl + " = " + gn( memory) + "_efx_" + str(i) + "[" + gn( adr_regs[id(port)]) + "];\n" else: r += "assign " + gn(port.dat_r) + " = " + gn( data_regs[id(port)]) + ";\n" r += "\n" if memory.init is not None: content_7_0 = "" content_15_8 = "" content_23_16 = "" content_31_24 = "" formatter = "{:0" + str(int(memory.width / 4)) + "X}\n" init_7_0 = [] init_15_8 = [] init_23_16 = [] init_31_24 = [] for w in memory.init: init_7_0.append(w & 0xff) init_15_8.append((w >> 8) & 0xff) init_23_16.append((w >> 16) & 0xff) init_31_24.append((w >> 24) & 0xff) for d in init_7_0: content_7_0 += formatter.format(d) for d in init_15_8: content_15_8 += formatter.format(d) for d in init_23_16: content_23_16 += formatter.format(d) for d in init_31_24: content_31_24 += formatter.format(d) memory_filename1 = add_data_file( gn(memory) + "_efx_1.init", content_7_0) memory_filename2 = add_data_file( gn(memory) + "_efx_2.init", content_15_8) memory_filename3 = add_data_file( gn(memory) + "_efx_3.init", content_23_16) memory_filename4 = add_data_file( gn(memory) + "_efx_4.init", content_31_24) r += "initial begin\n" r += "\t$readmemh(\"" + memory_filename1 + "\", " + gn( memory) + "_efx_0" + ");\n" r += "\t$readmemh(\"" + memory_filename2 + "\", " + gn( memory) + "_efx_1" + ");\n" r += "\t$readmemh(\"" + memory_filename3 + "\", " + gn( memory) + "_efx_2" + ");\n" r += "\t$readmemh(\"" + memory_filename4 + "\", " + gn( memory) + "_efx_3" + ");\n" r += "end\n\n" return r
def emit_verilog(memory, ns, add_data_file): r = "" def gn(e): if isinstance(e, Memory): return ns.get_name(e) else: return verilog_printexpr(ns, e)[0] adrbits = bits_for(memory.depth - 1) r += "".join(("reg [{}:0] ".format(memory.width - 1), gn(memory), "[0:{}];\n".format(memory.depth - 1))) adr_regs = {} data_regs = {} for port in memory.ports: if not port.async_read: if port.mode == WRITE_FIRST and port.we is not None: adr_reg = Signal(name_override="memadr") r += "".join(("reg [{}:0] ".format(adrbits - 1), gn(adr_reg), ";\n")) adr_regs[id(port)] = adr_reg else: data_reg = Signal(name_override="memdat") r += "".join(("reg [{}:0] ".format(memory.width - 1), gn(data_reg), ";\n")) data_regs[id(port)] = data_reg for port in memory.ports: r += "always @(posedge {}) begin\n".format(gn(port.clock)) if port.we is not None: if port.we_granularity: n = memory.width // port.we_granularity for i in range(n): m = i * port.we_granularity M = (i + 1) * port.we_granularity - 1 sl = "[{}:{}]".format(M, m) r += "\tif ({}[{}])\n".format(gn(port.we), i) r += "\t\t{}[{}]{} <= {}{};\n".format( gn(memory), gn(port.adr), sl, gn(port.dat_w), sl) else: r += "\tif ({})\n".format(gn(port.we)) r += "\t\t{}[{}] <= {};\n".format( gn(memory), gn(port.adr), gn(port.dat_w)) if not port.async_read: if port.mode == WRITE_FIRST and port.we is not None: rd = "\t{} <= {};\n".format( gn(adr_regs[id(port)]), gn(port.adr)) else: bassign = "{} <= {}[{}];\n".format( gn(data_regs[id(port)]), gn(memory), gn(port.adr)) if port.mode == READ_FIRST or port.we is None: rd = "\t" + bassign elif port.mode == NO_CHANGE: rd = ("\tif (!{})\n".format(gn(port.we)) + "\t\t" + bassign) if port.re is None: r += rd else: r += "\tif ({})\n".format(gn(port.re)) r += "\t" + rd.replace("\n\t", "\n\t\t") r += "end\n\n" for port in memory.ports: if port.async_read: r += "assign {} = {}[{}];\n".format( gn(port.dat_r), gn(memory), gn(port.adr)) else: if port.mode == WRITE_FIRST and port.we is not None: r += "assign {} = {}[{}];\n".format( gn(port.dat_r), gn(memory), gn(adr_regs[id(port)])) else: r += "assign {} = {};\n".format( gn(port.dat_r), gn(data_regs[id(port)])) r += "\n" if memory.init is not None: content = "" for d in memory.init: content += "{:x}\n".format(d) memory_filename = add_data_file(gn(memory) + ".init", content) r += "initial begin\n" r += "\t$readmemh(\"{}\", {});\n".format(memory_filename, gn(memory)) r += "end\n\n" return r
def emit_verilog(memory, ns, add_data_file): r = "" def gn(e): if isinstance(e, Memory): return ns.get_name(e) else: return verilog_printexpr(ns, e)[0] adrbits = bits_for(memory.depth - 1) r += "reg [" + str(memory.width-1) + ":0] " \ + gn(memory) \ + "[0:" + str(memory.depth-1) + "];\n" adr_regs = {} data_regs = {} for port in memory.ports: if not port.async_read: if port.mode == WRITE_FIRST: adr_reg = Signal(name_override="memadr") r += "reg [" + str(adrbits-1) + ":0] " \ + gn(adr_reg) + ";\n" adr_regs[id(port)] = adr_reg else: data_reg = Signal(name_override="memdat") r += "reg [" + str(memory.width-1) + ":0] " \ + gn(data_reg) + ";\n" data_regs[id(port)] = data_reg for port in memory.ports: r += "always @(posedge " + gn(port.clock) + ") begin\n" if port.we is not None: if port.we_granularity: n = memory.width // port.we_granularity for i in range(n): m = i * port.we_granularity M = (i + 1) * port.we_granularity - 1 sl = "[" + str(M) + ":" + str(m) + "]" r += "\tif (" + gn(port.we) + "[" + str(i) + "])\n" r += "\t\t" + gn(memory) + "[" + gn( port.adr) + "]" + sl + " <= " + gn( port.dat_w) + sl + ";\n" else: r += "\tif (" + gn(port.we) + ")\n" r += "\t\t" + gn(memory) + "[" + gn( port.adr) + "] <= " + gn(port.dat_w) + ";\n" if not port.async_read: if port.mode == WRITE_FIRST: rd = "\t" + gn(adr_regs[id(port)]) + " <= " + gn( port.adr) + ";\n" else: bassign = gn( data_regs[id(port)]) + " <= " + gn(memory) + "[" + gn( port.adr) + "];\n" if port.mode == READ_FIRST: rd = "\t" + bassign elif port.mode == NO_CHANGE: rd = "\tif (!" + gn(port.we) + ")\n" \ + "\t\t" + bassign if port.re is None: r += rd else: r += "\tif (" + gn(port.re) + ")\n" r += "\t" + rd.replace("\n\t", "\n\t\t") r += "end\n\n" for port in memory.ports: if port.async_read: r += "assign " + gn( port.dat_r) + " = " + gn(memory) + "[" + gn( port.adr) + "];\n" else: if port.mode == WRITE_FIRST: r += "assign " + gn( port.dat_r) + " = " + gn(memory) + "[" + gn( adr_regs[id(port)]) + "];\n" else: r += "assign " + gn(port.dat_r) + " = " + gn( data_regs[id(port)]) + ";\n" r += "\n" if memory.init is not None: content = "" formatter = "{:0" + str(int(memory.width / 4)) + "X}\n" for d in memory.init: content += formatter.format(d) memory_filename = add_data_file(gn(memory) + ".init", content) r += "initial begin\n" r += "\t$readmemh(\"" + memory_filename + "\", " + gn( memory) + ");\n" r += "end\n\n" return r
def __init__(self, platform, pads, size=2 * 1024 * 1024): self.size = size self.bus = bus = wishbone.Interface() self.reset = Signal() self.cfg1 = CSRStorage(size=8) self.cfg2 = CSRStorage(size=8) self.cfg3 = CSRStorage(size=8) self.cfg4 = CSRStorage(size=8) self.stat1 = CSRStatus(size=8) self.stat2 = CSRStatus(size=8) self.stat3 = CSRStatus(size=8) self.stat4 = CSRStatus(size=8) cfg = Signal(32) cfg_we = Signal(4) cfg_out = Signal(32) self.comb += [ cfg.eq( Cat(self.cfg1.storage, self.cfg2.storage, self.cfg3.storage, self.cfg4.storage)), cfg_we.eq( Cat(self.cfg1.re, self.cfg2.re, self.cfg3.re, self.cfg4.re)), self.stat1.status.eq(cfg_out[0:8]), self.stat2.status.eq(cfg_out[8:16]), self.stat3.status.eq(cfg_out[16:24]), self.stat4.status.eq(cfg_out[24:32]), ] mosi_pad = TSTriple() miso_pad = TSTriple() cs_n_pad = TSTriple() clk_pad = TSTriple() wp_pad = TSTriple() hold_pad = TSTriple() self.specials += mosi_pad.get_tristate(pads.mosi) self.specials += miso_pad.get_tristate(pads.miso) self.specials += cs_n_pad.get_tristate(pads.cs_n) self.specials += clk_pad.get_tristate(pads.clk) self.specials += wp_pad.get_tristate(pads.wp) self.specials += hold_pad.get_tristate(pads.hold) reset = Signal() self.comb += [ reset.eq(ResetSignal() | self.reset), cs_n_pad.oe.eq(~reset), clk_pad.oe.eq(~reset), ] flash_addr = Signal(24) # size/4 because data bus is 32 bits wide, -1 for base 0 mem_bits = bits_for(int(size / 4) - 1) pad = Signal(2) self.comb += flash_addr.eq(Cat(pad, bus.adr[0:mem_bits - 1])) read_active = Signal() spi_ready = Signal() self.sync += [ If( bus.stb & bus.cyc & ~read_active, read_active.eq(1), bus.ack.eq(0), ).Elif( read_active & spi_ready, read_active.eq(0), bus.ack.eq(1), ).Else( bus.ack.eq(0), read_active.eq(0), ) ] o_rdata = Signal(32) self.comb += bus.dat_r.eq(o_rdata) self.specials += Instance( "spimemio", o_flash_io0_oe=mosi_pad.oe, o_flash_io1_oe=miso_pad.oe, o_flash_io2_oe=wp_pad.oe, o_flash_io3_oe=hold_pad.oe, o_flash_io0_do=mosi_pad.o, o_flash_io1_do=miso_pad.o, o_flash_io2_do=wp_pad.o, o_flash_io3_do=hold_pad.o, o_flash_csb=cs_n_pad.o, o_flash_clk=clk_pad.o, i_flash_io0_di=mosi_pad.i, i_flash_io1_di=miso_pad.i, i_flash_io2_di=wp_pad.i, i_flash_io3_di=hold_pad.i, i_resetn=~reset, i_clk=ClockSignal(), i_valid=bus.stb & bus.cyc, o_ready=spi_ready, i_addr=flash_addr, o_rdata=o_rdata, i_cfgreg_we=cfg_we, i_cfgreg_di=cfg, o_cfgreg_do=cfg_out, ) platform.add_source("rtl/spimemio.v")
def dmatpl(depth): b = bits_for(depth - 1) return [('start', b), ('count', b)]
def dmatpl(depth): b = bits_for(depth-1) return [('start', b), ('count', b)]
def emit_verilog(memory, ns, add_data_file): r = "" def gn(e): if isinstance(e, Memory): return ns.get_name(e) else: return verilog_printexpr(ns, e)[0] adrbits = bits_for(memory.depth - 1) r += "".join(("reg [{}:0] ".format(memory.width - 1), gn(memory), "[0:{}];\n".format(memory.depth - 1))) adr_regs = {} data_regs = {} for port in memory.ports: if not port.async_read: if port.mode == WRITE_FIRST: adr_reg = Signal(name_override="memadr") r += "".join(("reg [{}:0] ".format(adrbits - 1), gn(adr_reg), ";\n")) adr_regs[id(port)] = adr_reg else: data_reg = Signal(name_override="memdat") r += "".join(("reg [{}:0] ".format(memory.width - 1), gn(data_reg), ";\n")) data_regs[id(port)] = data_reg for port in memory.ports: r += "always @(posedge {}) begin\n".format(gn(port.clock)) if port.we is not None: if port.we_granularity: n = memory.width // port.we_granularity for i in range(n): m = i * port.we_granularity M = (i + 1) * port.we_granularity - 1 sl = "[{}:{}]".format(M, m) r += "\tif ({}[{}])\n".format(gn(port.we), i) r += "\t\t{}[{}]{} <= {}{};\n".format( gn(memory), gn(port.adr), sl, gn(port.dat_w), sl) else: r += "\tif ({})\n".format(gn(port.we)) r += "\t\t{}[{}] <= {};\n".format(gn(memory), gn(port.adr), gn(port.dat_w)) if not port.async_read: if port.mode == WRITE_FIRST: rd = "\t{} <= {};\n".format(gn(adr_regs[id(port)]), gn(port.adr)) else: bassign = "{} <= {}[{}];\n".format(gn(data_regs[id(port)]), gn(memory), gn(port.adr)) if port.mode == READ_FIRST: rd = "\t" + bassign elif port.mode == NO_CHANGE: rd = ("\tif (!{})\n".format(gn(port.we)) + "\t\t" + bassign) if port.re is None: r += rd else: r += "\tif ({})\n".format(gn(port.re)) r += "\t" + rd.replace("\n\t", "\n\t\t") r += "end\n\n" for port in memory.ports: if port.async_read: r += "assign {} = {}[{}];\n".format(gn(port.dat_r), gn(memory), gn(port.adr)) else: if port.mode == WRITE_FIRST: r += "assign {} = {}[{}];\n".format( gn(port.dat_r), gn(memory), gn(adr_regs[id(port)])) else: r += "assign {} = {};\n".format(gn(port.dat_r), gn(data_regs[id(port)])) r += "\n" if memory.init is not None: content = "" for d in memory.init: content += "{:x}\n".format(d) memory_filename = add_data_file(gn(memory) + ".init", content) r += "initial begin\n" r += "\t$readmemh(\"{}\", {});\n".format(memory_filename, gn(memory)) r += "end\n\n" return r