def __init__(self, pads, dummy=15, div=2, with_bitbang=True, endianness="big"): """ Simple SPI flash. Supports multi-bit pseudo-parallel reads (aka Dual or Quad I/O Fast Read). Only supports mode3 (cpol=1, cpha=1). """ SpiFlashCommon.__init__(self, pads) self.bus = bus = wishbone.Interface() spi_width = len(pads.dq) max_transfer_size = 8*8 assert spi_width >= 2 if with_bitbang: self.bitbang = CSRStorage(4, reset_less=True, fields=[ CSRField("mosi", description="Output value for MOSI pin, valid whenever ``dir`` is ``0``."), CSRField("clk", description="Output value for SPI CLK pin."), CSRField("cs_n", description="Output value for SPI CSn pin."), CSRField("dir", description="Sets the direction for *ALL* SPI data pins except CLK and CSn.", values=[ ("0", "OUT", "SPI pins are all output"), ("1", "IN", "SPI pins are all input"), ]) ], description=""" Bitbang controls for SPI output. Only standard 1x SPI is supported, and as a result all four wires are ganged together. This means that it is only possible to perform half-duplex operations, using this SPI core. """) self.miso = CSRStatus(description="Incoming value of MISO signal.") self.bitbang_en = CSRStorage(description="Write a ``1`` here to disable memory-mapped mode and enable bitbang mode.") queue = self.queue = CSRStatus(4) in_len = self.in_len = CSRStorage(4) out_len = self.out_len = CSRStorage(4) in_left = self.in_left = Signal(max=2**8) out_left = self.out_left = Signal(max=2**8) self.quad_transfer = Signal(reset=0) spi_in = self.spi_in = CSRStorage(max_transfer_size) spi_out = self.spi_out = CSRStatus(max_transfer_size) cs_n = Signal(reset=1) clk = Signal() dq_oe = Signal() wbone_width = len(bus.dat_r) cmd_width = 8 addr_width = 24 dq = TSTriple(spi_width) sr = Signal(max(cmd_width, addr_width, wbone_width)) if endianness == "big": self.comb += bus.dat_r.eq(sr) else: self.comb += bus.dat_r.eq(reverse_bytes(sr)) self.specials.dq0 = Tristate(pads.dq[0], o=dq.o[0], i=dq.i[0], oe=dq.oe) self.specials.dq1 = Tristate(pads.dq[1], o=dq.o[1], i=dq.i[1], oe=dq.oe) if with_bitbang: # Keep DQ2,DQ3 as outputs during bitbang, this ensures they activate ~WP or ~HOLD functions self.specials.dq2 = Tristate(pads.dq[2], o=dq.o[2], i=dq.i[2], oe=(dq.oe | self.bitbang_en.storage)) self.specials.dq3 = Tristate(pads.dq[3], o=dq.o[3], i=dq.i[3], oe=(dq.oe | self.bitbang_en.storage)) else: self.specials.dq2 = Tristate(pads.dq[2], o=dq.o[2], i=dq.i[2], oe=dq.oe) self.specials.dq3 = Tristate(pads.dq[3], o=dq.o[3], i=dq.i[3], oe=dq.oe) sr = Signal(max(cmd_width, addr_width, wbone_width, max_transfer_size)) if endianness == "big": self.comb += bus.dat_r.eq(sr[:wbone_width]) else: self.comb += bus.dat_r.eq(reverse_bytes(sr[:wbone_width])) hw_read_logic_single = [ pads.clk.eq(clk), pads.cs_n.eq(cs_n), dq.o.eq(sr[-spi_width:]), dq.oe.eq(dq_oe) ] hw_read_logic_quad = [ pads.clk.eq(clk), pads.cs_n.eq(cs_n), dq.o.eq(Cat(sr[-1:], Replicate(1, 3))), dq.oe.eq(dq_oe) ] if with_bitbang: bitbang_logic = [ pads.clk.eq(self.bitbang.storage[1]), pads.cs_n.eq(self.bitbang.storage[2]), # In Dual/Quad mode, no single data pin is consistently # an input or output thanks to dual/quad reads, so we need a bit # to swap direction of the pins. Aside from this additional bit, # bitbang mode is identical for Single/Dual/Quad; dq[0] is mosi # and dq[1] is miso, meaning remaining data pin values don't # appear in CSR registers. If(self.bitbang.storage[3], dq.oe.eq(0) ).Else( dq.oe.eq(1) ), If(self.bitbang.storage[1], # CPOL=0/CPHA=0 or CPOL=1/CPHA=1 only. self.miso.status.eq(dq.i[1]) ), dq.o.eq(Cat(self.bitbang.storage[0], Replicate(1, spi_width-1))) ] self.comb += [ If(self.bitbang_en.storage, bitbang_logic ).Elif(self.quad_transfer, hw_read_logic_single ).Else( hw_read_logic_quad ) ] else: self.comb += [ If(self.quad_transfer, hw_read_logic_single ).Else( hw_read_logic_quad ) ] if div < 2: raise ValueError("Unsupported value \'{}\' for div parameter for SpiFlash core".format(div)) # spi is byte-addressed, prefix by zeros z = Replicate(0, log2_int(wbone_width//8)) i = Signal(max=div) dqi = Signal(spi_width) # SPI or memmap mode self.mode = Signal() self.sync += [ If(i == div//2 - 1, clk.eq(1), dqi.eq(dq.i), ), If(i == div - 1, i.eq(0), clk.eq(0), If(self.quad_transfer, sr.eq(Cat(dqi, sr[:-spi_width])) ).Else( sr.eq(Cat(dqi[1], sr[:-1])) ) ).Else( i.eq(i + 1), ), ] read_seq = [ (4*cmd_width//spi_width*div, [dq_oe.eq(1), cs_n.eq(0), sr[-cmd_width:].eq(_QIOFR), self.quad_transfer.eq(0)]), (addr_width//spi_width*div, [sr[-addr_width:].eq(Cat(z, bus.adr)), self.quad_transfer.eq(1)]), ((1+dummy + wbone_width//spi_width)*div, [dq_oe.eq(0)]), (1, [bus.ack.eq(1), cs_n.eq(1)]), (div, # tSHSL! [bus.ack.eq(0)]), (0, [queue.status[0].eq(0)]), ] write_seq = [ (4*cmd_width//spi_width*div, [dq_oe.eq(1), cs_n.eq(0), sr[-cmd_width:].eq(_QIOPP), self.quad_transfer.eq(0)]), (addr_width//spi_width*div, [sr[-addr_width:].eq(Cat(z, bus.adr)), self.quad_transfer.eq(1)]), ((wbone_width//spi_width)*div, [sr[-wbone_width:].eq(reverse_bytes(bus.dat_w))]), (1, [bus.ack.eq(1), cs_n.eq(1)]), (div, [bus.ack.eq(0)]), (0, [queue.status[1].eq(0)]), ] # prepare spi transfer self.sync += If(self.out_len.re & (self.out_len.storage != 0) & self.en_quad.storage[0], self.out_left.eq(Cat(1, self.out_len.storage) ) ) self.sync += If(self.out_len.re & (self.out_len.storage == 0), self.out_left.eq(0) ) self.sync += If(self.out_len.re & (self.out_len.storage != 0) & ~self.en_quad.storage[0], self.out_left.eq(Cat(1, Replicate(0, 2), self.out_len.storage)) ) self.sync += If(self.in_len.re & (self.in_len.storage != 0) & ~self.en_quad.storage[0], [queue.status[2].eq(1), self.in_left.eq(Cat(Replicate(0, 3), in_len.storage)), self.quad_transfer.eq(0)] ) # write data to sr self.sync += If(queue.status[2] & (i == div - 1) & ~self.en_quad.storage[0], sr[-max_transfer_size:].eq(self.spi_in.storage), queue.status[2].eq(0), queue.status[3].eq(1), cs_n.eq(0), dq_oe.eq(1)) # count spi to slave transfer cycles self.sync += If(queue.status[3] & (self.in_left > 0) & (i == div - 1), self.in_left.eq(self.in_left - 1), dq_oe.eq(1)) # count spi to master transfer cycles self.sync += If(queue.status[3] & (self.in_left < 1) & (self.out_left > 0) & (i == div - 1), self.out_left.eq(self.out_left - 1), dq_oe.eq(0)) #end transmision and read data from sr self.sync += If(~self.in_len.re & (in_left < 1) & (out_left < 1) & queue.status[3], queue.status[3].eq(0), cs_n.eq(1), If(self.out_len.storage == 1, self.spi_out.status.eq(Cat(Replicate(0, 8*7), sr)) ).Elif(self.out_len.storage == 2, self.spi_out.status.eq(Cat(Replicate(0, 8*6), sr)) ).Elif(self.out_len.storage == 3, self.spi_out.status.eq(Cat(Replicate(0, 8*5), sr)) ).Elif(self.out_len.storage == 4, self.spi_out.status.eq(Cat(Replicate(0, 8*4), sr)) ).Elif(self.out_len.storage == 5, self.spi_out.status.eq(Cat(Replicate(0, 8*3), sr)) ).Elif(self.out_len.storage == 6, self.spi_out.status.eq(Cat(Replicate(0, 8*2), sr)) ).Elif(self.out_len.storage == 7, self.spi_out.status.eq(Cat(Replicate(0, 8*1), sr)) ).Else(self.spi_out.status.eq(sr))) # detect mem map access self.sync += If(~self.mode & bus.cyc & bus.stb & ~bus.we, queue.status[0].eq(1)) self.sync += If(~self.mode & bus.cyc & bus.stb & bus.we, queue.status[1].eq(1)) self.sync += timeline(queue.status[0] & ~self.en_quad.storage[0] & (i == div - 1), accumulate_timeline_deltas(read_seq)) self.sync += timeline(queue.status[1] & ~self.en_quad.storage[0] & (i == div - 1), accumulate_timeline_deltas(write_seq))
def __init__(self, platform, core_config, **kwargs): platform.add_extension(get_common_ios()) sys_clk_freq = core_config["sys_clk_freq"] SoCSDRAM.__init__(self, platform, sys_clk_freq, cpu_type=core_config["cpu"], l2_size=16*core_config["sdram_module_nb"], **kwargs) # crg self.submodules.crg = LiteDRAMCRG(platform, core_config) # sdram platform.add_extension(get_dram_ios(core_config)) assert core_config["memtype"] in ["DDR2", "DDR3"] self.submodules.ddrphy = core_config["sdram_phy"]( platform.request("ddram"), memtype=core_config["memtype"], nphases=4 if core_config["memtype"] == "DDR3" else 2, sys_clk_freq=sys_clk_freq, iodelay_clk_freq=core_config["iodelay_clk_freq"], cmd_latency=core_config["cmd_latency"]) self.add_constant("CMD_DELAY", core_config["cmd_delay"]) if core_config["memtype"] == "DDR3": self.ddrphy.settings.add_electrical_settings( rtt_nom=core_config["rtt_nom"], rtt_wr=core_config["rtt_wr"], ron=core_config["ron"]) sdram_module = core_config["sdram_module"](sys_clk_freq, "1:4" if core_config["memtype"] == "DDR3" else "1:2") controller_settings = controller_settings=ControllerSettings( cmd_buffer_depth=core_config["cmd_buffer_depth"]) self.register_sdram(self.ddrphy, sdram_module.geom_settings, sdram_module.timing_settings, controller_settings=controller_settings) # sdram init self.submodules.ddrctrl = LiteDRAMCoreControl() self.comb += [ platform.request("init_done").eq(self.ddrctrl.init_done.storage), platform.request("init_error").eq(self.ddrctrl.init_error.storage) ] # CSR port if core_config.get("expose_csr_port", "no") == "yes": csr_port = csr_bus.Interface(self.csr_address_width, self.csr_data_width) self.add_csr_master(csr_port) platform.add_extension(get_csr_ios(self.csr_address_width, self.csr_data_width)) _csr_port_io = platform.request("csr_port", 0) self.comb += [ csr_port.adr.eq(_csr_port_io.adr), csr_port.we.eq(_csr_port_io.we), csr_port.dat_w.eq(_csr_port_io.dat_w), _csr_port_io.dat_r.eq(csr_port.dat_r), ] # user port self.comb += [ platform.request("user_clk").eq(ClockSignal()), platform.request("user_rst").eq(ResetSignal()) ] if core_config["user_ports_type"] == "native": for i in range(core_config["user_ports_nb"]): user_port = self.sdram.crossbar.get_port() platform.add_extension(get_native_user_port_ios(i, user_port.address_width, user_port.data_width)) _user_port_io = platform.request("user_port", i) self.comb += [ # cmd user_port.cmd.valid.eq(_user_port_io.cmd_valid), _user_port_io.cmd_ready.eq(user_port.cmd.ready), user_port.cmd.we.eq(_user_port_io.cmd_we), user_port.cmd.addr.eq(_user_port_io.cmd_addr), # wdata user_port.wdata.valid.eq(_user_port_io.wdata_valid), _user_port_io.wdata_ready.eq(user_port.wdata.ready), user_port.wdata.we.eq(_user_port_io.wdata_we), user_port.wdata.data.eq(_user_port_io.wdata_data), # rdata _user_port_io.rdata_valid.eq(user_port.rdata.valid), user_port.rdata.ready.eq(_user_port_io.rdata_ready), _user_port_io.rdata_data.eq(user_port.rdata.data), ] elif core_config["user_ports_type"] == "wishbone": for i in range(core_config["user_ports_nb"]): user_port = self.sdram.crossbar.get_port() wb_port = wishbone.Interface( user_port.data_width, user_port.address_width) wishbone2native = LiteDRAMWishbone2Native(wb_port, user_port) self.submodules += wishbone2native platform.add_extension(get_wishbone_user_port_ios(i, len(wb_port.adr), len(wb_port.dat_w))) _wb_port_io = platform.request("user_port", i) self.comb += [ wb_port.adr.eq(_wb_port_io.adr), wb_port.dat_w.eq(_wb_port_io.dat_w), _wb_port_io.dat_r.eq(wb_port.dat_r), wb_port.sel.eq(_wb_port_io.sel), wb_port.cyc.eq(_wb_port_io.cyc), wb_port.stb.eq(_wb_port_io.stb), _wb_port_io.ack.eq(wb_port.ack), wb_port.we.eq(_wb_port_io.we), _wb_port_io.err.eq(wb_port.err), ] elif core_config["user_ports_type"] == "axi": for i in range(core_config["user_ports_nb"]): user_port = self.sdram.crossbar.get_port() axi_port = LiteDRAMAXIPort( user_port.data_width, user_port.address_width + log2_int(user_port.data_width//8), core_config["user_ports_id_width"]) axi2native = LiteDRAMAXI2Native(axi_port, user_port) self.submodules += axi2native platform.add_extension(get_axi_user_port_ios(i, axi_port.address_width, axi_port.data_width, core_config["user_ports_id_width"])) _axi_port_io = platform.request("user_port", i) self.comb += [ # aw axi_port.aw.valid.eq(_axi_port_io.aw_valid), _axi_port_io.aw_ready.eq(axi_port.aw.ready), axi_port.aw.addr.eq(_axi_port_io.aw_addr), axi_port.aw.burst.eq(_axi_port_io.aw_burst), axi_port.aw.len.eq(_axi_port_io.aw_len), axi_port.aw.size.eq(_axi_port_io.aw_size), axi_port.aw.id.eq(_axi_port_io.aw_id), # w axi_port.w.valid.eq(_axi_port_io.w_valid), _axi_port_io.w_ready.eq(axi_port.w.ready), axi_port.w.last.eq(_axi_port_io.w_last), axi_port.w.strb.eq(_axi_port_io.w_strb), axi_port.w.data.eq(_axi_port_io.w_data), # b _axi_port_io.b_valid.eq(axi_port.b.valid), axi_port.b.ready.eq(_axi_port_io.b_ready), _axi_port_io.b_resp.eq(axi_port.b.resp), _axi_port_io.b_id.eq(axi_port.b.id), # ar axi_port.ar.valid.eq(_axi_port_io.ar_valid), _axi_port_io.ar_ready.eq(axi_port.ar.ready), axi_port.ar.addr.eq(_axi_port_io.ar_addr), axi_port.ar.burst.eq(_axi_port_io.ar_burst), axi_port.ar.len.eq(_axi_port_io.ar_len), axi_port.ar.size.eq(_axi_port_io.ar_size), axi_port.ar.id.eq(_axi_port_io.ar_id), # r _axi_port_io.r_valid.eq(axi_port.r.valid), axi_port.r.ready.eq(_axi_port_io.r_ready), _axi_port_io.r_last.eq(axi_port.r.last), _axi_port_io.r_resp.eq(axi_port.r.resp), _axi_port_io.r_data.eq(axi_port.r.data), _axi_port_io.r_id.eq(axi_port.r.id), ] else: raise ValueError("Unsupported port type: {}".format(core_config["user_ports_type"]))
def __init__(self, platform, variant="standard"): self.platform = platform self.variant = variant self.reset = Signal() self.ibus = wishbone.Interface() self.dbus = wishbone.Interface() self.periph_buses = [self.ibus, self.dbus] self.memory_buses = [] self.interrupt = Signal(15) ibus = Record(obi_layout) dbus = Record(obi_layout) # OBI <> Wishbone. self.submodules.ibus_conv = OBI2Wishbone(ibus, self.ibus) self.submodules.dbus_conv = OBI2Wishbone(dbus, self.dbus) self.comb += [ ibus.we.eq(0), ibus.be.eq(1111), ] self.cpu_params = dict( # Clk / Rst. i_clk_i=ClockSignal("sys"), i_rst_ni=~ResetSignal("sys"), # Controls. i_clock_en_i=1, i_test_en_i=0, i_fregfile_disable_i=0, i_core_id_i=0, i_cluster_id_i=0, # IBus. o_instr_req_o=ibus.req, i_instr_gnt_i=ibus.gnt, i_instr_rvalid_i=ibus.rvalid, o_instr_addr_o=ibus.addr, i_instr_rdata_i=ibus.rdata, # DBus. o_data_req_o=dbus.req, i_data_gnt_i=dbus.gnt, i_data_rvalid_i=dbus.rvalid, o_data_we_o=dbus.we, o_data_be_o=dbus.be, o_data_addr_o=dbus.addr, o_data_wdata_o=dbus.wdata, i_data_rdata_i=dbus.rdata, # APU. i_apu_master_gnt_i=0, i_apu_master_valid_i=0, # IRQ. i_irq_sec_i=0, i_irq_software_i=0, i_irq_external_i=0, i_irq_fast_i=self.interrupt, i_irq_nmi_i=0, i_irq_fastx_i=0, # Debug. i_debug_req_i=0, # CPU Control. i_fetch_enable_i=1, ) # Add Verilog sources. add_manifest_sources(platform, 'cv32e40p_manifest.flist') # Specific FPU variant parameters/files. if variant in self.has_fpu: self.cpu_params.update(p_FPU=1) add_manifest_sources(platform, 'cv32e40p_fpu_manifest.flist')
def __init__(self, platform, core_config): platform.add_extension(get_pcie_ios(core_config["phy_lanes"])) for i in range(core_config["dma_channels"]): platform.add_extension( get_axi_dma_ios(i, core_config["phy_data_width"])) platform.add_extension(get_msi_irqs_ios(width=core_config["msi_irqs"])) sys_clk_freq = float(core_config.get("clk_freq", 125e6)) # SoCMini ---------------------------------------------------------------------------------- SoCMini.__init__(self, platform, clk_freq=sys_clk_freq, csr_data_width=32, csr_ordering=core_config.get("csr_ordering", "big"), ident="LitePCIe standalone core", ident_version=True) # CRG -------------------------------------------------------------------------------------- clk_external = core_config.get("clk_external", False) self.submodules.crg = LitePCIeCRG(platform, sys_clk_freq, clk_external) # PCIe PHY --------------------------------------------------------------------------------- self.submodules.pcie_phy = core_config["phy"]( platform, platform.request("pcie"), pcie_data_width=core_config.get("phy_pcie_data_width", 64), data_width=core_config["phy_data_width"], bar0_size=core_config["phy_bar0_size"]) # PCIe Endpoint ---------------------------------------------------------------------------- self.submodules.pcie_endpoint = LitePCIeEndpoint( self.pcie_phy, endianness=self.pcie_phy.endianness, max_pending_requests=core_config.get("ep_max_pending_requests", 4)) # PCIe Wishbone Master --------------------------------------------------------------------- pcie_wishbone_master = LitePCIeWishboneMaster( self.pcie_endpoint, qword_aligned=self.pcie_phy.qword_aligned) self.submodules += pcie_wishbone_master self.add_wb_master(pcie_wishbone_master.wishbone) # PCIe MMAP Master ------------------------------------------------------------------------- if core_config.get("mmap", False): mmap_base = core_config["mmap_base"] mmap_size = core_config["mmap_size"] mmap_translation = core_config.get("mmap_translation", 0x00000000) wb = wishbone.Interface(data_width=32) self.mem_map["mmap"] = mmap_base self.add_wb_slave(mmap_base, wb, mmap_size) self.add_memory_region("mmap", mmap_base, mmap_size, type="io") axi = AXILiteInterface(data_width=32, address_width=32) wb2axi = Wishbone2AXILite(wb, axi, base_address=-mmap_translation) self.submodules += wb2axi platform.add_extension(axi.get_ios("mmap_axi_lite")) axi_pads = platform.request("mmap_axi_lite") self.comb += axi.connect_to_pads(axi_pads, mode="master") # PCIe MMAP Slave -------------------------------------------------------------------------- if core_config.get("mmap_slave", False): # AXI-Full if core_config.get("mmap_slave_axi_full", False): pcie_axi_slave = LitePCIeAXISlave(self.pcie_endpoint, data_width=128) self.submodules += pcie_axi_slave platform.add_extension( pcie_axi_slave.axi.get_ios("mmap_slave_axi")) axi_pads = platform.request("mmap_slave_axi") self.comb += pcie_axi_slave.axi.connect_to_pads(axi_pads, mode="slave") # AXI-Lite else: platform.add_extension(axi.get_ios("mmap_slave_axi_lite")) axi_pads = platform.request("mmap_slave_axi_lite") wb = wishbone.Interface(data_width=32) axi = AXILiteInterface(data_width=32, address_width=32) self.comb += axi.connect_to_pads(axi_pads, mode="slave") axi2wb = AXILite2Wishbone(axi, wb) self.submodules += axi2wb pcie_wishbone_slave = LitePCIeWishboneSlave( self.pcie_endpoint, qword_aligned=self.pcie_phy.qword_aligned) self.submodules += pcie_wishbone_slave self.comb += wb.connect(pcie_wishbone_slave.wishbone) # PCIe DMA --------------------------------------------------------------------------------- pcie_dmas = [] self.add_constant("DMA_CHANNELS", core_config["dma_channels"]) for i in range(core_config["dma_channels"]): pcie_dma = LitePCIeDMA( self.pcie_phy, self.pcie_endpoint, with_buffering=core_config["dma_buffering"] != 0, buffering_depth=core_config["dma_buffering"], with_loopback=core_config["dma_loopback"], with_synchronizer=core_config["dma_synchronizer"], with_monitor=core_config["dma_monitor"]) pcie_dma = stream.BufferizeEndpoints({"sink": stream.DIR_SINK})(pcie_dma) pcie_dma = stream.BufferizeEndpoints({"source": stream.DIR_SOURCE})(pcie_dma) setattr(self.submodules, "pcie_dma" + str(i), pcie_dma) self.add_csr("pcie_dma{}".format(i)) dma_writer_ios = platform.request("dma{}_writer_axi".format(i)) dma_reader_ios = platform.request("dma{}_reader_axi".format(i)) self.comb += [ # Writer IOs pcie_dma.sink.valid.eq(dma_writer_ios.tvalid), dma_writer_ios.tready.eq(pcie_dma.sink.ready), pcie_dma.sink.last.eq(dma_writer_ios.tlast), pcie_dma.sink.data.eq(dma_writer_ios.tdata), pcie_dma.sink.first.eq(dma_writer_ios.tuser), # Reader IOs dma_reader_ios.tvalid.eq(pcie_dma.source.valid), pcie_dma.source.ready.eq(dma_reader_ios.tready), dma_reader_ios.tlast.eq(pcie_dma.source.last), dma_reader_ios.tdata.eq(pcie_dma.source.data), dma_reader_ios.tuser.eq(pcie_dma.source.first), ] # PCIe MSI --------------------------------------------------------------------------------- if core_config.get("msi_x", False): assert core_config["msi_irqs"] <= 32 self.submodules.pcie_msi = LitePCIeMSIX(self.pcie_endpoint, width=64) self.comb += self.pcie_msi.irqs[32:32 + core_config["msi_irqs"]].eq( platform.request("msi_irqs")) else: assert core_config["msi_irqs"] <= 16 if core_config.get("msi_multivector", False): self.submodules.pcie_msi = LitePCIeMSIMultiVector(width=32) else: self.submodules.pcie_msi = LitePCIeMSI(width=32) self.comb += self.pcie_msi.source.connect(self.pcie_phy.msi) self.comb += self.pcie_msi.irqs[16:16 + core_config["msi_irqs"]].eq( platform.request("msi_irqs")) self.interrupts = {} for i in range(core_config["dma_channels"]): self.interrupts["pcie_dma" + str(i) + "_writer"] = getattr( self, "pcie_dma" + str(i)).writer.irq self.interrupts["pcie_dma" + str(i) + "_reader"] = getattr( self, "pcie_dma" + str(i)).reader.irq for i, (k, v) in enumerate(sorted(self.interrupts.items())): self.comb += self.pcie_msi.irqs[i].eq(v) self.add_constant(k.upper() + "_INTERRUPT", i) assert len(self.interrupts.keys()) <= 16
def test_wishbone_8bit(self): # Verify Wishbone with 8-bit data width. data = self.pattern_test_data["8bit"] wb = wishbone.Interface(adr_width=30, data_width=8) port = LiteDRAMNativePort("both", address_width=30, data_width=8) self.wishbone_readback_test(data["pattern"], data["expected"], wb, port)
def __init__(self, platform): self.bus = bus = wishbone.Interface() wdata = Signal(32) wmask = Signal(4) wdata_we = Signal() wdata_avail = Signal() wdata_ready = Signal() self.sync.clk50 += [ wdata_avail.eq(bus.cyc & bus.stb & bus.we), If( bus.cyc & bus.stb & bus.we & ~bus.ack, If( wdata_ready, wdata.eq(bus.dat_w), wmask.eq(bus.sel), wdata_we.eq(1), bus.ack.eq( 1 ), #### TODO check that this works with the clk50->clk100 domain crossing ).Else( wdata_we.eq(0), bus.ack.eq(0), )).Else( wdata_we.eq(0), bus.ack.eq(0), ) ] self.key_re = Signal(8) for k in range(0, 8): setattr( self, "key" + str(k), CSRStorage(32, name="key" + str(k), description="""secret key word {}""".format(k))) self.key_re[k].eq(getattr(self, "key" + str(k)).re) self.config = CSRStorage( description="Configuration register for the HMAC block", fields=[ CSRField("sha_en", size=1, description="Enable the SHA256 core"), CSRField("endian_swap", size=1, description="Swap the endianness on the input data"), CSRField( "digest_swap", size=1, description="Swap the endianness on the output digest"), CSRField("hmac_en", size=1, description="Enable the HMAC core"), ]) control_latch = Signal(self.config.size) ctrl_freeze = Signal() self.sync.clk50 += [ If(ctrl_freeze, control_latch.eq(control_latch)).Else( control_latch.eq(self.config.storage)) ] self.command = CSRStorage( description="Command register for the HMAC block", fields=[ CSRField("hash_start", size=1, description= "Writing a 1 indicates the beginning of hash data", pulse=True), CSRField("hash_process", size=1, description="Writing a 1 digests the hash data", pulse=True), ]) self.wipe = CSRStorage( 32, description= "wipe the secret key using the written value. Wipe happens upon write." ) for k in range(0, 8): setattr( self, "digest" + str(k), CSRStatus(32, name="digest" + str(k), description="""digest word {}""".format(k))) self.msg_length = CSRStatus( size=64, description="Length of digested message, in bits") self.error_code = CSRStatus(size=32, description="Error code") self.submodules.ev = EventManager() self.ev.err_valid = EventSourcePulse( description="Error flag was generated") self.ev.fifo_full = EventSourcePulse(description="FIFO is full") self.ev.hash_done = EventSourcePulse(description="HMAC is done") self.ev.sha256_done = EventSourcePulse(description="SHA256 is done") self.ev.finalize() err_valid = Signal() err_valid_r = Signal() fifo_full = Signal() fifo_full_r = Signal() hmac_hash_done = Signal() sha256_hash_done = Signal() self.sync += [ err_valid_r.eq(err_valid), fifo_full_r.eq(fifo_full), ] self.comb += [ self.ev.err_valid.trigger.eq(~err_valid_r & err_valid), self.ev.fifo_full.trigger.eq(~fifo_full_r & fifo_full), self.ev.hash_done.trigger.eq(hmac_hash_done), self.ev.sha256_done.trigger.eq(sha256_hash_done), ] # At a width of 32 bits, an 36kiB fifo is 1024 entries deep fifo_wvalid = Signal() fifo_wdata_mask = Signal(36) fifo_rready = Signal() fifo_rdata_mask = Signal(36) self.fifo = CSRStatus(description="FIFO status", fields=[ CSRField("read_count", size=10, description="read pointer"), CSRField("write_count", size=10, description="write pointer"), CSRField("read_error", size=1, description="read error occurred"), CSRField("write_error", size=1, description="write error occurred"), CSRField("almost_full", size=1, description="almost full"), CSRField("almost_empty", size=1, description="almost empty"), ]) fifo_rvalid = Signal() fifo_empty = Signal() fifo_wready = Signal() fifo_full_local = Signal() self.comb += fifo_rvalid.eq(~fifo_empty) self.comb += fifo_wready.eq(~fifo_full_local) self.specials += Instance( "FIFO36E1", p_DATA_WIDTH=36, p_ALMOST_EMPTY_OFFSET=8, p_ALMOST_FULL_OFFSET=8, p_DO_REG=1, p_FIRST_WORD_FALL_THROUGH="TRUE", p_EN_SYN="FALSE", i_RDCLK=ClockSignal("clk50"), i_WRCLK=ClockSignal("clk50"), i_RST=ResetSignal("clk50"), o_FULL=fifo_full_local, i_WREN=fifo_wvalid, i_DI=fifo_wdata_mask[:32], i_DIP=fifo_wdata_mask[32:], o_EMPTY=fifo_empty, i_RDEN=fifo_rready & fifo_rvalid, o_DO=fifo_rdata_mask[:32], o_DOP=fifo_rdata_mask[32:], o_RDCOUNT=self.fifo.fields.read_count, o_RDERR=self.fifo.fields.read_error, o_WRCOUNT=self.fifo.fields.write_count, o_WRERR=self.fifo.fields.write_error, o_ALMOSTFULL=self.fifo.fields.almost_full, o_ALMOSTEMPTY=self.fifo.fields.almost_empty, ) key_re_50 = Signal(8) for k in range(0, 8): setattr(self.submodules, 'keyre50_' + str(k), BlindTransfer("sys", "clk50")) getattr(self, 'keyre50_' + str(k)).i.eq( getattr(self, 'key' + str(k)).re) self.comb += key_re_50[k].eq(getattr(self, 'keyre50_' + str(k)).o) hash_start_50 = Signal() self.submodules.hashstart = BlindTransfer("sys", "clk50") self.comb += [ self.hashstart.i.eq(self.command.fields.hash_start), hash_start_50.eq(self.hashstart.o) ] hash_proc_50 = Signal() self.submodules.hashproc = BlindTransfer("sys", "clk50") self.comb += [ self.hashproc.i.eq(self.command.fields.hash_process), hash_proc_50.eq(self.hashproc.o) ] wipe_50 = Signal() self.submodules.wipe50 = BlindTransfer("sys", "clk50") self.comb += [ self.wipe50.i.eq(self.wipe.re), wipe_50.eq(self.wipe50.o) ] self.specials += Instance( "sha2_litex", i_clk_i=ClockSignal("clk50"), i_rst_ni=~ResetSignal("clk50"), i_secret_key_0=self.key0.storage, i_secret_key_1=self.key1.storage, i_secret_key_2=self.key2.storage, i_secret_key_3=self.key3.storage, i_secret_key_4=self.key4.storage, i_secret_key_5=self.key5.storage, i_secret_key_6=self.key6.storage, i_secret_key_7=self.key7.storage, i_secret_key_re=key_re_50, i_reg_hash_start=hash_start_50, i_reg_hash_process=hash_proc_50, o_ctrl_freeze=ctrl_freeze, i_sha_en=control_latch[0], i_endian_swap=control_latch[1], i_digest_swap=control_latch[2], i_hmac_en=control_latch[3], o_reg_hash_done=hmac_hash_done, o_sha_hash_done=sha256_hash_done, i_wipe_secret_re=wipe_50, i_wipe_secret_v=self.wipe.storage, o_digest_0=self.digest0.status, o_digest_1=self.digest1.status, o_digest_2=self.digest2.status, o_digest_3=self.digest3.status, o_digest_4=self.digest4.status, o_digest_5=self.digest5.status, o_digest_6=self.digest6.status, o_digest_7=self.digest7.status, o_msg_length=self.msg_length.status, o_error_code=self.error_code.status, i_msg_fifo_wdata=wdata, i_msg_fifo_write_mask=wmask, i_msg_fifo_we=wdata_we, i_msg_fifo_req=wdata_avail, o_msg_fifo_gnt=wdata_ready, o_local_fifo_wvalid=fifo_wvalid, i_local_fifo_wready=fifo_wready, o_local_fifo_wdata_mask=fifo_wdata_mask, i_local_fifo_rvalid=fifo_rvalid, o_local_fifo_rready=fifo_rready, i_local_fifo_rdata_mask=fifo_rdata_mask, o_err_valid=err_valid, i_err_valid_pending=self.ev.err_valid.pending, o_fifo_full_event=fifo_full, ) platform.add_source( os.path.join("deps", "opentitan", "hw", "ip", "hmac", "rtl", "hmac_pkg.sv")) platform.add_source( os.path.join("deps", "opentitan", "hw", "ip", "hmac", "rtl", "sha2.sv")) platform.add_source( os.path.join("deps", "opentitan", "hw", "ip", "hmac", "rtl", "sha2_pad.sv")) platform.add_source( os.path.join("deps", "opentitan", "hw", "ip", "prim", "rtl", "prim_packer.sv")) platform.add_source( os.path.join("deps", "opentitan", "hw", "ip", "hmac", "rtl", "hmac_core.sv")) platform.add_source( os.path.join("deps", "gateware", "gateware", "sha2_litex.sv"))
def __init__(self, platform): self.sink = stream.Endpoint([("data", 16)]) self.source = stream.Endpoint([("data", 8)]) self.bus = wishbone.Interface() # # # # chroma upsampler self.submodules.chroma_upsampler = chroma_upsampler = ClockDomainsRenamer("encoder")(YCbCr422to444()) self.comb += [ Record.connect(self.sink, chroma_upsampler.sink, omit=["data"]), chroma_upsampler.sink.y.eq(self.sink.data[:8]), chroma_upsampler.sink.cb_cr.eq(self.sink.data[8:]) ] fdct_fifo_rd = Signal() fdct_fifo_q = Signal(24) fdct_fifo_hf_full = Signal() fdct_data_d1 = Signal(24) fdct_data_d2 = Signal(24) fdct_data_d3 = Signal(24) fdct_data_d4 = Signal(24) fdct_data_d5 = Signal(24) self.sync.encoder += [ If(fdct_fifo_rd, fdct_data_d1.eq(Cat(chroma_upsampler.source.y, chroma_upsampler.source.cb, chroma_upsampler.source.cr)), ), fdct_data_d2.eq(fdct_data_d1), fdct_data_d3.eq(fdct_data_d2), fdct_data_d4.eq(fdct_data_d3), fdct_data_d5.eq(fdct_data_d4) ] self.comb += [ fdct_fifo_q.eq(fdct_data_d4), fdct_fifo_hf_full.eq(chroma_upsampler.source.valid), chroma_upsampler.source.ready.eq(fdct_fifo_rd) ] # output fifo output_fifo_almost_full = Signal() self.submodules.output_fifo = output_fifo = ClockDomainsRenamer("encoder")(stream.SyncFIFO([("data", 8)], 1024)) self.comb += [ output_fifo_almost_full.eq(output_fifo.fifo.level > 1024-128), Record.connect(output_fifo.source, self.source) ] # Wishbone cross domain crossing jpeg_bus = wishbone.Interface() self.specials += Instance("wb_async_reg", i_wbm_clk=ClockSignal(), i_wbm_rst=ResetSignal(), i_wbm_adr_i=self.bus.adr, i_wbm_dat_i=self.bus.dat_w, o_wbm_dat_o=self.bus.dat_r, i_wbm_we_i=self.bus.we, i_wbm_sel_i=self.bus.sel, i_wbm_stb_i=self.bus.stb, o_wbm_ack_o=self.bus.ack, o_wbm_err_o=self.bus.err, #o_wbm_rty_o=, i_wbm_cyc_i=self.bus.cyc, i_wbs_clk=ClockSignal("encoder"), i_wbs_rst=ResetSignal("encoder"), o_wbs_adr_o=jpeg_bus.adr, i_wbs_dat_i=jpeg_bus.dat_r, o_wbs_dat_o=jpeg_bus.dat_w, o_wbs_we_o=jpeg_bus.we, o_wbs_sel_o=jpeg_bus.sel, o_wbs_stb_o=jpeg_bus.stb, i_wbs_ack_i=jpeg_bus.ack, i_wbs_err_i=jpeg_bus.err, i_wbs_rty_i=0, o_wbs_cyc_o=jpeg_bus.cyc) # encoder self.specials += Instance("JpegEnc", i_CLK=ClockSignal("encoder"), i_RST=ResetSignal("encoder"), i_OPB_ABus=Cat(Signal(2), jpeg_bus.adr) & 0x3ff, i_OPB_BE=jpeg_bus.sel, i_OPB_DBus_in=jpeg_bus.dat_w, i_OPB_RNW=~jpeg_bus.we, i_OPB_select=jpeg_bus.stb & jpeg_bus.cyc, o_OPB_DBus_out=jpeg_bus.dat_r, o_OPB_XferAck=jpeg_bus.ack, #o_OPB_retry=, #o_OPB_toutSup=, o_OPB_errAck=jpeg_bus.err, o_fdct_fifo_rd=fdct_fifo_rd, i_fdct_fifo_q=fdct_fifo_q, i_fdct_fifo_hf_full=fdct_fifo_hf_full, #o_fdct_fifo_dval_o=, o_ram_byte=output_fifo.sink.data, o_ram_wren=output_fifo.sink.valid, #o_ram_wraddr=, #o_frame_size=, i_outif_almost_full=output_fifo_almost_full) # add vhdl sources platform.add_source_dir(os.path.join("gateware", "encoder", "vhdl")) # add verilog sources platform.add_source(os.path.join("gateware", "encoder", "verilog", "wb_async_reg.v"))
def __init__(self, platform, connector="fmc", gen="gen3", with_global_analyzer = False, with_sector2mem_analyzer = False, with_mem2sector_analyzer = False): assert connector in ["fmc", "sfp", "pcie"] assert gen in ["gen1", "gen2", "gen3"] sys_clk_freq = int(200e6) sata_clk_freq = {"gen1": 75e6, "gen2": 150e6, "gen3": 300e6}[gen] # CRG -------------------------------------------------------------------------------------- self.submodules.crg = _CRG(platform, sys_clk_freq) # SoCMini ---------------------------------------------------------------------------------- SoCMini.__init__(self, platform, sys_clk_freq, ident = "LiteSATA bench on KC705", ident_version = True, with_uart = True, uart_name = "bridge") # SATA ------------------------------------------------------------------------------------- # RefClk sata_refclk = None if connector != "fmc": # Generate 150MHz from PLL. self.clock_domains.cd_sata_refclk = ClockDomain() self.crg.pll.create_clkout(self.cd_sata_refclk, 150e6) sata_refclk = ClockSignal("sata_refclk") platform.add_platform_command("set_property SEVERITY {{Warning}} [get_drc_checks REQP-52]") # PHY self.submodules.sata_phy = LiteSATAPHY(platform.device, refclk = sata_refclk, pads = platform.request(connector+"2sata"), gen = gen, clk_freq = sys_clk_freq, data_width = 16) self.add_csr("sata_phy") # Core self.submodules.sata_core = LiteSATACore(self.sata_phy) # Crossbar self.submodules.sata_crossbar = LiteSATACrossbar(self.sata_core) # BIST self.submodules.sata_bist = LiteSATABIST(self.sata_crossbar, with_csr=True) self.add_csr("sata_bist") # Sector2Mem DMA bus = wishbone.Interface(data_width=32, adr_width=32) self.submodules.sata_sector2mem = LiteSATASector2MemDMA(self.sata_crossbar.get_port(), bus) self.bus.add_master("sata_sector2mem", master=bus) self.add_csr("sata_sector2mem") # Mem2Sector DMA bus = wishbone.Interface(data_width=32, adr_width=32) self.submodules.sata_mem2sector = LiteSATAMem2SectorDMA(bus, self.sata_crossbar.get_port()) self.bus.add_master("sata_mem2sector", master=bus) self.add_csr("sata_mem2sector") # Timing constraints platform.add_period_constraint(self.sata_phy.crg.cd_sata_tx.clk, 1e9/sata_clk_freq) platform.add_period_constraint(self.sata_phy.crg.cd_sata_rx.clk, 1e9/sata_clk_freq) self.platform.add_false_path_constraints( self.crg.cd_sys.clk, self.sata_phy.crg.cd_sata_tx.clk, self.sata_phy.crg.cd_sata_rx.clk) # Leds ------------------------------------------------------------------------------------- # sys_clk sys_counter = Signal(32) self.sync.sys += sys_counter.eq(sys_counter + 1) self.comb += platform.request("user_led", 0).eq(sys_counter[26]) # tx_clk tx_counter = Signal(32) self.sync.sata_tx += tx_counter.eq(tx_counter + 1) self.comb += platform.request("user_led", 1).eq(tx_counter[26]) # rx_clk rx_counter = Signal(32) self.sync.sata_rx += rx_counter.eq(rx_counter + 1) self.comb += platform.request("user_led", 2).eq(rx_counter[26]) # ready self.comb += platform.request("user_led", 3).eq(self.sata_phy.ctrl.ready) # Analyzers --------------------------------------------------------------------------------- if with_global_analyzer: analyzer_signals = [ self.sata_phy.phy.tx_init.fsm, self.sata_phy.phy.rx_init.fsm, self.sata_phy.ctrl.fsm, self.sata_phy.ctrl.ready, self.sata_phy.source, self.sata_phy.sink, self.sata_core.command.sink, self.sata_core.command.source, self.sata_core.link.rx.fsm, self.sata_core.link.tx.fsm, self.sata_core.transport.rx.fsm, self.sata_core.transport.tx.fsm, self.sata_core.command.rx.fsm, self.sata_core.command.tx.fsm, ] self.submodules.global_analyzer = LiteScopeAnalyzer(analyzer_signals, 512, csr_csv="global_analyzer.csv") self.add_csr("global_analyzer") if with_sector2mem_analyzer: analyzer_signals = [ self.sata_sector2mem.start.re, self.sata_sector2mem.fsm, self.sata_sector2mem.port.sink, self.sata_sector2mem.port.source, self.sata_sector2mem.bus, ] self.submodules.sector2mem_analyzer = LiteScopeAnalyzer(analyzer_signals, 2048, csr_csv="sector2mem_analyzer.csv") self.add_csr("sector2mem_analyzer") if with_mem2sector_analyzer: analyzer_signals = [ self.sata_mem2sector.start.re, self.sata_mem2sector.fsm, self.sata_mem2sector.port.sink, self.sata_mem2sector.port.source, self.sata_mem2sector.bus, ] self.submodules.mem2sector_analyzer = LiteScopeAnalyzer(analyzer_signals, 2048, csr_csv="mem2sector_analyzer.csv") self.add_csr("mem2sector_analyzer")
def __init__(self, pads=None, font_filename="cp437.bin", screen_init_filename="screen-init.bin"): # Wishbone interface self.bus = bus = wishbone.Interface(data_width=8) # Acknowledge immediately self.sync += [ bus.ack.eq(0), If (bus.cyc & bus.stb & ~bus.ack, bus.ack.eq(1)) ] # RAM initialization screen_init = read_ram_init_file(screen_init_filename, 4800) font = read_ram_init_file(font_filename, 4096) ram_init = screen_init + font # Create RAM mem = Memory(width=8, depth=8896, init=ram_init) self.specials += mem wrport = mem.get_port(write_capable=True, clock_domain="sys") self.specials += wrport rdport = mem.get_port(write_capable=False, clock_domain="vga") self.specials += rdport # Memory map internal block RAM to Wishbone interface self.sync += [ wrport.we.eq(0), If (bus.cyc & bus.stb & bus.we, wrport.we.eq(1), wrport.adr.eq(bus.adr), wrport.dat_w.eq(bus.dat_w), ) ] # Display resolution WIDTH = 640 HEIGHT = 480 # Offset to font data in RAM FONT_ADDR = 80 * 30 * 2 # VGA output self.red = red = Signal(8) if pads is None else pads.red self.green = green = Signal(8) if pads is None else pads.green self.blue = blue = Signal(8) if pads is None else pads.blue self.hsync = hsync = Signal() if pads is None else pads.hsync self.vsync = vsync = Signal() if pads is None else pads.vsync # VGA timings H_SYNC_PULSE = 96 H_BACK_PORCH = 48 + H_SYNC_PULSE H_DATA = WIDTH + H_BACK_PORCH H_FRONT_PORCH = 16 + H_DATA V_SYNC_PULSE = 2 V_BACK_PORCH = 29 + V_SYNC_PULSE V_DATA = HEIGHT + V_BACK_PORCH V_FRONT_PORCH = 10 + V_DATA pixel_counter = Signal(10) line_counter = Signal(10) # Read address in text RAM text_addr = Signal(16) # Read address in text RAM at line start text_addr_start = Signal(16) # Current line within a character, 0 to 15 fline = Signal(4) # Current x position within a character, 0 to 7 fx = Signal(3) # Current and next byte for a character line fbyte = Signal(8) next_byte = Signal(8) # Current foreground color fgcolor = Signal(24) next_fgcolor = Signal(24) # Current background color bgcolor = Signal(24) # Current fg/bg color index from RAM color = Signal(8) # Color index and lookup color_index = Signal(4) color_lookup = Signal(24) # VGA palette palette = [ 0x000000, 0x0000aa, 0x00aa00, 0x00aaaa, 0xaa0000, 0xaa00aa, 0xaa5500, 0xaaaaaa, 0x555555, 0x5555ff, 0x55ff55, 0x55ffff, 0xff5555, 0xff55ff, 0xffff55, 0xffffff ] cases = {} for i in range(16): cases[i] = color_lookup.eq(palette[i]) self.comb += Case(color_index, cases) self.sync.vga += [ # Default values red.eq(0), green.eq(0), blue.eq(0), # Show pixels If((line_counter >= V_BACK_PORCH) & (line_counter < V_DATA), If((pixel_counter >= H_BACK_PORCH) & (pixel_counter < H_DATA), If(fbyte[7], red.eq(fgcolor[16:24]), green.eq(fgcolor[8:16]), blue.eq(fgcolor[0:8]) ).Else( red.eq(bgcolor[16:24]), green.eq(bgcolor[8:16]), blue.eq(bgcolor[0:8]) ), fbyte.eq(Cat(Signal(), fbyte[:-1])) ) ), # Load next character code, font line and color If(fx == 1, # schedule reading the character code rdport.adr.eq(text_addr), text_addr.eq(text_addr + 1) ), If(fx == 2, # Schedule reading the color rdport.adr.eq(text_addr), text_addr.eq(text_addr + 1) ), If(fx == 3, # Read character code, and set address for font line rdport.adr.eq(FONT_ADDR + Cat(Signal(4), rdport.dat_r) + fline) ), If(fx == 4, # Read color color.eq(rdport.dat_r) ), If(fx == 5, # Read font line, and set color index to get foreground color next_byte.eq(rdport.dat_r), color_index.eq(color[0:4]), ), If(fx == 6, # Get next foreground color, and set color index for background color next_fgcolor.eq(color_lookup), color_index.eq(color[4:8]) ), If(fx == 7, # Set background color and everything for the next 8 pixels bgcolor.eq(color_lookup), fgcolor.eq(next_fgcolor), fbyte.eq(next_byte) ), fx.eq(fx + 1), If(fx == 7, fx.eq(0)), # Horizontal timing for one line pixel_counter.eq(pixel_counter + 1), If(pixel_counter < H_SYNC_PULSE, hsync.eq(0) ).Elif (pixel_counter < H_BACK_PORCH, hsync.eq(1) ), If(pixel_counter == H_BACK_PORCH - 9, # Prepare reading first character of next line fx.eq(0), text_addr.eq(text_addr_start) ), If(pixel_counter == H_FRONT_PORCH, # Initilize next line pixel_counter.eq(0), line_counter.eq(line_counter + 1), # Font height is 16 pixels fline.eq(fline + 1), If(fline == 15, fline.eq(0), text_addr_start.eq(text_addr_start + 2 * 80) ) ), # Vertical timing for one screen If(line_counter < V_SYNC_PULSE, vsync.eq(0) ).Elif(line_counter < V_BACK_PORCH, vsync.eq(1) ), If(line_counter == V_FRONT_PORCH, # End of image line_counter.eq(0) ), If(line_counter == V_BACK_PORCH - 1, # Prepare generating next image data fline.eq(0), text_addr_start.eq(0) ) ]
def __init__(self, platform, variant="standard"): self.platform = platform self.variant = variant self.reset = Signal() self.interrupt = Signal(8) mem_dw, mmio_dw, num_cores = CPU_SIZE_PARAMS[self.variant] self.mem_axi = mem_axi = axi.AXIInterface(data_width=mem_dw, address_width=32, id_width=4) self.mmio_axi = mmio_axi = axi.AXIInterface(data_width=mmio_dw, address_width=32, id_width=4) self.l2fb_axi = l2fb_axi = axi.AXIInterface(data_width=mmio_dw, address_width=32, id_width=4) self.mmio_wb = mmio_wb = wishbone.Interface(data_width=mmio_dw, adr_width=32 - log2_int(mmio_dw // 8)) self.l2fb_wb = l2fb_wb = wishbone.Interface(data_width=mmio_dw, adr_width=32 - log2_int(mmio_dw // 8)) self.memory_buses = [ mem_axi ] # Peripheral buses (Connected to main SoC's bus). self.periph_buses = [ mmio_wb ] # Memory buses (Connected directly to LiteDRAM). self.dma_bus = l2fb_wb # DMA bus (Arbitrated and connected to SoC's bus). # # # self.cpu_params = dict( # Clk / Rst. i_clock=ClockSignal("sys"), i_reset=ResetSignal("sys") | self.reset, # Debug (ignored). i_debug_clock=0, i_debug_reset=ResetSignal() | self.reset, o_debug_clockeddmi_dmi_req_ready=Open(), i_debug_clockeddmi_dmi_req_valid=0, i_debug_clockeddmi_dmi_req_bits_addr=0, i_debug_clockeddmi_dmi_req_bits_data=0, i_debug_clockeddmi_dmi_req_bits_op=0, i_debug_clockeddmi_dmi_resp_ready=0, o_debug_clockeddmi_dmi_resp_valid=Open(), o_debug_clockeddmi_dmi_resp_bits_data=Open(), o_debug_clockeddmi_dmi_resp_bits_resp=Open(), i_debug_clockeddmi_dmiClock=0, i_debug_clockeddmi_dmiReset=ResetSignal() | self.reset, o_debug_ndreset=Open(), o_debug_dmactive=Open(), i_debug_dmactiveAck=0, # IRQ. i_interrupts=self.interrupt, # AXI Memory (L1-cached). i_mem_axi4_0_aw_ready=mem_axi.aw.ready, o_mem_axi4_0_aw_valid=mem_axi.aw.valid, o_mem_axi4_0_aw_bits_id=mem_axi.aw.id, o_mem_axi4_0_aw_bits_addr=mem_axi.aw.addr, o_mem_axi4_0_aw_bits_len=mem_axi.aw.len, o_mem_axi4_0_aw_bits_size=mem_axi.aw.size, o_mem_axi4_0_aw_bits_burst=mem_axi.aw.burst, o_mem_axi4_0_aw_bits_lock=mem_axi.aw.lock, o_mem_axi4_0_aw_bits_cache=mem_axi.aw.cache, o_mem_axi4_0_aw_bits_prot=mem_axi.aw.prot, o_mem_axi4_0_aw_bits_qos=mem_axi.aw.qos, i_mem_axi4_0_w_ready=mem_axi.w.ready, o_mem_axi4_0_w_valid=mem_axi.w.valid, o_mem_axi4_0_w_bits_data=mem_axi.w.data, o_mem_axi4_0_w_bits_strb=mem_axi.w.strb, o_mem_axi4_0_w_bits_last=mem_axi.w.last, o_mem_axi4_0_b_ready=mem_axi.b.ready, i_mem_axi4_0_b_valid=mem_axi.b.valid, i_mem_axi4_0_b_bits_id=mem_axi.b.id, i_mem_axi4_0_b_bits_resp=mem_axi.b.resp, i_mem_axi4_0_ar_ready=mem_axi.ar.ready, o_mem_axi4_0_ar_valid=mem_axi.ar.valid, o_mem_axi4_0_ar_bits_id=mem_axi.ar.id, o_mem_axi4_0_ar_bits_addr=mem_axi.ar.addr, o_mem_axi4_0_ar_bits_len=mem_axi.ar.len, o_mem_axi4_0_ar_bits_size=mem_axi.ar.size, o_mem_axi4_0_ar_bits_burst=mem_axi.ar.burst, o_mem_axi4_0_ar_bits_lock=mem_axi.ar.lock, o_mem_axi4_0_ar_bits_cache=mem_axi.ar.cache, o_mem_axi4_0_ar_bits_prot=mem_axi.ar.prot, o_mem_axi4_0_ar_bits_qos=mem_axi.ar.qos, o_mem_axi4_0_r_ready=mem_axi.r.ready, i_mem_axi4_0_r_valid=mem_axi.r.valid, i_mem_axi4_0_r_bits_id=mem_axi.r.id, i_mem_axi4_0_r_bits_data=mem_axi.r.data, i_mem_axi4_0_r_bits_resp=mem_axi.r.resp, i_mem_axi4_0_r_bits_last=mem_axi.r.last, # AXI MMIO (not cached). i_mmio_axi4_0_aw_ready=mmio_axi.aw.ready, o_mmio_axi4_0_aw_valid=mmio_axi.aw.valid, o_mmio_axi4_0_aw_bits_id=mmio_axi.aw.id, o_mmio_axi4_0_aw_bits_addr=mmio_axi.aw.addr, o_mmio_axi4_0_aw_bits_len=mmio_axi.aw.len, o_mmio_axi4_0_aw_bits_size=mmio_axi.aw.size, o_mmio_axi4_0_aw_bits_burst=mmio_axi.aw.burst, o_mmio_axi4_0_aw_bits_lock=mmio_axi.aw.lock, o_mmio_axi4_0_aw_bits_cache=mmio_axi.aw.cache, o_mmio_axi4_0_aw_bits_prot=mmio_axi.aw.prot, o_mmio_axi4_0_aw_bits_qos=mmio_axi.aw.qos, i_mmio_axi4_0_w_ready=mmio_axi.w.ready, o_mmio_axi4_0_w_valid=mmio_axi.w.valid, o_mmio_axi4_0_w_bits_data=mmio_axi.w.data, o_mmio_axi4_0_w_bits_strb=mmio_axi.w.strb, o_mmio_axi4_0_w_bits_last=mmio_axi.w.last, o_mmio_axi4_0_b_ready=mmio_axi.b.ready, i_mmio_axi4_0_b_valid=mmio_axi.b.valid, i_mmio_axi4_0_b_bits_id=mmio_axi.b.id, i_mmio_axi4_0_b_bits_resp=mmio_axi.b.resp, i_mmio_axi4_0_ar_ready=mmio_axi.ar.ready, o_mmio_axi4_0_ar_valid=mmio_axi.ar.valid, o_mmio_axi4_0_ar_bits_id=mmio_axi.ar.id, o_mmio_axi4_0_ar_bits_addr=mmio_axi.ar.addr, o_mmio_axi4_0_ar_bits_len=mmio_axi.ar.len, o_mmio_axi4_0_ar_bits_size=mmio_axi.ar.size, o_mmio_axi4_0_ar_bits_burst=mmio_axi.ar.burst, o_mmio_axi4_0_ar_bits_lock=mmio_axi.ar.lock, o_mmio_axi4_0_ar_bits_cache=mmio_axi.ar.cache, o_mmio_axi4_0_ar_bits_prot=mmio_axi.ar.prot, o_mmio_axi4_0_ar_bits_qos=mmio_axi.ar.qos, o_mmio_axi4_0_r_ready=mmio_axi.r.ready, i_mmio_axi4_0_r_valid=mmio_axi.r.valid, i_mmio_axi4_0_r_bits_id=mmio_axi.r.id, i_mmio_axi4_0_r_bits_data=mmio_axi.r.data, i_mmio_axi4_0_r_bits_resp=mmio_axi.r.resp, i_mmio_axi4_0_r_bits_last=mmio_axi.r.last, # AXI L2FB (Slave, for e.g., DMA). o_l2_frontend_bus_axi4_0_aw_ready=l2fb_axi.aw.ready, i_l2_frontend_bus_axi4_0_aw_valid=l2fb_axi.aw.valid, i_l2_frontend_bus_axi4_0_aw_bits_id=l2fb_axi.aw.id, i_l2_frontend_bus_axi4_0_aw_bits_addr=l2fb_axi.aw.addr, i_l2_frontend_bus_axi4_0_aw_bits_len=l2fb_axi.aw.len, i_l2_frontend_bus_axi4_0_aw_bits_size=l2fb_axi.aw.size, i_l2_frontend_bus_axi4_0_aw_bits_burst=l2fb_axi.aw.burst, i_l2_frontend_bus_axi4_0_aw_bits_lock=l2fb_axi.aw.lock, i_l2_frontend_bus_axi4_0_aw_bits_cache=l2fb_axi.aw.cache, i_l2_frontend_bus_axi4_0_aw_bits_prot=l2fb_axi.aw.prot, i_l2_frontend_bus_axi4_0_aw_bits_qos=l2fb_axi.aw.qos, o_l2_frontend_bus_axi4_0_w_ready=l2fb_axi.w.ready, i_l2_frontend_bus_axi4_0_w_valid=l2fb_axi.w.valid, i_l2_frontend_bus_axi4_0_w_bits_data=l2fb_axi.w.data, i_l2_frontend_bus_axi4_0_w_bits_strb=l2fb_axi.w.strb, i_l2_frontend_bus_axi4_0_w_bits_last=l2fb_axi.w.last, i_l2_frontend_bus_axi4_0_b_ready=l2fb_axi.b.ready, o_l2_frontend_bus_axi4_0_b_valid=l2fb_axi.b.valid, o_l2_frontend_bus_axi4_0_b_bits_id=l2fb_axi.b.id, o_l2_frontend_bus_axi4_0_b_bits_resp=l2fb_axi.b.resp, o_l2_frontend_bus_axi4_0_ar_ready=l2fb_axi.ar.ready, i_l2_frontend_bus_axi4_0_ar_valid=l2fb_axi.ar.valid, i_l2_frontend_bus_axi4_0_ar_bits_id=l2fb_axi.ar.id, i_l2_frontend_bus_axi4_0_ar_bits_addr=l2fb_axi.ar.addr, i_l2_frontend_bus_axi4_0_ar_bits_len=l2fb_axi.ar.len, i_l2_frontend_bus_axi4_0_ar_bits_size=l2fb_axi.ar.size, i_l2_frontend_bus_axi4_0_ar_bits_burst=l2fb_axi.ar.burst, i_l2_frontend_bus_axi4_0_ar_bits_lock=l2fb_axi.ar.lock, i_l2_frontend_bus_axi4_0_ar_bits_cache=l2fb_axi.ar.cache, i_l2_frontend_bus_axi4_0_ar_bits_prot=l2fb_axi.ar.prot, i_l2_frontend_bus_axi4_0_ar_bits_qos=l2fb_axi.ar.qos, i_l2_frontend_bus_axi4_0_r_ready=l2fb_axi.r.ready, o_l2_frontend_bus_axi4_0_r_valid=l2fb_axi.r.valid, o_l2_frontend_bus_axi4_0_r_bits_id=l2fb_axi.r.id, o_l2_frontend_bus_axi4_0_r_bits_data=l2fb_axi.r.data, o_l2_frontend_bus_axi4_0_r_bits_resp=l2fb_axi.r.resp, o_l2_frontend_bus_axi4_0_r_bits_last=l2fb_axi.r.last, ) # additional per-core debug signals: self.cpu_params.update({ 'i_resetctrl_hartIsInReset_%s' % i: Open() for i in range(num_cores) }) # Adapt AXI interfaces to Wishbone. mmio_a2w = axi.AXI2Wishbone(mmio_axi, mmio_wb, base_address=0) self.submodules += mmio_a2w l2fb_a2w = axi.Wishbone2AXI(l2fb_wb, l2fb_axi, base_address=0) self.submodules += l2fb_a2w # Add Verilog sources. self.add_sources(platform, variant)
def __init__(self, pad, nleds, sys_clk_freq, bus_mastering=False, bus_base=None, revision="new", init=None): if bus_mastering: self.bus = bus = wishbone.Interface(data_width=32) else: # Memory. mem = Memory(32, nleds, init=init) port = mem.get_port() self.specials += mem, port # Wishone Memory. self.submodules.wb_mem = wishbone.SRAM( mem_or_size=mem, read_only=False, bus=wishbone.Interface(data_width=32)) self.bus = self.wb_mem.bus # Internal Signals. led_count = Signal(max=nleds) led_data = Signal(24) xfer_start = Signal() xfer_done = Signal() xfer_data = Signal(24) # Timings self.trst = trst = { "old": 50e-6 * 1.25, "new": 280e-6 * 1.25 }[revision] self.t0h = t0h = 0.40e-6 self.t0l = t0l = 0.85e-6 self.t1h = t1h = 0.80e-6 self.t1l = t1l = 0.45e-6 # Timers. trst_timer = WaitTimer(int(trst * sys_clk_freq)) self.submodules += trst_timer t0h_timer = WaitTimer(int(t0h * sys_clk_freq)) t0l_timer = WaitTimer(int(t0l * sys_clk_freq) - 1) # Compensate Xfer FSM latency. self.submodules += t0h_timer, t0l_timer t1h_timer = WaitTimer(int(t1h * sys_clk_freq)) t1l_timer = WaitTimer(int(t1l * sys_clk_freq) - 1) # Compensate Xfer FSM latency. self.submodules += t1h_timer, t1l_timer # Main FSM. self.submodules.fsm = fsm = FSM(reset_state="RST") fsm.act("RST", NextValue(led_count, 0), trst_timer.wait.eq(xfer_done), If(trst_timer.done, NextState("LED-READ"))) if bus_mastering: fsm.act( "LED-READ", bus.stb.eq(1), bus.cyc.eq(1), bus.we.eq(0), bus.sel.eq(2**(bus.data_width // 8) - 1), bus.adr.eq(bus_base[2:] + led_count), If(bus.ack, NextValue(led_data, bus.dat_r), NextState("LED-SEND"))) else: self.comb += port.adr.eq(led_count) fsm.act("LED-READ", NextState("LED-LATCH")) fsm.act("LED-LATCH", NextValue(led_data, port.dat_r), NextState("LED-SEND")) fsm.act("LED-SEND", If(xfer_done, xfer_start.eq(1), NextState("LED-SHIFT"))) fsm.act( "LED-SHIFT", If(led_count == (nleds - 1), NextState("RST")).Else(NextValue(led_count, led_count + 1), NextState("LED-READ"))) # XFER FSM. xfer_bit = Signal(5) xfer_fsm = FSM(reset_state="IDLE") self.submodules += xfer_fsm xfer_fsm.act( "IDLE", xfer_done.eq(1), If(xfer_start, NextValue(xfer_bit, 24 - 1), NextValue(xfer_data, led_data), NextState("RUN"))) xfer_fsm.act( "RUN", # Send a one. If( xfer_data[-1], t1h_timer.wait.eq(1), t1l_timer.wait.eq(t1h_timer.done), pad.eq(~t1h_timer.done), # Send a zero. ).Else( t0h_timer.wait.eq(1), t0l_timer.wait.eq(t0h_timer.done), pad.eq(~t0h_timer.done), ), # When bit has been sent: If( t0l_timer.done | t1l_timer.done, # Clear wait on timers. t0h_timer.wait.eq(0), t0l_timer.wait.eq(0), t1h_timer.wait.eq(0), t1l_timer.wait.eq(0), # Shift xfer_data. NextValue(xfer_data, Cat(Signal(), xfer_data)), # Decrement xfer_bit. NextValue(xfer_bit, xfer_bit - 1), # When xfer_bit reaches 0. If(xfer_bit == 0, NextState("IDLE"))))
def __init__(self, platform, cpu_reset_address, variant=None): assert variant in (None, "debug"), "Unsupported variant %s" % variant self.reset = Signal() self.ibus = i = wishbone.Interface() self.dbus = d = wishbone.Interface() i_err = Signal() d_err = Signal() self.interrupt = Signal(32) # Output reset signal -- set to 1 when CPU reset is asserted self.debug_reset = Signal() if variant == None: cpu_reset = ResetSignal() cpu_args = {} cpu_filename = "VexRiscv.v" elif variant == "debug": cpu_reset = Signal() cpu_args = {} cpu_filename = "VexRiscv-Debug.v" self.i_cmd_valid = Signal() self.i_cmd_payload_wr = Signal() self.i_cmd_payload_address = Signal(8) self.i_cmd_payload_data = Signal(32) self.o_cmd_ready = Signal() self.o_rsp_data = Signal(32) self.o_resetOut = Signal() reset_debug_logic = Signal() self.transfer_complete = Signal() self.transfer_in_progress = Signal() self.transfer_wait_for_ack = Signal() self.debug_bus = wishbone.Interface() self.sync += [ self.debug_bus.dat_r.eq(self.o_rsp_data), cpu_reset.eq(reset_debug_logic | ResetSignal()), ] self.sync += [ # CYC is held high for the duration of the transfer. # STB is kept high when the transfer finishes (write) # or the master is waiting for data (read), and stays # there until ACK, ERR, or RTY are asserted. If((self.debug_bus.stb & self.debug_bus.cyc) & (~self.transfer_in_progress) & (~self.transfer_complete) & (~self.transfer_wait_for_ack), self.i_cmd_payload_data.eq(self.debug_bus.dat_w), self.i_cmd_payload_address.eq((self.debug_bus.adr[0:6] << 2) | 0), self.i_cmd_payload_wr.eq(self.debug_bus.we), self.i_cmd_valid.eq(1), self.transfer_in_progress.eq(1), self.transfer_complete.eq(0), self.debug_bus.ack.eq(0) ).Elif(self.transfer_in_progress, If(self.o_cmd_ready, self.i_cmd_valid.eq(0), self.i_cmd_payload_wr.eq(0), self.transfer_complete.eq(1), self.transfer_in_progress.eq(0) ) ).Elif(self.transfer_complete, self.transfer_complete.eq(0), self.debug_bus.ack.eq(1), self.transfer_wait_for_ack.eq(1) ).Elif(self.transfer_wait_for_ack & ~(self.debug_bus.stb & self.debug_bus.cyc), self.transfer_wait_for_ack.eq(0), self.debug_bus.ack.eq(0) ), # Force a Wishbone error if transferring during a reset sequence. # Because o_resetOut is multiple cycles and i.stb/d.stb should # deassert one cycle after i_err/i_ack/d_err/d_ack are asserted, # this will give i_err and o_err enough time to be reset to 0 # once the reset cycle finishes. If(self.o_resetOut, If(i.cyc & i.stb, i_err.eq(1)).Else(i_err.eq(0)), If(d.cyc & d.stb, d_err.eq(1)).Else(d_err.eq(0)), reset_debug_logic.eq(1)) .Else( reset_debug_logic.eq(0) ) ] cpu_args.update({ "i_debugReset": ResetSignal(), "i_debug_bus_cmd_valid": self.i_cmd_valid, "i_debug_bus_cmd_payload_wr": self.i_cmd_payload_wr, "i_debug_bus_cmd_payload_address": self.i_cmd_payload_address, "i_debug_bus_cmd_payload_data": self.i_cmd_payload_data, "o_debug_bus_cmd_ready": self.o_cmd_ready, "o_debug_bus_rsp_data": self.o_rsp_data, "o_debug_resetOut": self.o_resetOut }) self.comb += [ i.err.eq(i_err), d.err.eq(d_err), ] self.specials += Instance("VexRiscv", **cpu_args, i_clk=ClockSignal(), i_reset=cpu_reset | self.reset, i_externalResetVector=cpu_reset_address, i_externalInterruptArray=self.interrupt, i_timerInterrupt=0, o_iBusWishbone_ADR=i.adr, o_iBusWishbone_DAT_MOSI=i.dat_w, o_iBusWishbone_SEL=i.sel, o_iBusWishbone_CYC=i.cyc, o_iBusWishbone_STB=i.stb, o_iBusWishbone_WE=i.we, o_iBusWishbone_CTI=i.cti, o_iBusWishbone_BTE=i.bte, i_iBusWishbone_DAT_MISO=i.dat_r, i_iBusWishbone_ACK=i.ack, i_iBusWishbone_ERR=i_err, o_dBusWishbone_ADR=d.adr, o_dBusWishbone_DAT_MOSI=d.dat_w, o_dBusWishbone_SEL=d.sel, o_dBusWishbone_CYC=d.cyc, o_dBusWishbone_STB=d.stb, o_dBusWishbone_WE=d.we, o_dBusWishbone_CTI=d.cti, o_dBusWishbone_BTE=d.bte, i_dBusWishbone_DAT_MISO=d.dat_r, i_dBusWishbone_ACK=d.ack, i_dBusWishbone_ERR=d_err) # add verilog sources self.add_sources(platform, cpu_filename)
def __init__(self, platform, variant="standard"): self.platform = platform self.variant = variant self.reset = Signal() self.idbus = idbus = wishbone.Interface() self.periph_buses = [idbus] # Peripheral buses (Connected to main SoC's bus). self.memory_buses = [] # Memory buses (Connected directly to LiteDRAM). # # # # FemtoRV Mem Bus. # ---------------- mbus = Record([ ("addr", 32), ("wdata", 32), ("wmask", 4), ("rdata", 32), ("rstrb", 1), ("rbusy", 1), ("wbusy", 1), ]) # FemtoRV Instance. # ----------------- self.cpu_params = dict( # Parameters. p_ADDR_WIDTH = 32, p_RESET_ADDR = Constant(0, 32), # Clk / Rst. i_clk = ClockSignal("sys"), i_reset = ~ResetSignal("sys"), # Active Low. # I/D Bus. o_mem_addr = mbus.addr, o_mem_wdata = mbus.wdata, o_mem_wmask = mbus.wmask, i_mem_rdata = mbus.rdata, o_mem_rstrb = mbus.rstrb, i_mem_rbusy = mbus.rbusy, i_mem_wbusy = mbus.wbusy, ) # Adapt FemtoRV Mem Bus to Wishbone. # ---------------------------------- # Bytes to Words addressing conversion. self.comb += idbus.adr.eq(mbus.addr[2:]) # Wdata/WMask direct connection. self.comb += idbus.dat_w.eq(mbus.wdata) self.comb += idbus.sel.eq(mbus.wmask) # Control adaptation. latch = Signal() write = mbus.wmask != 0 read = mbus.rstrb self.submodules.fsm = fsm = FSM(reset_state="IDLE") fsm.act("IDLE", idbus.stb.eq(read | write), idbus.cyc.eq(read | write), idbus.we.eq(write), If(read, mbus.rbusy.eq(1), NextState("READ") ).Elif(write, mbus.wbusy.eq(1), NextState("WRITE") ) ) fsm.act("READ", idbus.stb.eq(1), idbus.cyc.eq(1), mbus.rbusy.eq(1), If(idbus.ack, latch.eq(1), NextState("IDLE") ) ) fsm.act("WRITE", idbus.stb.eq(1), idbus.cyc.eq(1), idbus.we.eq(1), mbus.wbusy.eq(1), If(idbus.ack, NextState("IDLE") ) ) # Latch RData on Wishbone ack. self.sync += If(latch, mbus.rdata.eq(idbus.dat_r)) # Add Verilog sources. # -------------------- self.add_sources(platform)
def __init__(self, pads, dummy=15, div=2, with_bitbang=True, endianness="big"): """ Simple SPI flash. Supports multi-bit pseudo-parallel reads (aka Dual or Quad I/O Fast Read). Only supports mode3 (cpol=1, cpha=1). """ SpiFlashCommon.__init__(self, pads) self.bus = bus = wishbone.Interface() spi_width = len(pads.dq) assert spi_width >= 2 if with_bitbang: self.bitbang = CSRStorage(4, reset_less=True, fields=[ CSRField("mosi", description="Output value for MOSI pin, valid whenever ``dir`` is ``0``."), CSRField("clk", description="Output value for SPI CLK pin."), CSRField("cs_n", description="Output value for SPI CSn pin."), CSRField("dir", description="Sets the direction for *ALL* SPI data pins except CLK and CSn.", values=[ ("0", "OUT", "SPI pins are all output"), ("1", "IN", "SPI pins are all input"), ]) ], description=""" Bitbang controls for SPI output. Only standard 1x SPI is supported, and as a result all four wires are ganged together. This means that it is only possible to perform half-duplex operations, using this SPI core. """) self.miso = CSRStatus(description="Incoming value of MISO signal.") self.bitbang_en = CSRStorage(description="Write a ``1`` here to disable memory-mapped mode and enable bitbang mode.") # # # cs_n = Signal(reset=1) clk = Signal() dq_oe = Signal() wbone_width = len(bus.dat_r) read_cmd_params = { 4: (_format_cmd(_QIOFR, 4), 4*8), 2: (_format_cmd(_DIOFR, 2), 2*8), 1: (_format_cmd(_FAST_READ, 1), 1*8) } read_cmd, cmd_width = read_cmd_params[spi_width] addr_width = 24 dq = TSTriple(spi_width) # Keep DQ2,DQ3 as outputs during bitbang, this ensures they activate ~WP or ~HOLD functions self.specials.dq0 = Tristate(pads.dq[0], o=dq.o[0], i=dq.i[0], oe=dq.oe) self.specials.dq1 = Tristate(pads.dq[1], o=dq.o[1], i=dq.i[1], oe=dq.oe) self.specials.dq2 = Tristate(pads.dq[2], o=dq.o[2], i=dq.i[2], oe=(dq.oe | self.bitbang_en.storage)) self.specials.dq3 = Tristate(pads.dq[3], o=dq.o[3], i=dq.i[3], oe=(dq.oe | self.bitbang_en.storage)) sr = Signal(max(cmd_width, addr_width, wbone_width)) if endianness == "big": self.comb += bus.dat_r.eq(sr) else: self.comb += bus.dat_r.eq(reverse_bytes(sr)) hw_read_logic = [ pads.clk.eq(clk), pads.cs_n.eq(cs_n), dq.o.eq(sr[-spi_width:]), dq.oe.eq(dq_oe) ] if with_bitbang: bitbang_logic = [ pads.clk.eq(self.bitbang.storage[1]), pads.cs_n.eq(self.bitbang.storage[2]), # In Dual/Quad mode, no single data pin is consistently # an input or output thanks to dual/quad reads, so we need a bit # to swap direction of the pins. Aside from this additional bit, # bitbang mode is identical for Single/Dual/Quad; dq[0] is mosi # and dq[1] is miso, meaning remaining data pin values don't # appear in CSR registers. If(self.bitbang.storage[3], dq.oe.eq(0) ).Else( dq.oe.eq(1) ), If(self.bitbang.storage[1], # CPOL=0/CPHA=0 or CPOL=1/CPHA=1 only. self.miso.status.eq(dq.i[1]) ), dq.o.eq(Cat(self.bitbang.storage[0], Replicate(1, spi_width-1))) ] self.comb += [ If(self.bitbang_en.storage, bitbang_logic ).Else( hw_read_logic ) ] else: self.comb += hw_read_logic if div < 2: raise ValueError("Unsupported value \'{}\' for div parameter for SpiFlash core".format(div)) else: i = Signal(max=div) dqi = Signal(spi_width) self.sync += [ If(i == div//2 - 1, clk.eq(1), dqi.eq(dq.i), ), If(i == div - 1, i.eq(0), clk.eq(0), sr.eq(Cat(dqi, sr[:-spi_width])) ).Else( i.eq(i + 1), ), ] # spi is byte-addressed, prefix by zeros z = Replicate(0, log2_int(wbone_width//8)) seq = [ (cmd_width//spi_width*div, [dq_oe.eq(1), cs_n.eq(0), sr[-cmd_width:].eq(read_cmd)]), (addr_width//spi_width*div, [sr[-addr_width:].eq(Cat(z, bus.adr))]), ((dummy + wbone_width//spi_width)*div, [dq_oe.eq(0)]), (1, [bus.ack.eq(1), cs_n.eq(1)]), (div, # tSHSL! [bus.ack.eq(0)]), (0, []), ] # accumulate timeline deltas t, tseq = 0, [] for dt, a in seq: tseq.append((t, a)) t += dt self.sync += timeline(bus.cyc & bus.stb & (i == div - 1), tseq)
def __init__(self, pads, rd_timing, wr_timing, page_rd_timing): self.bus = wishbone.Interface() config_status = self.config_status = CSRStatus(fields=[ CSRField("mode", size=32, description="The current configuration mode of the SRAM") ]) read_config = self.read_config = CSRStorage(fields=[ CSRField( "trigger", size=1, description= "Writing to this bit triggers the SRAM mode status read update", pulse=True) ]) # # # # min 150us, at 100MHz this is 15,000 cycles sram_zz = Signal(reset=1) load_config = Signal() self.sram_ready = Signal() reset_counter = Signal( 14, reset=50) # Cut short because 150us > FPGA config time self.sync += [ If(reset_counter != 0, reset_counter.eq(reset_counter - 1), self.sram_ready.eq(0)).Else(self.sram_ready.eq(1)), If(reset_counter == 1, load_config.eq(1)).Else(load_config.eq(0)) ] data = TSTriple(32) self.specials += data.get_tristate(pads.d) store = Signal() self.load = load = Signal() config = Signal() config_override = Signal() config_ce_n = Signal(reset=1) config_we_n = Signal(reset=1) config_oe_n = Signal(reset=1) comb_oe_n = Signal() comb_we_n = Signal() comb_zz_n = Signal() comb_ce_n = Signal() comb_dm_n = Signal(4) comb_adr = Signal(22) comb_data_o = Signal(32) comb_oe_n.reset, comb_we_n.reset = 1, 1 comb_zz_n.reset, comb_ce_n.reset = 1, 1 self.comb += [ comb_oe_n.eq(1), comb_we_n.eq(1), comb_zz_n.eq(sram_zz), comb_ce_n.eq(1), If( config_override, comb_oe_n.eq(config_oe_n), comb_we_n.eq(config_we_n), comb_ce_n.eq(config_ce_n), comb_zz_n.eq(1), If( config_ce_n, # DM should track CE_n comb_dm_n.eq(0xf), ).Else(comb_dm_n.eq(0x0)), comb_adr.eq(0x3fffff), comb_data_o.eq(0), ).Else( # Register data/address to avoid off-chip glitches If( sram_zz == 0, comb_adr.eq( 0xf0 ), # 1111_0000 page mode enabled, TCR = 85C, PAR enabled, full array PAR comb_dm_n.eq(0xf), ).Elif( self.bus.cyc & self.bus.stb, comb_adr.eq(self.bus.adr), comb_dm_n.eq(~self.bus.sel), If(self.bus.we, comb_data_o.eq(self.bus.dat_w)).Else(comb_oe_n.eq(0))), If(store | config, comb_we_n.eq(0)), If( store | config | (self.bus.cyc & self.bus.stb & ~self.bus.we), comb_ce_n.eq(0))) ] self.sync_oe_n = sync_oe_n = Signal() self.sync += sync_oe_n.eq( comb_oe_n) # Register internally to match ODDR self.comb += data.oe.eq(sync_oe_n) self.specials += [ Instance( "ODDR", p_DDR_CLK_EDGE="SAME_EDGE", i_C=ClockSignal(), i_R=ResetSignal(), i_S=0, i_CE=1, i_D1=comb_oe_n, i_D2=comb_oe_n, o_Q=pads.oe_n, ), Instance( "ODDR", p_DDR_CLK_EDGE="SAME_EDGE", i_C=ClockSignal(), i_R=ResetSignal(), i_S=0, i_CE=1, i_D1=comb_we_n, i_D2=comb_we_n, o_Q=pads.we_n, ), Instance( "ODDR", p_DDR_CLK_EDGE="SAME_EDGE", i_C=ClockSignal(), i_R=ResetSignal(), i_S=0, i_CE=1, i_D1=comb_zz_n, i_D2=comb_zz_n, o_Q=pads.zz_n, ), Instance( "ODDR", p_DDR_CLK_EDGE="SAME_EDGE", i_C=ClockSignal(), i_R=ResetSignal(), i_S=0, i_CE=1, i_D1=comb_ce_n, i_D2=comb_ce_n, o_Q=pads.ce_n, ), ] for i in range(4): self.specials += Instance( "ODDR", p_DDR_CLK_EDGE="SAME_EDGE", i_C=ClockSignal(), i_R=ResetSignal(), i_S=0, i_CE=1, i_D1=comb_dm_n[i], i_D2=comb_dm_n[i], o_Q=pads.dm_n[i], ), for i in range(22): self.specials += Instance( "ODDR", p_DDR_CLK_EDGE="SAME_EDGE", i_C=ClockSignal(), i_R=ResetSignal(), i_S=0, i_CE=1, i_D1=comb_adr[i], i_D2=comb_adr[i], o_Q=pads.adr[i], ), for i in range(32): self.specials += Instance( "ODDR", p_DDR_CLK_EDGE="SAME_EDGE", i_C=ClockSignal(), i_R=ResetSignal(), i_S=0, i_CE=1, i_D1=comb_data_o[i], i_D2=comb_data_o[i], o_Q=data.o[i], ), for i in range(32): self.specials += Instance("IDDR", p_DDR_CLK_EDGE="OPPOSITE_EDGE", i_C=ClockSignal(), i_R=ResetSignal(), i_S=0, i_CE=load, i_D=data.i[i], o_Q1=self.bus.dat_r[i]), counter = Signal(max=max(rd_timing, wr_timing, 15) + 1) counter_limit = Signal(max=max(rd_timing, wr_timing, 15) + 1) counter_en = Signal() counter_done = Signal() self.comb += counter_done.eq(counter == counter_limit) self.sync += [ If(counter_en & ~counter_done, counter.eq(counter + 1)).Else(counter.eq(0)) ] last_page_adr = Signal(22) last_cycle_was_rd = Signal() self.submodules.fsm = fsm = FSM() fsm.act( "IDLE", NextValue(config, 0), If(read_config.fields.trigger, NextValue(config_override, 1), NextState("CONFIG_READ")), If( load_config, NextValue(last_cycle_was_rd, 0), NextValue( counter_limit, 10 ), # 100 ns, assuming sysclk = 10ns. A little margin over min 70ns NextValue(sram_zz, 0), # zz has to fall before WE NextState("CONFIG_PRE")). Elif( self.bus.cyc & self.bus.stb, NextValue(sram_zz, 1), If(self.bus.we, NextValue(counter_limit, wr_timing), counter_en.eq(1), store.eq(1), NextValue(last_cycle_was_rd, 0), NextState("WR")) .Else( counter_en .eq(1), NextValue(last_page_adr, self.bus.adr ), NextValue( last_cycle_was_rd, 1), If( (self.bus.adr[2:last_page_adr.nbits] == last_page_adr[2:last_page_adr.nbits]) & last_cycle_was_rd, # doc says 4:nbits, but it doesn't work in practice... NextState("RD"), NextValue(counter_limit, page_rd_timing), ).Else(NextValue(counter_limit, rd_timing), NextState("RD")))).Else(NextValue(sram_zz, 1), )) fsm.act( "CONFIG_READ", NextValue(counter_limit, rd_timing), NextValue(config_ce_n, 1), NextValue(config_we_n, 1), NextValue(config_oe_n, 1), NextState("CFGRD1"), ) fsm.act( "CFGRD1", counter_en.eq(1), NextValue(config_ce_n, 0), NextValue(config_oe_n, 0), If( counter_done, NextValue(counter_limit, rd_timing), NextValue(config_ce_n, 1), # Should be 5ns min high time NextValue(config_oe_n, 1), NextState("CFGRD2"), )) fsm.act( "CFGRD2", counter_en.eq(1), NextValue(config_ce_n, 0), NextValue(config_oe_n, 0), If( counter_done, NextValue(counter_limit, rd_timing), NextValue(config_ce_n, 1), # Should be 5ns min high time NextValue(config_oe_n, 1), NextState("CFGWR1"), )) fsm.act( "CFGWR1", counter_en.eq(1), NextValue(config_ce_n, 0), NextValue(config_we_n, 0), If( counter_done, NextValue(counter_limit, rd_timing), NextValue(config_ce_n, 1), # Should be 5ns min high time NextValue(config_we_n, 1), NextState("CFGRD3"), )) fsm.act( "CFGRD3", counter_en.eq(1), NextValue(config_ce_n, 0), NextValue(config_oe_n, 0), If( counter_done, NextValue(config_status.fields.mode, data.i), NextValue(config_ce_n, 1), # Should be 5ns min high time NextValue(config_oe_n, 1), NextValue(config_override, 0), NextState("IDLE"), )) fsm.act("CONFIG_PRE", NextState("CONFIG")) fsm.act( "CONFIG", counter_en.eq(1), If( counter_done, NextValue(config, 0), NextState("ZZ_UP"), ).Else(NextValue(config, 1), ), ) fsm.act( "ZZ_UP", NextValue(config, 0), NextValue(sram_zz, 1), NextState("IDLE"), ) fsm.act("RD", counter_en.eq(1), If(counter_done, load.eq(1), NextState("ACK"))) fsm.act("WR", counter_en.eq(1), store.eq(1), If(counter_done, NextState("ACK"))) fsm.act("ACK", self.bus.ack.eq(1), NextState("IDLE"))
def __init__(self, pads, dummy=15, div=2, with_bitbang=True): """ Simple SPI flash, e.g. N25Q128 on the LX9 Microboard. Supports multi-bit pseudo-parallel reads (aka Dual or Quad I/O Fast Read). Only supports mode0 (cpol=0, cpha=0). Optionally supports software bitbanging (for write, erase, or other commands). """ self.bus = bus = wishbone.Interface() spi_width = len(pads.dq) if with_bitbang: self.bitbang = CSRStorage(4) self.miso = CSRStatus() self.bitbang_en = CSRStorage() ### cs_n = Signal(reset=1) clk = Signal() dq_oe = Signal() wbone_width = len(bus.dat_r) read_cmd_params = { 4: (_format_cmd(_QIOFR, 4), 4 * 8), 2: (_format_cmd(_DIOFR, 2), 2 * 8), 1: (_format_cmd(_FAST_READ, 1), 1 * 8) } read_cmd, cmd_width = read_cmd_params[spi_width] addr_width = 24 pads.cs_n.reset = 1 dq = TSTriple(spi_width) self.specials.dq = dq.get_tristate(pads.dq) sr = Signal(max(cmd_width, addr_width, wbone_width)) dqs = Replicate(1, spi_width - 1) self.comb += bus.dat_r.eq(sr) hw_read_logic = [ pads.clk.eq(clk), pads.cs_n.eq(cs_n), dq.o.eq(sr[-spi_width:]), dq.oe.eq(dq_oe) ] if with_bitbang: bitbang_logic = [ pads.clk.eq(self.bitbang.storage[1]), pads.cs_n.eq(self.bitbang.storage[2]), dq.o.eq(Cat(self.bitbang.storage[0], dqs)), If(self.bitbang.storage[3], dq.oe.eq(0)).Else(dq.oe.eq(1)), If(self.bitbang.storage[1], self.miso.status.eq(dq.i[1])) ] self.comb += \ If(self.bitbang_en.storage, bitbang_logic ).Else( hw_read_logic ) else: self.comb += hw_read_logic if div < 2: raise ValueError( "Unsupported value \'{}\' for div parameter for SpiFlash core". format(div)) else: i = Signal(max=div) dqi = Signal(spi_width) self.sync += [ If( i == div // 2 - 1, clk.eq(1), dqi.eq(dq.i), ), If(i == div - 1, i.eq(0), clk.eq(0), sr.eq(Cat(dqi, sr[:-spi_width]))).Else(i.eq(i + 1), ), ] # spi is byte-addressed, prefix by zeros z = Replicate(0, log2_int(wbone_width // 8)) seq = [ (cmd_width // spi_width * div, [dq_oe.eq(1), cs_n.eq(0), sr[-cmd_width:].eq(read_cmd)]), (addr_width // spi_width * div, [sr[-addr_width:].eq(Cat(z, bus.adr))]), ((dummy + wbone_width // spi_width) * div, [dq_oe.eq(0)]), (1, [bus.ack.eq(1), cs_n.eq(1)]), ( div, # tSHSL! [bus.ack.eq(0)]), (0, []), ] # accumulate timeline deltas t, tseq = 0, [] for dt, a in seq: tseq.append((t, a)) t += dt self.sync += timeline(bus.cyc & bus.stb & (i == div - 1), tseq)
def __init__(self, platform, pads): self.submodules.ll = ClockDomainsRenamer("local")(SDLinkLayer( platform, pads)) # Event interrupts and acknowledgment self.submodules.ev = EventManager() self.ev.read = EventSourcePulse() self.ev.write = EventSourcePulse() self.ev.finalize() self._connect_event(self.ev.read, self.ll.block_read_act, self.ll.block_read_go) self._connect_event(self.ev.write, self.ll.block_write_act, self.ll.block_write_done) # Wishbone access to SRAM buffers self.bus = wishbone.Interface() self.submodules.wb_rd_buffer = wishbone.SRAM(self.ll.rd_buffer, read_only=False) self.submodules.wb_wr_buffer = wishbone.SRAM(self.ll.wr_buffer, read_only=False) wb_slaves = [(lambda a: a[9] == 0, self.wb_rd_buffer.bus), (lambda a: a[9] == 1, self.wb_wr_buffer.bus)] self.submodules.wb_decoder = wishbone.Decoder(self.bus, wb_slaves, register=True) # Local reset domain self._reset = CSRStorage() self.clock_domains.cd_local = ClockDomain() self.comb += self.cd_local.clk.eq(ClockSignal()) self.comb += self.cd_local.rst.eq(ResetSignal() | self._reset.storage) # Current data operation self._read_act = CSRStatus() self._read_addr = CSRStatus(32) self._read_byteaddr = CSRStatus(32) self._read_num = CSRStatus(32) self._read_stop = CSRStatus() self._write_act = CSRStatus() self._write_addr = CSRStatus(32) self._write_byteaddr = CSRStatus(32) self._write_num = CSRStatus(32) self._preerase_num = CSRStatus(23) self._erase_start = CSRStatus(32) self._erase_end = CSRStatus(32) self.comb += [ self._read_act.status.eq(self.ll.block_read_act), self._read_addr.status.eq(self.ll.block_read_addr), self._read_byteaddr.status.eq(self.ll.block_read_byteaddr), self._read_num.status.eq(self.ll.block_read_num), self._read_stop.status.eq(self.ll.block_read_stop), self._write_act.status.eq(self.ll.block_write_act), self._write_addr.status.eq(self.ll.block_write_addr), self._write_byteaddr.status.eq(self.ll.block_write_byteaddr), self._write_num.status.eq(self.ll.block_write_num), self._preerase_num.status.eq(self.ll.block_preerase_num), self._erase_start.status.eq(self.ll.block_erase_start), self._erase_end.status.eq(self.ll.block_erase_end), ] # Informational registers, not needed for data transfer self._info_bits = CSRStatus(16) self.comb += self._info_bits.status.eq( Cat( self.ll.mode_4bit, self.ll.mode_spi, self.ll.host_hc_support, Constant(False), # Reserved bit 3 Constant(False), # Reserved bit 4 Constant(False), # Reserved bit 5 Constant(False), # Reserved bit 6 Constant(False), # Reserved bit 7 self.ll.info_card_desel, self.ll.err_op_out_range, self.ll.err_unhandled_cmd, self.ll.err_cmd_crc, )) self._most_recent_cmd = CSRStatus(len(self.ll.cmd_in_cmd)) self.comb += self._most_recent_cmd.status.eq(self.ll.cmd_in_cmd) self._card_status = CSRStatus(len(self.ll.card_status)) self.comb += self._card_status.status.eq(self.ll.card_status)
def __init__(self, platform, variant="standard"): self.platform = platform self.variant = variant self.reset = Signal() self.ibus = ibus = wishbone.Interface(data_width=64, adr_width=29) self.dbus = dbus = wishbone.Interface(data_width=64, adr_width=29) self.periph_buses = [ ibus, dbus ] # Peripheral buses (Connected to main SoC's bus). self.memory_buses = [ ] # Memory buses (Connected directly to LiteDRAM). if "irq" in variant: self.interrupt = Signal(16) self.core_ext_irq = Signal() # # # self.cpu_params = dict( # Clk / Rst. i_clk=ClockSignal("sys"), i_rst=ResetSignal("sys") | self.reset, # IBus. i_wishbone_insn_dat_r=ibus.dat_r, i_wishbone_insn_ack=ibus.ack, i_wishbone_insn_stall=ibus.cyc & ~ibus.ack, # No burst support o_wishbone_insn_adr=ibus.adr, o_wishbone_insn_dat_w=ibus.dat_w, o_wishbone_insn_cyc=ibus.cyc, o_wishbone_insn_stb=ibus.stb, o_wishbone_insn_sel=ibus.sel, o_wishbone_insn_we=ibus.we, # DBus. i_wishbone_data_dat_r=dbus.dat_r, i_wishbone_data_ack=dbus.ack, i_wishbone_data_stall=dbus.cyc & ~dbus.ack, # No burst support o_wishbone_data_adr=dbus.adr, o_wishbone_data_dat_w=dbus.dat_w, o_wishbone_data_cyc=dbus.cyc, o_wishbone_data_stb=dbus.stb, o_wishbone_data_sel=dbus.sel, o_wishbone_data_we=dbus.we, # Snoop. i_wb_snoop_in_adr=0, i_wb_snoop_in_dat_w=0, i_wb_snoop_in_cyc=0, i_wb_snoop_in_stb=0, i_wb_snoop_in_sel=0, i_wb_snoop_in_we=0, # Debug. i_dmi_addr=0, i_dmi_din=0, o_dmi_dout=Open(), i_dmi_req=0, i_dmi_wr=0, o_dmi_ack=Open(), # IRQ. i_core_ext_irq=self.core_ext_irq, ) # Add VHDL sources. self.add_sources(platform, use_ghdl_yosys_plugin="ghdl" in self.variant)
def __init__( self, platform, clk_freq, # CPU parameters cpu_type="vexriscv", cpu_reset_address=0x00000000, cpu_variant=None, # ROM parameters integrated_rom_size=0, integrated_rom_init=[], # SRAM parameters integrated_sram_size=0x1000, integrated_sram_init=[], # MAIN_RAM parameters integrated_main_ram_size=0, integrated_main_ram_init=[], # CSR parameters csr_data_width=8, csr_alignment=32, csr_address_width=14, # Identifier parameters ident="", ident_version=False, # UART parameters with_uart=True, uart_name="serial", uart_baudrate=115200, # Timer parameters with_timer=True, # Controller parameters with_ctrl=True, # Wishbone parameters with_wishbone=True, wishbone_timeout_cycles=1e6, **kwargs): self.platform = platform self.clk_freq = clk_freq # SoC's CSR/Mem/Interrupt mapping (default or user defined + dynamically allocateds) self.soc_csr_map = {} self.soc_interrupt_map = {} self.soc_mem_map = self.mem_map self.soc_io_regions = self.io_regions # SoC's Config/Constants/Regions self.config = {} self.constants = {} self.mem_regions = {} self.csr_regions = {} # Wishbone masters/slaves lists self._wb_masters = [] self._wb_slaves = [] # CSR masters list self._csr_masters = [] self.add_retro_compat(kwargs) # Parameters managment --------------------------------------------------------------------- if cpu_type == "None": cpu_type = None if not with_wishbone: self.soc_mem_map["csr"] = 0x00000000 self.cpu_type = cpu_type self.cpu_variant = cpu.check_format_cpu_variant(cpu_variant) self.integrated_rom_size = integrated_rom_size self.integrated_rom_initialized = integrated_rom_init != [] self.integrated_sram_size = integrated_sram_size self.integrated_main_ram_size = integrated_main_ram_size assert csr_data_width in [8, 16, 32] self.csr_data_width = csr_data_width self.csr_address_width = csr_address_width assert csr_alignment in [32, 64] self.with_ctrl = with_ctrl self.with_uart = with_uart self.uart_baudrate = uart_baudrate self.with_wishbone = with_wishbone self.wishbone_timeout_cycles = wishbone_timeout_cycles # Modules instances ------------------------------------------------------------------------ # Add user's CSRs (needs to be done before the first dynamic allocation) for _name, _id in self.csr_map.items(): self.add_csr(_name, _id) # Add SoCController if with_ctrl: self.submodules.ctrl = SoCController() self.add_csr("ctrl", allow_user_defined=True) # Add CPU self.config["CPU_TYPE"] = str(cpu_type).upper() if cpu_type is not None: if cpu_variant is not None: self.config["CPU_VARIANT"] = str( cpu_variant.split('+')[0]).upper() # Check type if cpu_type not in cpu.CPUS.keys(): raise ValueError( "Unsupported CPU type: {} -- supported CPU types: {}". format(cpu_type, ", ".join(cpu.CPUS.keys()))) # Declare the CPU self.submodules.cpu = cpu.CPUS[cpu_type](platform, self.cpu_variant) if cpu_type == "microwatt": self.add_constant("UART_POLLING", None) # Update Memory Map (if defined by CPU) self.soc_mem_map.update(self.cpu.mem_map) # Update IO Regions (if defined by CPU) self.soc_io_regions.update(self.cpu.io_regions) # Set reset address self.cpu.set_reset_address( self.soc_mem_map["rom"] if integrated_rom_size else cpu_reset_address) self.config["CPU_RESET_ADDR"] = self.cpu.reset_address # Add CPU buses as 32-bit Wishbone masters for cpu_bus in self.cpu.buses: assert cpu_bus.data_width in [32, 64, 128] soc_bus = wishbone.Interface(data_width=32) self.submodules += wishbone.Converter(cpu_bus, soc_bus) self.add_wb_master(soc_bus) # Add CPU CSR (dynamic) self.add_csr("cpu", allow_user_defined=True) # Add CPU interrupts for _name, _id in self.cpu.interrupts.items(): self.add_interrupt(_name, _id) # Allow SoCController to reset the CPU if with_ctrl: self.comb += self.cpu.reset.eq(self.ctrl.reset) assert csr_alignment <= self.cpu.data_width csr_alignment = self.cpu.data_width else: self.submodules.cpu = cpu.CPUNone() self.soc_io_regions.update(self.cpu.io_regions) # Add user's interrupts (needs to be done after CPU interrupts are allocated) for _name, _id in self.interrupt_map.items(): self.add_interrupt(_name, _id) # Add integrated ROM if integrated_rom_size: self.submodules.rom = wishbone.SRAM(integrated_rom_size, read_only=True, init=integrated_rom_init) self.register_rom(self.rom.bus, integrated_rom_size) # Add integrated SRAM if integrated_sram_size: self.submodules.sram = wishbone.SRAM(integrated_sram_size, init=integrated_sram_init) self.register_mem("sram", self.soc_mem_map["sram"], self.sram.bus, integrated_sram_size) # Add integrated MAIN_RAM (only useful when no external SRAM/SDRAM is available) if integrated_main_ram_size: self.submodules.main_ram = wishbone.SRAM( integrated_main_ram_size, init=integrated_main_ram_init) self.register_mem("main_ram", self.soc_mem_map["main_ram"], self.main_ram.bus, integrated_main_ram_size) # Add UART if with_uart: if uart_name in ["stub", "stream"]: self.submodules.uart = uart.UART() if uart_name == "stub": self.comb += self.uart.sink.ready.eq(1) elif uart_name == "bridge": self.submodules.uart = uart.UARTWishboneBridge( platform.request("serial"), clk_freq, uart_baudrate) self.add_wb_master(self.uart.wishbone) elif uart_name == "crossover": self.submodules.uart = uart.UARTCrossover() else: if uart_name == "jtag_atlantic": from litex.soc.cores.jtag import JTAGAtlantic self.submodules.uart_phy = JTAGAtlantic() elif uart_name == "jtag_uart": from litex.soc.cores.jtag import JTAGPHY self.submodules.uart_phy = JTAGPHY(device=platform.device) else: self.submodules.uart_phy = uart.UARTPHY( platform.request(uart_name), clk_freq, uart_baudrate) self.submodules.uart = ResetInserter()(uart.UART( self.uart_phy)) self.add_csr("uart_phy", allow_user_defined=True) self.add_csr("uart", allow_user_defined=True) self.add_interrupt("uart", allow_user_defined=True) # Add Identifier if ident: if ident_version: ident = ident + " " + get_version() self.submodules.identifier = identifier.Identifier(ident) self.add_csr("identifier_mem", allow_user_defined=True) self.config["CLOCK_FREQUENCY"] = int(clk_freq) # Add Timer if with_timer: self.submodules.timer0 = timer.Timer() self.add_csr("timer0", allow_user_defined=True) self.add_interrupt("timer0", allow_user_defined=True) # Add Wishbone to CSR bridge self.config["CSR_DATA_WIDTH"] = csr_data_width self.config["CSR_ALIGNMENT"] = csr_alignment assert csr_data_width <= csr_alignment self.csr_data_width = csr_data_width self.csr_alignment = csr_alignment if with_wishbone: self.submodules.wishbone2csr = wishbone2csr.WB2CSR( bus_csr=csr_bus.Interface(address_width=csr_address_width, data_width=csr_data_width)) self.add_csr_master(self.wishbone2csr.csr) self.register_mem("csr", self.soc_mem_map["csr"], self.wishbone2csr.wishbone, 2**(csr_address_width + 2))
def __init__(self, platform, variant="standard"): self.platform = platform self.variant = variant self.trap = Signal() self.reset = Signal() self.interrupt = Signal(32) self.idbus = idbus = wishbone.Interface() self.periph_buses = [ idbus ] # Peripheral buses (Connected to main SoC's bus). self.memory_buses = [ ] # Memory buses (Connected directly to LiteDRAM). # # # mem_valid = Signal() mem_instr = Signal() mem_ready = Signal() mem_addr = Signal(32) mem_wdata = Signal(32) mem_wstrb = Signal(4) mem_rdata = Signal(32) # PicoRV32 parameters, change the desired parameters to create a create a new variant. self.cpu_params = dict( p_ENABLE_COUNTERS=1, p_ENABLE_COUNTERS64=1, p_ENABLE_REGS_16_31= 1, # Changing REGS has no effect as on FPGAs, the regs are p_ENABLE_REGS_DUALPORT= 1, # implemented using a register file stored in DPRAM. p_LATCHED_MEM_RDATA=0, p_TWO_STAGE_SHIFT=1, p_TWO_CYCLE_COMPARE=0, p_TWO_CYCLE_ALU=0, p_CATCH_MISALIGN=1, p_CATCH_ILLINSN=1, p_ENABLE_PCPI=0, p_ENABLE_MUL=1, p_ENABLE_DIV=1, p_ENABLE_FAST_MUL=0, p_ENABLE_IRQ=1, p_ENABLE_IRQ_QREGS=1, p_ENABLE_IRQ_TIMER=1, p_ENABLE_TRACE=0, p_MASKED_IRQ=0x00000000, p_LATCHED_IRQ=0xffffffff, p_STACKADDR=0xffffffff, ) # Enforce default parameters for Minimal variant. if variant == "minimal": self.cpu_params.update( p_ENABLE_COUNTERS=0, p_ENABLE_COUNTERS64=0, p_TWO_STAGE_SHIFT=0, p_CATCH_MISALIGN=0, p_ENABLE_MUL=0, p_ENABLE_DIV=0, p_ENABLE_IRQ_TIMER=0, ) self.cpu_params.update( # Clk / Rst. i_clk=ClockSignal("sys"), i_resetn=~(ResetSignal("sys") | self.reset), # Trap. o_trap=self.trap, # Memory Interface. o_mem_valid=mem_valid, o_mem_instr=mem_instr, i_mem_ready=mem_ready, o_mem_addr=mem_addr, o_mem_wdata=mem_wdata, o_mem_wstrb=mem_wstrb, i_mem_rdata=mem_rdata, # Look Ahead Interface (not used). o_mem_la_read=Signal(), o_mem_la_write=Signal(), o_mem_la_addr=Signal(32), o_mem_la_wdata=Signal(32), o_mem_la_wstrb=Signal(4), # Co-Processor interface (not used). o_pcpi_valid=Signal(), o_pcpi_insn=Signal(32), o_pcpi_rs1=Signal(32), o_pcpi_rs2=Signal(32), i_pcpi_wr=0, i_pcpi_rd=0, i_pcpi_wait=0, i_pcpi_ready=0, # IRQ interface. i_irq=self.interrupt, o_eoi=Signal(32)) # not used # Adapt Memory Interface to Wishbone. self.comb += [ idbus.adr.eq(mem_addr[2:]), idbus.dat_w.eq(mem_wdata), idbus.we.eq(mem_wstrb != 0), idbus.sel.eq(mem_wstrb), idbus.cyc.eq(mem_valid), idbus.stb.eq(mem_valid), idbus.cti.eq(0), idbus.bte.eq(0), mem_ready.eq(idbus.ack), mem_rdata.eq(idbus.dat_r), ] # Add Verilog sources self.add_sources(platform)
def __init__(self, platform, variant): self.platform = platform self.variant = "standard" self.human_name = self.human_name + "-" + variant.upper() self.reset = Signal() self.jtag_clk = Signal() self.jtag_enable = Signal() self.jtag_capture = Signal() self.jtag_shift = Signal() self.jtag_update = Signal() self.jtag_reset = Signal() self.jtag_tdo = Signal() self.jtag_tdi = Signal() self.interrupt = Signal(32) self.pbus = pbus = wishbone.Interface() self.periph_buses = [ pbus ] # Peripheral buses (Connected to main SoC's bus). self.memory_buses = [ ] # Memory buses (Connected directly to LiteDRAM). # # # self.cpu_params = dict( # Clk / Rst. i_debugCd_external_clk=ClockSignal(), i_debugCd_external_reset=ResetSignal() | self.reset, # Interrupts. i_interrupts=self.interrupt, # JTAG. i_jtag_clk=self.jtag_clk, i_debugPort_enable=self.jtag_enable, i_debugPort_capture=self.jtag_capture, i_debugPort_shift=self.jtag_shift, i_debugPort_update=self.jtag_update, i_debugPort_reset=self.jtag_reset, i_debugPort_tdi=self.jtag_tdi, o_debugPort_tdo=self.jtag_tdo, # Peripheral Bus (Master). o_peripheral_CYC=pbus.cyc, o_peripheral_STB=pbus.stb, i_peripheral_ACK=pbus.ack, o_peripheral_WE=pbus.we, o_peripheral_ADR=pbus.adr, i_peripheral_DAT_MISO=pbus.dat_r, o_peripheral_DAT_MOSI=pbus.dat_w, o_peripheral_SEL=pbus.sel, i_peripheral_ERR=pbus.err, o_peripheral_CTI=pbus.cti, o_peripheral_BTE=pbus.bte) if VexRiscvSMP.coherent_dma: self.dma_bus = dma_bus = wishbone.Interface( data_width=VexRiscvSMP.dcache_width) dma_bus_stall = Signal() dma_bus_inhibit = Signal() self.cpu_params.update( # DMA Bus (Slave). i_dma_wishbone_CYC=dma_bus.cyc, i_dma_wishbone_STB=dma_bus.stb & ~dma_bus_inhibit, o_dma_wishbone_ACK=dma_bus.ack, i_dma_wishbone_WE=dma_bus.we, i_dma_wishbone_SEL=dma_bus.sel, i_dma_wishbone_ADR=dma_bus.adr, o_dma_wishbone_DAT_MISO=dma_bus.dat_r, i_dma_wishbone_DAT_MOSI=dma_bus.dat_w, o_dma_wishbone_STALL=dma_bus_stall) self.sync += [ If( dma_bus.stb & dma_bus.cyc & ~dma_bus_stall, dma_bus_inhibit.eq(1), ), If(dma_bus.ack, dma_bus_inhibit.eq(0)) ]
def __init__(self, pads, dummy=15, div=2): """ Simple SPI flash. Supports 1-bit reads. Only supports mode0 (cpol=0, cpha=0). """ self.bus = bus = wishbone.Interface() # # # if hasattr(pads, "wp"): self.comb += pads.wp.eq(1) if hasattr(pads, "hold"): self.comb += pads.hold.eq(1) cs_n = Signal(reset=1) clk = Signal() wbone_width = len(bus.dat_r) read_cmd = _FAST_READ cmd_width = 8 addr_width = 24 sr = Signal(max(cmd_width, addr_width, wbone_width)) if endianness == "big": self.comb += bus.dat_r.eq(sr) else: self.comb += bus.dat_r.eq(reverse_bytes(sr)) self.comb += [ pads.clk.eq(clk), pads.cs_n.eq(cs_n), pads.mosi.eq(sr[-1:]) ] if div < 2: raise ValueError("Unsupported value \'{}\' for div parameter for SpiFlash core".format(div)) else: i = Signal(max=div) miso = Signal() self.sync += [ If(i == div//2 - 1, clk.eq(1), miso.eq(pads.miso), ), If(i == div - 1, i.eq(0), clk.eq(0), sr.eq(Cat(miso, sr[:-1])) ).Else( i.eq(i + 1), ), ] # spi is byte-addressed, prefix by zeros z = Replicate(0, log2_int(wbone_width//8)) seq = [ (cmd_width*div, [cs_n.eq(0), sr[-cmd_width:].eq(read_cmd)]), (addr_width*div, [sr[-addr_width:].eq(Cat(z, bus.adr))]), ((dummy + wbone_width)*div, []), (1, [bus.ack.eq(1), cs_n.eq(1)]), (div, # tSHSL! [bus.ack.eq(0)]), (0, []), ] # accumulate timeline deltas t, tseq = 0, [] for dt, a in seq: tseq.append((t, a)) t += dt self.sync += timeline(bus.cyc & bus.stb & (i == div - 1), tseq)
def add_debug(self): debug_reset = Signal() ibus_err = Signal() dbus_err = Signal() self.i_cmd_valid = Signal() self.i_cmd_payload_wr = Signal() self.i_cmd_payload_address = Signal(8) self.i_cmd_payload_data = Signal(32) self.o_cmd_ready = Signal() self.o_rsp_data = Signal(32) self.o_resetOut = Signal() reset_debug_logic = Signal() self.transfer_complete = Signal() self.transfer_in_progress = Signal() self.transfer_wait_for_ack = Signal() self.debug_bus = wishbone.Interface() self.sync += [ self.debug_bus.dat_r.eq(self.o_rsp_data), debug_reset.eq(reset_debug_logic | ResetSignal()), ] self.sync += [ # CYC is held high for the duration of the transfer. # STB is kept high when the transfer finishes (write) # or the master is waiting for data (read), and stays # there until ACK, ERR, or RTY are asserted. If((self.debug_bus.stb & self.debug_bus.cyc) & (~self.transfer_in_progress) & (~self.transfer_complete) & (~self.transfer_wait_for_ack), self.i_cmd_payload_data.eq(self.debug_bus.dat_w), self.i_cmd_payload_address.eq((self.debug_bus.adr[0:6] << 2) | 0), self.i_cmd_payload_wr.eq(self.debug_bus.we), self.i_cmd_valid.eq(1), self.transfer_in_progress.eq(1), self.transfer_complete.eq(0), self.debug_bus.ack.eq(0)).Elif( self.transfer_in_progress, If(self.o_cmd_ready, self.i_cmd_valid.eq(0), self.i_cmd_payload_wr.eq(0), self.transfer_complete.eq(1), self.transfer_in_progress.eq(0))).Elif( self.transfer_complete, self.transfer_complete.eq(0), self.debug_bus.ack.eq(1), self.transfer_wait_for_ack.eq(1)).Elif( self.transfer_wait_for_ack & ~(self.debug_bus.stb & self.debug_bus.cyc), self.transfer_wait_for_ack.eq(0), self.debug_bus.ack.eq(0)), # Force a Wishbone error if transferring during a reset sequence. # Because o_resetOut is multiple cycles and i.stb/d.stb should # deassert one cycle after i_err/i_ack/d_err/d_ack are asserted, # this will give i_err and o_err enough time to be reset to 0 # once the reset cycle finishes. If( self.o_resetOut, If(self.ibus.cyc & self.ibus.stb, ibus_err.eq(1)).Else(ibus_err.eq(0)), If(self.dbus.cyc & self.dbus.stb, dbus_err.eq(1)).Else(dbus_err.eq(0)), reset_debug_logic.eq(1)).Else(reset_debug_logic.eq(0)) ] self.cpu_params.update( i_reset=ResetSignal() | self.reset | debug_reset, i_iBusWishbone_ERR=self.ibus.err | ibus_err, i_dBusWishbone_ERR=self.dbus.err | dbus_err, i_debugReset=ResetSignal(), i_debug_bus_cmd_valid=self.i_cmd_valid, i_debug_bus_cmd_payload_wr=self.i_cmd_payload_wr, i_debug_bus_cmd_payload_address=self.i_cmd_payload_address, i_debug_bus_cmd_payload_data=self.i_cmd_payload_data, o_debug_bus_cmd_ready=self.o_cmd_ready, o_debug_bus_rsp_data=self.o_rsp_data, o_debug_resetOut=self.o_resetOut)
def __init__(self, pads, dummy=15, div=2, endianness="big"): """ Simple SPI flash. Supports multi-bit pseudo-parallel reads (aka Dual or Quad I/O Fast Read). Only supports mode0 (cpol=0, cpha=0). """ self.bus = bus = wishbone.Interface() spi_width = len(pads.dq) assert spi_width >= 2 # # # cs_n = Signal(reset=1) clk = Signal() dq_oe = Signal() wbone_width = len(bus.dat_r) read_cmd_params = { 4: (_format_cmd(_QIOFR, 4), 4*8), 2: (_format_cmd(_DIOFR, 2), 2*8), 1: (_format_cmd(_FAST_READ, 1), 1*8) } read_cmd, cmd_width = read_cmd_params[spi_width] addr_width = 24 dq = TSTriple(spi_width) self.specials.dq = dq.get_tristate(pads.dq) sr = Signal(max(cmd_width, addr_width, wbone_width)) if endianness == "big": self.comb += bus.dat_r.eq(sr) else: self.comb += bus.dat_r.eq(reverse_bytes(sr)) self.comb += [ pads.clk.eq(clk), pads.cs_n.eq(cs_n), dq.o.eq(sr[-spi_width:]), dq.oe.eq(dq_oe) ] if div < 2: raise ValueError("Unsupported value \'{}\' for div parameter for SpiFlash core".format(div)) else: i = Signal(max=div) dqi = Signal(spi_width) self.sync += [ If(i == div//2 - 1, clk.eq(1), dqi.eq(dq.i), ), If(i == div - 1, i.eq(0), clk.eq(0), sr.eq(Cat(dqi, sr[:-spi_width])) ).Else( i.eq(i + 1), ), ] # spi is byte-addressed, prefix by zeros z = Replicate(0, log2_int(wbone_width//8)) seq = [ (cmd_width//spi_width*div, [dq_oe.eq(1), cs_n.eq(0), sr[-cmd_width:].eq(read_cmd)]), (addr_width//spi_width*div, [sr[-addr_width:].eq(Cat(z, bus.adr))]), ((dummy + wbone_width//spi_width)*div, [dq_oe.eq(0)]), (1, [bus.ack.eq(1), cs_n.eq(1)]), (div, # tSHSL! [bus.ack.eq(0)]), (0, []), ] # accumulate timeline deltas t, tseq = 0, [] for dt, a in seq: tseq.append((t, a)) t += dt self.sync += timeline(bus.cyc & bus.stb & (i == div - 1), tseq)
def test_wishbone_32bit_to_64bit(self): # Verify Wishbone with 32-bit data width up-converted to 64-bit data width. data = self.pattern_test_data["32bit_to_64bit"] wb = wishbone.Interface(adr_width=30, data_width=32) port = LiteDRAMNativePort("both", address_width=30, data_width=64) self.wishbone_readback_test(data["pattern"], data["expected"], wb, port)
def __init__(self, sys_clk_freq=int(768e4), with_pwm=False, with_gpio=False, gpio_width=32, with_spi_master=False, spi_master_data_width=8, spi_master_clk_freq=8e6, **kwargs): platform = Platform(_io) # UART if kwargs["with_uart"]: platform.add_extension([( "serial", 0, Subsignal("tx", Pins(1)), Subsignal("rx", Pins(1)), )]) # CRG -------------------------------------------------------------------------------------- self.submodules.crg = CRG(platform.request("sys_clk"), rst=platform.request("sys_rst")) # SoCMini ---------------------------------------------------------------------------------- SoCMini.__init__(self, platform, clk_freq=sys_clk_freq, **kwargs) # SPI Master if with_spi_master: platform.add_extension([( "spi_master", 0, Subsignal("clk", Pins(1)), Subsignal("cs_n", Pins(1)), Subsignal("mosi", Pins(1)), Subsignal("miso", Pins(1)), )]) self.submodules.spi_master = SPIMaster( pads=platform.request("spi_master"), data_width=spi_master_data_width, sys_clk_freq=sys_clk_freq, spi_clk_freq=spi_master_clk_freq, ) self.add_csr("spi_master") # PWM if with_pwm: platform.add_extension([("pwm0", 0, Pins(1))]) self.submodules.pwm0 = PWM(platform.request("pwm0")) self.add_csr("pwm0") platform.add_extension([("pwm1", 0, Pins(1))]) self.submodules.pwm1 = PWM(platform.request("pwm1")) self.add_csr("pwm1") platform.add_extension([("pwm2", 0, Pins(1))]) self.submodules.pwm2 = PWM(platform.request("pwm2")) self.add_csr("pwm2") # GPIO if with_gpio: platform.add_extension([("gpio", 0, Pins(gpio_width))]) self.submodules.gpio = GPIOTristate(platform.request("gpio")) self.add_csr("gpio") # Wishbone Master if kwargs["bus"] == "wishbone": wb_bus = wishbone.Interface() self.bus.add_master(master=wb_bus) platform.add_extension(wb_bus.get_ios("wb")) wb_pads = platform.request("wb") self.comb += wb_bus.connect_to_pads(wb_pads, mode="slave") # AXI-Lite Master if kwargs["bus"] == "axi": axi_bus = axi.AXILiteInterface(data_width=32, address_width=32) wb_bus = wishbone.Interface() axi2wb = axi.AXILite2Wishbone(axi_bus, wb_bus) self.submodules += axi2wb self.bus.add_master(master=wb_bus) platform.add_extension(axi_bus.get_ios("axi")) axi_pads = platform.request("axi") self.comb += axi_bus.connect_to_pads(axi_pads, mode="slave") # IRQs for name, loc in sorted(self.irq.locs.items()): module = getattr(self, name) platform.add_extension([("irq_" + name, 0, Pins(1))]) irq_pin = platform.request("irq_" + name) self.comb += irq_pin.eq(module.ev.irq)
def __init__(self, pads=None): if pads is None: pads = Record(self.jtag_layout) self.pads = pads self.dmbus = wishbone.Interface() self.sbbus = wishbone.Interface() dmbus = Record(obi_layout) sbbus = Record(obi_layout) self.submodules.sbbus_conv = OBI2Wishbone(sbbus, self.sbbus) self.submodules.dmbus_conv = Wishbone2OBI(self.dmbus, dmbus) self.debug_req = Signal() self.ndmreset = Signal() tdo_i = Signal() tdo_o = Signal() tdo_oe = Signal() self.specials += Tristate(pads.tdo, tdo_o, tdo_oe, tdo_i) self.dm_params = dict( # Clk / Rst. i_clk=ClockSignal("sys"), i_rst_n=~ResetSignal("sys"), o_ndmreset=self.ndmreset, o_debug_req=self.debug_req, # Slave Bus. i_dm_req=dmbus.req, i_dm_we=dmbus.we, i_dm_addr=dmbus.addr, i_dm_be=dmbus.be, i_dm_wdata=dmbus.wdata, o_dm_rdata=dmbus.rdata, # Master Bus. o_sb_req=sbbus.req, o_sb_addr=sbbus.addr, o_sb_we=sbbus.we, o_sb_wdata=sbbus.wdata, o_sb_be=sbbus.be, i_sb_gnt=sbbus.gnt, i_sb_rvalid=sbbus.rvalid, i_sb_rdata=sbbus.rdata, # JTAG. i_tck=pads.tck, i_tms=pads.tms, i_trst_n=pads.trst, i_tdi=pads.tdi, o_tdo=tdo_o, o_tdo_oe=tdo_oe, ) self.comb += [ dmbus.gnt.eq(dmbus.req), dmbus.rvalid.eq(dmbus.gnt), ] self.specials += Instance("dm_wrap", **self.dm_params)
def __init__(self, platform, variant="standard"): assert variant in CPU_VARIANTS, "Unsupported variant %s" % variant self.platform = platform self.variant = variant self.reset = Signal() self.interrupt = Signal(32) self.ibus = i = wishbone.Interface() self.dbus = d = wishbone.Interface() self.periph_buses = [i, d] self.memory_buses = [] if variant == "linux": self.mem_map = self.mem_map_linux # # # cpu_args = dict( p_FEATURE_INSTRUCTIONCACHE="ENABLED", p_OPTION_ICACHE_BLOCK_WIDTH=4, p_OPTION_ICACHE_SET_WIDTH=8, p_OPTION_ICACHE_WAYS=1, p_OPTION_ICACHE_LIMIT_WIDTH=31, p_FEATURE_DATACACHE="ENABLED", p_OPTION_DCACHE_BLOCK_WIDTH=4, p_OPTION_DCACHE_SET_WIDTH=8, p_OPTION_DCACHE_WAYS=1, p_OPTION_DCACHE_LIMIT_WIDTH=31, p_FEATURE_TIMER="NONE", p_OPTION_PIC_TRIGGER="LEVEL", p_FEATURE_SYSCALL="NONE", p_FEATURE_TRAP="NONE", p_FEATURE_RANGE="NONE", p_FEATURE_OVERFLOW="NONE", p_FEATURE_ADDC="ENABLED", p_FEATURE_CMOV="ENABLED", p_FEATURE_FFL1="ENABLED", p_OPTION_CPU0="CAPPUCCINO", p_IBUS_WB_TYPE="B3_REGISTERED_FEEDBACK", p_DBUS_WB_TYPE="B3_REGISTERED_FEEDBACK", ) if variant == "linux": cpu_args.update( # Linux needs the memory management units. p_FEATURE_IMMU="ENABLED", p_FEATURE_DMMU="ENABLED", # FIXME: Currently we need the or1k timer when we should be # using the litex timer. p_FEATURE_TIMER="ENABLED", ) # FIXME: Check if these are needed? use_defaults = ( "p_FEATURE_SYSCALL", "p_FEATURE_TRAP", "p_FEATURE_RANGE", "p_FEATURE_OVERFLOW", ) for to_remove in use_defaults: del cpu_args[to_remove] i_adr_o = Signal(32) d_adr_o = Signal(32) self.cpu_params = dict( **cpu_args, i_clk=ClockSignal(), i_rst=ResetSignal() | self.reset, i_irq_i=self.interrupt, o_iwbm_adr_o=i_adr_o, o_iwbm_dat_o=i.dat_w, o_iwbm_sel_o=i.sel, o_iwbm_cyc_o=i.cyc, o_iwbm_stb_o=i.stb, o_iwbm_we_o=i.we, o_iwbm_cti_o=i.cti, o_iwbm_bte_o=i.bte, i_iwbm_dat_i=i.dat_r, i_iwbm_ack_i=i.ack, i_iwbm_err_i=i.err, i_iwbm_rty_i=0, o_dwbm_adr_o=d_adr_o, o_dwbm_dat_o=d.dat_w, o_dwbm_sel_o=d.sel, o_dwbm_cyc_o=d.cyc, o_dwbm_stb_o=d.stb, o_dwbm_we_o=d.we, o_dwbm_cti_o=d.cti, o_dwbm_bte_o=d.bte, i_dwbm_dat_i=d.dat_r, i_dwbm_ack_i=d.ack, i_dwbm_err_i=d.err, i_dwbm_rty_i=0, ) self.comb += [ self.ibus.adr.eq(i_adr_o[2:]), self.dbus.adr.eq(d_adr_o[2:]) ] # add verilog sources self.add_sources(platform)
def __init__(self, pads, dummy=15, div=2, with_bitbang=True, endianness="big"): """ Simple memory-mapped SPI flash. Supports 1-bit reads. Only supports mode3 (cpol=1, cpha=1). """ SpiFlashCommon.__init__(self, pads) self.bus = bus = wishbone.Interface() if with_bitbang: self.bitbang = CSRStorage( 4, reset_less=True, fields=[ CSRField("mosi", description="Output value for SPI MOSI pin."), CSRField("clk", description="Output value for SPI CLK pin."), CSRField("cs_n", description="Output value for SPI CSn pin."), CSRField("dir", description="Unused in this design.") ], description="""Bitbang controls for SPI output.""") self.miso = CSRStatus(description="Incoming value of MISO pin.") self.bitbang_en = CSRStorage( description= "Write a ``1`` here to disable memory-mapped mode and enable bitbang mode." ) # # # if hasattr(pads, "wp"): self.comb += pads.wp.eq(1) if hasattr(pads, "hold"): self.comb += pads.hold.eq(1) cs_n = Signal(reset=1) clk = Signal() wbone_width = len(bus.dat_r) read_cmd = _FAST_READ cmd_width = 8 addr_width = 24 sr = Signal(max(cmd_width, addr_width, wbone_width)) if endianness == "big": self.comb += bus.dat_r.eq(sr) else: self.comb += bus.dat_r.eq(reverse_bytes(sr)) hw_read_logic = [ pads.clk.eq(clk), pads.cs_n.eq(cs_n), pads.mosi.eq(sr[-1:]) ] if with_bitbang: bitbang_logic = [ pads.clk.eq(self.bitbang.storage[1]), pads.cs_n.eq(self.bitbang.storage[2]), If( self.bitbang. storage[1], # CPOL=0/CPHA=0 or CPOL=1/CPHA=1 only. self.miso.status.eq(pads.miso)), pads.mosi.eq(self.bitbang.storage[0]) ] self.comb += [ If(self.bitbang_en.storage, bitbang_logic).Else(hw_read_logic) ] else: self.comb += hw_read_logic if div < 2: raise ValueError( "Unsupported value \'{}\' for div parameter for SpiFlash core". format(div)) else: i = Signal(max=div) miso = Signal() self.sync += [ If( i == div // 2 - 1, clk.eq(1), miso.eq(pads.miso), ), If(i == div - 1, i.eq(0), clk.eq(0), sr.eq(Cat(miso, sr[:-1]))).Else(i.eq(i + 1), ), ] # spi is byte-addressed, prefix by zeros z = Replicate(0, log2_int(wbone_width // 8)) seq = [ (cmd_width * div, [cs_n.eq(0), sr[-cmd_width:].eq(read_cmd)]), (addr_width * div, [sr[-addr_width:].eq(Cat(z, bus.adr))]), ((dummy + wbone_width) * div, []), (1, [bus.ack.eq(1), cs_n.eq(1)]), ( div, # tSHSL! [bus.ack.eq(0)]), (0, []), ] # accumulate timeline deltas t, tseq = 0, [] for dt, a in seq: tseq.append((t, a)) t += dt self.sync += timeline(bus.cyc & bus.stb & (i == div - 1), tseq)
def __init__(self, platform, cpu_reset_addr, variant="standard"): assert variant in CPU_VARIANTS, "Unsupported variant %s" % variant assert cpu_reset_addr == 0x10000000, "cpu_reset_addr hardcoded in Chisel elaboration!" self.platform = platform self.variant = variant self.reset = Signal() self.interrupt = Signal(4) self.mem_axi = mem_axi = axi.AXIInterface(data_width=32, address_width=32, id_width=4) self.mmio_axi = mmio_axi = axi.AXIInterface(data_width=32, address_width=32, id_width=4) self.mem_wb = mem_wb = wishbone.Interface() self.mmio_wb = mmio_wb = wishbone.Interface() self.ibus = ibus = wishbone.Interface() self.dbus = dbus = wishbone.Interface() # # # self.specials += Instance( "ExampleRocketSystem", # clock, reset i_clock=ClockSignal(), i_reset=ResetSignal() | self.reset, # debug (ignored) #o_debug_clockeddmi_dmi_req_ready=, i_debug_clockeddmi_dmi_req_valid=0, i_debug_clockeddmi_dmi_req_bits_addr=0, i_debug_clockeddmi_dmi_req_bits_data=0, i_debug_clockeddmi_dmi_req_bits_op=0, i_debug_clockeddmi_dmi_resp_ready=0, #o_debug_clockeddmi_dmi_resp_valid=, #o_debug_clockeddmi_dmi_resp_bits_data=, #o_debug_clockeddmi_dmi_resp_bits_resp=, i_debug_clockeddmi_dmiClock=0, i_debug_clockeddmi_dmiReset=0, #o_debug_ndreset=, #o_debug_dmactive=, # irq i_interrupts=self.interrupt, # axi memory (L1-cached) i_mem_axi4_0_aw_ready=mem_axi.aw.ready, o_mem_axi4_0_aw_valid=mem_axi.aw.valid, o_mem_axi4_0_aw_bits_id=mem_axi.aw.id, o_mem_axi4_0_aw_bits_addr=mem_axi.aw.addr, o_mem_axi4_0_aw_bits_len=mem_axi.aw.len, o_mem_axi4_0_aw_bits_size=mem_axi.aw.size, o_mem_axi4_0_aw_bits_burst=mem_axi.aw.burst, o_mem_axi4_0_aw_bits_lock=mem_axi.aw.lock, o_mem_axi4_0_aw_bits_cache=mem_axi.aw.cache, o_mem_axi4_0_aw_bits_prot=mem_axi.aw.prot, o_mem_axi4_0_aw_bits_qos=mem_axi.aw.qos, i_mem_axi4_0_w_ready=mem_axi.w.ready, o_mem_axi4_0_w_valid=mem_axi.w.valid, o_mem_axi4_0_w_bits_data=mem_axi.w.data, o_mem_axi4_0_w_bits_strb=mem_axi.w.strb, o_mem_axi4_0_w_bits_last=mem_axi.w.last, o_mem_axi4_0_b_ready=mem_axi.b.ready, i_mem_axi4_0_b_valid=mem_axi.b.valid, i_mem_axi4_0_b_bits_id=mem_axi.b.id, i_mem_axi4_0_b_bits_resp=mem_axi.b.resp, i_mem_axi4_0_ar_ready=mem_axi.ar.ready, o_mem_axi4_0_ar_valid=mem_axi.ar.valid, o_mem_axi4_0_ar_bits_id=mem_axi.ar.id, o_mem_axi4_0_ar_bits_addr=mem_axi.ar.addr, o_mem_axi4_0_ar_bits_len=mem_axi.ar.len, o_mem_axi4_0_ar_bits_size=mem_axi.ar.size, o_mem_axi4_0_ar_bits_burst=mem_axi.ar.burst, o_mem_axi4_0_ar_bits_lock=mem_axi.ar.lock, o_mem_axi4_0_ar_bits_cache=mem_axi.ar.cache, o_mem_axi4_0_ar_bits_prot=mem_axi.ar.prot, o_mem_axi4_0_ar_bits_qos=mem_axi.ar.qos, o_mem_axi4_0_r_ready=mem_axi.r.ready, i_mem_axi4_0_r_valid=mem_axi.r.valid, i_mem_axi4_0_r_bits_id=mem_axi.r.id, i_mem_axi4_0_r_bits_data=mem_axi.r.data, i_mem_axi4_0_r_bits_resp=mem_axi.r.resp, i_mem_axi4_0_r_bits_last=mem_axi.r.last, # axi mmio (not cached) i_mmio_axi4_0_aw_ready=mmio_axi.aw.ready, o_mmio_axi4_0_aw_valid=mmio_axi.aw.valid, o_mmio_axi4_0_aw_bits_id=mmio_axi.aw.id, o_mmio_axi4_0_aw_bits_addr=mmio_axi.aw.addr, o_mmio_axi4_0_aw_bits_len=mmio_axi.aw.len, o_mmio_axi4_0_aw_bits_size=mmio_axi.aw.size, o_mmio_axi4_0_aw_bits_burst=mmio_axi.aw.burst, o_mmio_axi4_0_aw_bits_lock=mmio_axi.aw.lock, o_mmio_axi4_0_aw_bits_cache=mmio_axi.aw.cache, o_mmio_axi4_0_aw_bits_prot=mmio_axi.aw.prot, o_mmio_axi4_0_aw_bits_qos=mmio_axi.aw.qos, i_mmio_axi4_0_w_ready=mmio_axi.w.ready, o_mmio_axi4_0_w_valid=mmio_axi.w.valid, o_mmio_axi4_0_w_bits_data=mmio_axi.w.data, o_mmio_axi4_0_w_bits_strb=mmio_axi.w.strb, o_mmio_axi4_0_w_bits_last=mmio_axi.w.last, o_mmio_axi4_0_b_ready=mmio_axi.b.ready, i_mmio_axi4_0_b_valid=mmio_axi.b.valid, i_mmio_axi4_0_b_bits_id=mmio_axi.b.id, i_mmio_axi4_0_b_bits_resp=mmio_axi.b.resp, i_mmio_axi4_0_ar_ready=mmio_axi.ar.ready, o_mmio_axi4_0_ar_valid=mmio_axi.ar.valid, o_mmio_axi4_0_ar_bits_id=mmio_axi.ar.id, o_mmio_axi4_0_ar_bits_addr=mmio_axi.ar.addr, o_mmio_axi4_0_ar_bits_len=mmio_axi.ar.len, o_mmio_axi4_0_ar_bits_size=mmio_axi.ar.size, o_mmio_axi4_0_ar_bits_burst=mmio_axi.ar.burst, o_mmio_axi4_0_ar_bits_lock=mmio_axi.ar.lock, o_mmio_axi4_0_ar_bits_cache=mmio_axi.ar.cache, o_mmio_axi4_0_ar_bits_prot=mmio_axi.ar.prot, o_mmio_axi4_0_ar_bits_qos=mmio_axi.ar.qos, o_mmio_axi4_0_r_ready=mmio_axi.r.ready, i_mmio_axi4_0_r_valid=mmio_axi.r.valid, i_mmio_axi4_0_r_bits_id=mmio_axi.r.id, i_mmio_axi4_0_r_bits_data=mmio_axi.r.data, i_mmio_axi4_0_r_bits_resp=mmio_axi.r.resp, i_mmio_axi4_0_r_bits_last=mmio_axi.r.last, ) # adapt axi interfaces to wishbone mem_a2w = ResetInserter()(axi.AXI2Wishbone(mem_axi, mem_wb, base_address=0)) mmio_a2w = ResetInserter()(axi.AXI2Wishbone(mmio_axi, mmio_wb, base_address=0)) # NOTE: AXI2Wishbone FSMs must be reset with the CPU! self.comb += [ mem_a2w.reset.eq(ResetSignal() | self.reset), mmio_a2w.reset.eq(ResetSignal() | self.reset), ] # down-convert wishbone from 64 to 32 bit data width # mem_dc = wishbone.Converter(mem_wb, ibus) # mmio_dc = wishbone.Converter(mmio_wb, dbus) self.submodules += mem_a2w, mmio_a2w # add verilog sources self.add_sources(platform, variant)