Exemple #1
0
	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
Exemple #2
0
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
Exemple #3
0
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
Exemple #4
0
    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
Exemple #5
0
    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
Exemple #6
0
    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))
Exemple #7
0
    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))
Exemple #8
0
    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")
Exemple #9
0
    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")
Exemple #10
0
    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
Exemple #11
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, 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)
Exemple #12
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)
Exemple #13
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
Exemple #14
0
    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")
Exemple #15
0
    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")
Exemple #16
0
    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")
Exemple #17
0
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
Exemple #18
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 += "".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
Exemple #19
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 = ""
            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
Exemple #20
0
    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")
Exemple #21
0
def dmatpl(depth):
    b = bits_for(depth - 1)
    return [('start', b), ('count', b)]
Exemple #22
0
def dmatpl(depth):
    b = bits_for(depth-1)
    return [('start', b), ('count', b)]
Exemple #23
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 += "".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