def __init__(self, platform, eba_reset): self.ibus = i = wishbone.Interface() self.dbus = d = wishbone.Interface() self.interrupt = Signal(32) ### i_adr_o = Signal(32) d_adr_o = Signal(32) self.specials += Instance("lm32_cpu", p_eba_reset=Instance.PreformattedParam( "32'h{:08x}".format(eba_reset)), i_clk_i=ClockSignal(), i_rst_i=ResetSignal(), i_interrupt=self.interrupt, o_I_ADR_O=i_adr_o, o_I_DAT_O=i.dat_w, o_I_SEL_O=i.sel, o_I_CYC_O=i.cyc, o_I_STB_O=i.stb, o_I_WE_O=i.we, o_I_CTI_O=i.cti, o_I_BTE_O=i.bte, i_I_DAT_I=i.dat_r, i_I_ACK_I=i.ack, i_I_ERR_I=i.err, i_I_RTY_I=0, o_D_ADR_O=d_adr_o, o_D_DAT_O=d.dat_w, o_D_SEL_O=d.sel, o_D_CYC_O=d.cyc, o_D_STB_O=d.stb, o_D_WE_O=d.we, o_D_CTI_O=d.cti, o_D_BTE_O=d.bte, i_D_DAT_I=d.dat_r, i_D_ACK_I=d.ack, i_D_ERR_I=d.err, i_D_RTY_I=0) self.comb += [ self.ibus.adr.eq(i_adr_o[2:]), self.dbus.adr.eq(d_adr_o[2:]) ] # add Verilog sources platform.add_sources( os.path.join("extcores", "lm32", "submodule", "rtl"), "lm32_cpu.v", "lm32_instruction_unit.v", "lm32_decoder.v", "lm32_load_store_unit.v", "lm32_adder.v", "lm32_addsub.v", "lm32_logic_op.v", "lm32_shifter.v", "lm32_multiplier.v", "lm32_mc_arithmetic.v", "lm32_interrupt.v", "lm32_ram.v", "lm32_dp_ram.v", "lm32_icache.v", "lm32_dcache.v", "lm32_debug.v", "lm32_itlb.v", "lm32_dtlb.v") platform.add_verilog_include_path(os.path.join("extcores", "lm32"))
def __init__(self): self.i1 = wishbone.Interface() self.i2 = wishbone.Interface() # # # value = Signal(32) for i in self.i1, self.i2: self.sync += [ i.dat_r.eq(value), i.ack.eq(0), If(i.cyc & i.stb & ~i.ack, i.ack.eq(1), If(i.we, value.eq(i.dat_w))) ]
def __init__(self, address_width, wb=None): if wb is None: wb = wishbone.Interface() self.wb = wb self.rtlink = rtlink.Interface( rtlink.OInterface(flen(wb.dat_w), address_width + 1, suppress_nop=False), rtlink.IInterface(flen(wb.dat_r), timestamped=False)) # # # active = Signal() self.sync.rio += [ If(self.rtlink.o.stb, active.eq(1), wb.adr.eq(self.rtlink.o.address[:address_width]), wb.we.eq(~self.rtlink.o.address[address_width]), wb.dat_w.eq(self.rtlink.o.data), wb.sel.eq(2**flen(wb.sel) - 1)), If(wb.ack, active.eq(0)) ] self.comb += [ self.rtlink.o.busy.eq(active), wb.cyc.eq(active), wb.stb.eq(active), self.rtlink.i.stb.eq(wb.ack & ~wb.we), self.rtlink.i.data.eq(wb.dat_r) ]
def __init__(self): self.bus = wishbone.Interface() self.address = Sink([("a", 30)]) self.data = Source([("d", 32)]) self.busy = Signal() ### bus_stb = Signal() data_reg_loaded = Signal() data_reg = Signal(32) self.comb += [ self.busy.eq(data_reg_loaded), self.bus.we.eq(0), bus_stb.eq(self.address.stb & (~data_reg_loaded | self.data.ack)), self.bus.cyc.eq(bus_stb), self.bus.stb.eq(bus_stb), self.bus.adr.eq(self.address.a), self.address.ack.eq(self.bus.ack), self.data.stb.eq(data_reg_loaded), self.data.d.eq(data_reg) ] self.sync += [ If(self.data.ack, data_reg_loaded.eq(0)), If(self.bus.ack, data_reg_loaded.eq(1), data_reg.eq(self.bus.dat_r)) ]
def __init__(self, cachesize, asmiport): self.wishbone = wishbone.Interface() self.cachesize = cachesize self.asmiport = asmiport if len(self.asmiport.slots) != 1: raise ValueError("ASMI port must have 1 slot") if self.asmiport.hub.dw <= 32: raise ValueError("ASMI data width must be strictly larger than 32") if (self.asmiport.hub.dw % 32) != 0: raise ValueError("ASMI data width must be a multiple of 32")
def __init__(self, platform, clk_freq, sdram_controller_settings, **kwargs): SoC.__init__(self, platform, clk_freq, **kwargs) if isinstance(sdram_controller_settings, str): self.sdram_controller_settings = eval(sdram_controller_settings) else: self.sdram_controller_settings = sdram_controller_settings self._sdram_phy_registered = False self._wb_sdram_ifs = [] self._wb_sdram = wishbone.Interface()
def __init__(self, we_bit=28, sel_bits=slice(24, 28)): super(Wishbone, self).__init__() self.bus = bus = wishbone.Interface() ### start = Signal() read = Signal() self.sync += [ If( start, self.bus.adr.eq(self.dout.payload.addr), self.bus.dat_w.eq(self.dout.payload.data), ), If( read, self.din.payload.data.eq(self.bus.dat_r), ) ] self.comb += [ self.dout.ack.eq(1), self.din.payload.addr.eq(self.bus.adr), self.bus.cyc.eq(self.bus.stb), self.bus.we.eq(self.bus.adr[we_bit]), ] if sel_bits is not None: self.comb += self.bus.sel.eq(self.bus.adr[sel_bits]) else: self.bus.sel.reset = 0b1111 self.submodules.fsm = fsm = FSM() fsm.act("IDLE", If( self.dout.stb, start.eq(1), NextState("BUS"), )) fsm.act( "BUS", self.bus.stb.eq(1), If( self.bus.ack, If( self.bus.we, NextState("IDLE"), ).Else( read.eq(1), NextState("QUEUE"), ), )) fsm.act("QUEUE", self.din.stb.eq(1), If( self.din.ack, NextState("IDLE"), ))
def __init__(self): self.bus = wishbone.Interface() self.address_data = Sink([("a", 30), ("d", 32)]) self.busy = Signal() ### self.comb += [ self.busy.eq(0), self.bus.we.eq(1), self.bus.cyc.eq(self.address_data.stb), self.bus.stb.eq(self.address_data.stb), self.bus.adr.eq(self.address_data.a), self.bus.sel.eq(0xf), self.bus.dat_w.eq(self.address_data.d), self.address_data.ack.eq(self.bus.ack) ]
def __init__(self, dw, nrxslots=2, ntxslots=2): self.sink = Sink(eth_phy_description(dw)) self.source = Source(eth_phy_description(dw)) self.bus = wishbone.Interface() # # # # storage in SRAM sram_depth = buffer_depth // (dw // 8) self.submodules.sram = sram.LiteEthMACSRAM(dw, sram_depth, nrxslots, ntxslots) self.comb += [ Record.connect(self.sink, self.sram.sink), Record.connect(self.sram.source, self.source) ] # Wishbone interface wb_rx_sram_ifs = [ wishbone.SRAM(self.sram.writer.mems[n], read_only=True) for n in range(nrxslots) ] # TODO: FullMemoryWE should move to Mibuild wb_tx_sram_ifs = [ FullMemoryWE()(wishbone.SRAM(self.sram.reader.mems[n], read_only=False)) for n in range(ntxslots) ] wb_sram_ifs = wb_rx_sram_ifs + wb_tx_sram_ifs wb_slaves = [] decoderoffset = log2_int(sram_depth) decoderbits = log2_int(len(wb_sram_ifs)) for n, wb_sram_if in enumerate(wb_sram_ifs): def slave_filter(a, v=n): return a[decoderoffset:decoderoffset + decoderbits] == v wb_slaves.append((slave_filter, wb_sram_if.bus)) self.submodules += wb_sram_if wb_con = wishbone.Decoder(self.bus, wb_slaves, register=True) self.submodules += wb_con
def __init__(self, bus_wishbone=None, bus_csr=None): if bus_wishbone is None: bus_wishbone = wishbone.Interface() self.wishbone = bus_wishbone if bus_csr is None: bus_csr = csr.Interface() self.csr = bus_csr ### self.sync += [ self.csr.we.eq(0), self.csr.dat_w.eq(self.wishbone.dat_w), self.csr.adr.eq(self.wishbone.adr), self.wishbone.dat_r.eq(self.csr.dat_r) ] self.sync += timeline(self.wishbone.cyc & self.wishbone.stb, [ (1, [self.csr.we.eq(self.wishbone.we)]), (2, [self.wishbone.ack.eq(1)]), (3, [self.wishbone.ack.eq(0)]) ])
def __init__(self, platform, exec_address=0x40400000, main_mem_origin=0x40000000, l2_size=8192): self._reset = CSRStorage(reset=1) # # # self._wb_slaves = [] # CPU core self.clock_domains.cd_sys_kernel = ClockDomain() self.comb += [ self.cd_sys_kernel.clk.eq(ClockSignal()), self.cd_sys_kernel.rst.eq(self._reset.storage) ] self.submodules.cpu = RenameClockDomains( mor1kx.MOR1KX(platform, exec_address), "sys_kernel") # DRAM access self.wb_sdram = wishbone.Interface() self.add_wb_slave(mem_decoder(main_mem_origin), self.wb_sdram)
def __init__(self, endpoint, address_decoder): self.wishbone = wishbone.Interface() # # # port = endpoint.crossbar.get_slave_port(address_decoder) self.submodules.fsm = fsm = FSM() fsm.act( "IDLE", If(port.sink.stb & port.sink.sop, If( port.sink.we, NextState("WRITE"), ).Else(NextState("READ"))).Else(port.sink.ack.eq( port.sink.stb))) fsm.act("WRITE", self.wishbone.adr.eq(port.sink.adr[2:]), self.wishbone.dat_w.eq(port.sink.dat[:32]), self.wishbone.sel.eq(0xf), self.wishbone.stb.eq(1), self.wishbone.we.eq(1), self.wishbone.cyc.eq(1), If(self.wishbone.ack, port.sink.ack.eq(1), NextState("IDLE"))) fsm.act("READ", self.wishbone.adr.eq(port.sink.adr[2:]), self.wishbone.stb.eq(1), self.wishbone.we.eq(0), self.wishbone.cyc.eq(1), If(self.wishbone.ack, NextState("COMPLETION"))) self.sync += \ If(self.wishbone.stb & self.wishbone.ack, port.source.dat.eq(self.wishbone.dat_r), ) fsm.act("COMPLETION", port.source.stb.eq(1), port.source.sop.eq(1), port.source.eop.eq(1), port.source.len.eq(1), port.source.err.eq(0), port.source.tag.eq(port.sink.tag), port.source.adr.eq(port.sink.adr), port.source.cmp_id.eq(endpoint.phy.id), port.source.req_id.eq(port.sink.req_id), If(port.source.ack, port.sink.ack.eq(1), NextState("IDLE")))
def __init__(self, platform, reset_pc): self.ibus = i = wishbone.Interface() self.dbus = d = wishbone.Interface() self.interrupt = Signal(32) ### i_adr_o = Signal(32) d_adr_o = Signal(32) self.specials += Instance("mor1kx", 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="NONE", p_FEATURE_CMOV="NONE", p_FEATURE_FFL1="NONE", p_OPTION_CPU0="CAPPUCCINO", p_OPTION_RESET_PC=reset_pc, p_IBUS_WB_TYPE="B3_REGISTERED_FEEDBACK", p_DBUS_WB_TYPE="B3_REGISTERED_FEEDBACK", i_clk=ClockSignal(), i_rst=ResetSignal(), 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 platform.add_source_dir( os.path.join("extcores", "mor1kx", "submodule", "rtl", "verilog"))
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 = flen(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 = flen(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): self.bus = wishbone.Interface() super().__init__(("address", Sink, [("a", BV(30))]), ("data", Source, [("d", BV(32))]))
def register_sdram_phy(self, phy): if self._sdram_phy_registered: raise FinalizeError self._sdram_phy_registered = True # Core self.submodules.sdram = SDRAMCore(phy, phy.module.geom_settings, phy.module.timing_settings, self.sdram_controller_settings) dfi_databits_divisor = 1 if phy.settings.memtype == "SDR" else 2 sdram_width = phy.settings.dfi_databits // dfi_databits_divisor main_ram_size = 2**( phy.module.geom_settings.bankbits + phy.module.geom_settings.rowbits + phy.module.geom_settings.colbits) * sdram_width // 8 # XXX: Limit main_ram_size to 256MB, we should modify mem_map to allow larger memories. main_ram_size = min(main_ram_size, 256 * 1024 * 1024) l2_size = self.sdram_controller_settings.l2_size if l2_size: self.add_constant("L2_SIZE", l2_size) # add a Wishbone interface to the DRAM wb_sdram = wishbone.Interface() self.add_wb_sdram_if(wb_sdram) self.register_mem("main_ram", self.mem_map["main_ram"], wb_sdram, main_ram_size) # LASMICON frontend if isinstance(self.sdram_controller_settings, LASMIconSettings): if self.sdram_controller_settings.with_bandwidth: self.sdram.controller.multiplexer.add_bandwidth() if self.sdram_controller_settings.with_memtest: self.submodules.memtest_w = memtest.MemtestWriter( self.sdram.crossbar.get_master()) self.submodules.memtest_r = memtest.MemtestReader( self.sdram.crossbar.get_master()) if l2_size: lasmim = self.sdram.crossbar.get_master() l2_cache = wishbone.Cache(l2_size // 4, self._wb_sdram, wishbone.Interface(lasmim.dw)) # XXX Vivado ->2015.1 workaround, Vivado is not able to map correctly our L2 cache. # Issue is reported to Xilinx and should be fixed in next releases (2015.2?). # Remove this workaround when fixed by Xilinx. from mibuild.xilinx.vivado import XilinxVivadoToolchain if isinstance(self.platform.toolchain, XilinxVivadoToolchain): from migen.fhdl.simplify import FullMemoryWE self.submodules.l2_cache = FullMemoryWE()(l2_cache) else: self.submodules.l2_cache = l2_cache self.submodules.wishbone2lasmi = wishbone2lasmi.WB2LASMI( self.l2_cache.slave, lasmim) # MINICON frontend elif isinstance(self.sdram_controller_settings, MiniconSettings): if l2_size: l2_cache = wishbone.Cache(l2_size // 4, self._wb_sdram, self.sdram.controller.bus) # XXX Vivado ->2015.1 workaround, Vivado is not able to map correctly our L2 cache. # Issue is reported to Xilinx and should be fixed in next releases (2015.2?). # Remove this workaround when fixed by Xilinx. from mibuild.xilinx.vivado import XilinxVivadoToolchain if isinstance(self.platform.toolchain, XilinxVivadoToolchain): from migen.fhdl.simplify import FullMemoryWE self.submodules.l2_cache = FullMemoryWE()(l2_cache) else: self.submodules.l2_cache = l2_cache else: self.submodules.converter = wishbone.Converter( self._wb_sdram, self.sdram.controller.bus)
def __init__(self, slaves, depth=256, bus=None, with_wishbone=True): time_width, addr_width, data_width = [_[1] for _ in ventilator_layout] self.submodules.ctrl = CycleControl() self.submodules.ev = ev = EventManager() ev.in_readable = EventSourceLevel() ev.out_overflow = EventSourceProcess() ev.in_overflow = EventSourceLevel() ev.out_readable = EventSourceProcess() ev.stopped = EventSourceProcess() ev.started = EventSourceProcess() ev.finalize() self._in_time = CSRStatus(time_width) self._in_addr = CSRStatus(addr_width) self._in_data = CSRStatus(data_width) self._in_next = CSR() self._in_flush = CSR() self._out_time = CSRStorage(time_width, write_from_dev=with_wishbone) self._out_addr = CSRStorage(addr_width, write_from_dev=with_wishbone) self._out_data = CSRStorage(data_width, write_from_dev=with_wishbone) self._out_next = CSR() self._out_flush = CSR() self.busy = Signal() ### if with_wishbone: if bus is None: bus = wishbone.Interface() self.bus = bus slaves = [(self.ctrl, 0x00000000, 0xffffff00)] + slaves self.submodules.in_fifo = in_fifo = SyncFIFOBuffered( ventilator_layout, depth) self.submodules.out_fifo = out_fifo = SyncFIFOBuffered( ventilator_layout, depth) self.submodules.enc = PriorityEncoder(len(slaves)) wb_in_next = Signal() wb_out_next = Signal() out_request = Signal() in_request = Signal() # CSRs and Events self.comb += [ ev.in_readable.trigger.eq(in_fifo.readable), ev.out_overflow.trigger.eq(~out_fifo.writable), ev.in_overflow.trigger.eq(~in_fifo.writable), ev.out_readable.trigger.eq(out_fifo.readable), ev.started.trigger.eq(~self.ctrl.run), ev.stopped.trigger.eq(self.ctrl.run), self.ctrl.have_in.eq(~self.enc.n), self.ctrl.have_out.eq(out_fifo.readable), self._in_time.status.eq(in_fifo.dout.time), self._in_addr.status.eq(in_fifo.dout.addr), self._in_data.status.eq(in_fifo.dout.data), in_fifo.re.eq(self._in_next.re | wb_in_next), in_fifo.flush.eq(self._in_flush.re), out_fifo.din.time.eq(self._out_time.storage), out_fifo.din.addr.eq(self._out_addr.storage), out_fifo.din.data.eq(self._out_data.storage), out_fifo.we.eq(self._out_next.re | wb_out_next), out_fifo.flush.eq(self._out_flush.re), ] # din dout strobing self.comb += [ # TODO: 0 <= diff <= plausibility range out_request.eq(out_fifo.readable & self.ctrl.run & (self.ctrl.cycle == out_fifo.dout.time)), # ignore in_fifo.writable in_request.eq(~self.enc.n & self.ctrl.run), self.busy.eq(out_request | in_request), ] # to slaves addrs = [] datas = [] stbs = [] acks = [] for i, (slave, prefix, mask) in enumerate(slaves): prefix &= mask source = Source(slave_layout) sink = Sink(slave_layout) self.comb += [ source.connect(slave.dout), sink.connect(slave.din), ] sel = Signal() acks.append(sel & source.ack) addrs.append(prefix | (sink.payload.addr & (~mask & 0xffffffff))) datas.append(sink.payload.data) stbs.append(sink.stb) self.comb += [ sel.eq(out_fifo.dout.addr & mask == prefix), source.payload.addr.eq(out_fifo.dout.addr), source.payload.data.eq(out_fifo.dout.data), source.stb.eq(sel & out_request), sink.ack.eq((self.enc.o == i) & in_request), ] self.comb += out_fifo.re.eq(out_request & optree("|", acks)) # from slaves self.comb += [ self.enc.i.eq(Cat(stbs)), in_fifo.din.time.eq(self.ctrl.cycle), in_fifo.din.addr.eq(Array(addrs)[self.enc.o]), in_fifo.din.data.eq(Array(datas)[self.enc.o]), in_fifo.we.eq(in_request), ] # optional high throughput wishbone access if with_wishbone: self.comb += [ self._out_time.dat_w.eq(bus.dat_w), self._out_addr.dat_w.eq(bus.dat_w), self._out_data.dat_w.eq(bus.dat_w), If( bus.cyc & bus.stb, If( bus.we, Case( bus.adr[:4], { 0x5: wb_in_next.eq(1), 0x6: self._out_time.we.eq(1), 0x7: self._out_addr.we.eq(1), 0x8: self._out_data.we.eq(1), 0x9: wb_out_next.eq(1), }), ), Case( bus.adr[:4], { 0x0: bus.dat_r.eq(self.ctrl.cycle), 0x1: bus.dat_r.eq(self.ev.status.w), 0x2: bus.dat_r.eq(in_fifo.dout.time), 0x3: bus.dat_r.eq(in_fifo.dout.addr), 0x4: bus.dat_r.eq(in_fifo.dout.data), }), ) ] self.sync += bus.ack.eq(bus.cyc & bus.stb & ~bus.ack)
def __init__(self): self.sink = sink = Sink(eth_etherbone_mmap_description(32)) self.source = source = Source(eth_etherbone_mmap_description(32)) self.bus = bus = wishbone.Interface() # # # self.submodules.data = data = FlipFlop(32) self.comb += data.d.eq(bus.dat_r) self.submodules.fsm = fsm = FSM(reset_state="IDLE") fsm.act("IDLE", sink.ack.eq(1), If(sink.stb & sink.sop, sink.ack.eq(0), If(sink.we, NextState("WRITE_DATA") ).Else( NextState("READ_DATA") ) ) ) fsm.act("WRITE_DATA", bus.adr.eq(sink.addr), bus.dat_w.eq(sink.data), bus.sel.eq(sink.be), bus.stb.eq(sink.stb), bus.we.eq(1), bus.cyc.eq(1), If(bus.stb & bus.ack, sink.ack.eq(1), If(sink.eop, NextState("IDLE") ) ) ) fsm.act("READ_DATA", bus.adr.eq(sink.addr), bus.sel.eq(sink.be), bus.stb.eq(sink.stb), bus.cyc.eq(1), If(bus.stb & bus.ack, data.ce.eq(1), NextState("SEND_DATA") ) ) fsm.act("SEND_DATA", source.stb.eq(sink.stb), source.sop.eq(sink.sop), source.eop.eq(sink.eop), source.base_addr.eq(sink.base_addr), source.addr.eq(sink.addr), source.count.eq(sink.count), source.be.eq(sink.be), source.we.eq(1), source.data.eq(data.q), If(source.stb & source.ack, sink.ack.eq(1), If(source.eop, NextState("IDLE") ).Else( NextState("READ_DATA") ) ) )
def __init__(self, phy_settings, geom_settings, timing_settings): if phy_settings.memtype in ["SDR"]: burst_length = phy_settings.nphases * 1 # command multiplication*SDR elif phy_settings.memtype in ["DDR", "LPDDR", "DDR2", "DDR3"]: burst_length = phy_settings.nphases * 2 # command multiplication*DDR burst_width = phy_settings.dfi_databits * phy_settings.nphases address_align = log2_int(burst_length) # # # self.dfi = dfi = dfibus.Interface(geom_settings.addressbits, geom_settings.bankbits, phy_settings.dfi_databits, phy_settings.nphases) self.bus = bus = wishbone.Interface(burst_width) rdphase = phy_settings.rdphase wrphase = phy_settings.wrphase precharge_all = Signal() activate = Signal() refresh = Signal() write = Signal() read = Signal() # Compute current column, bank and row from wishbone address slicer = _AddressSlicer(geom_settings.colbits, geom_settings.bankbits, geom_settings.rowbits, address_align) # Manage banks bank_open = Signal() bank_idle = Signal() bank_hit = Signal() banks = [] for i in range(2**geom_settings.bankbits): bank = _Bank(geom_settings) self.comb += [ bank.open.eq(activate), bank.reset.eq(precharge_all), bank.row.eq(slicer.row(bus.adr)) ] banks.append(bank) self.submodules += banks cases = {} for i, bank in enumerate(banks): cases[i] = [bank.ce.eq(1)] self.comb += Case(slicer.bank(bus.adr), cases) self.comb += [ bank_hit.eq(optree("|", [bank.hit & bank.ce for bank in banks])), bank_idle.eq(optree("|", [bank.idle & bank.ce for bank in banks])), ] # Timings write2precharge_timer = WaitTimer(2 + timing_settings.tWR - 1) self.submodules += write2precharge_timer self.comb += write2precharge_timer.wait.eq(~write) refresh_timer = WaitTimer(timing_settings.tREFI) self.submodules += refresh_timer self.comb += refresh_timer.wait.eq(~refresh) # Main FSM self.submodules.fsm = fsm = FSM() fsm.act( "IDLE", If(refresh_timer.done, NextState("PRECHARGE-ALL")).Elif( bus.stb & bus.cyc, If(bank_hit, If(bus.we, NextState("WRITE")).Else(NextState("READ"))).Elif( ~bank_idle, If(write2precharge_timer.done, NextState("PRECHARGE"))).Else( NextState("ACTIVATE")))) fsm.act( "READ", read.eq(1), dfi.phases[rdphase].ras_n.eq(1), dfi.phases[rdphase].cas_n.eq(0), dfi.phases[rdphase].we_n.eq(1), dfi.phases[rdphase].rddata_en.eq(1), NextState("WAIT-READ-DONE"), ) fsm.act( "WAIT-READ-DONE", If(dfi.phases[rdphase].rddata_valid, bus.ack.eq(1), NextState("IDLE"))) fsm.act("WRITE", write.eq(1), dfi.phases[wrphase].ras_n.eq(1), dfi.phases[wrphase].cas_n.eq(0), dfi.phases[wrphase].we_n.eq(0), dfi.phases[wrphase].wrdata_en.eq(1), NextState("WRITE-LATENCY")) fsm.act("WRITE-ACK", bus.ack.eq(1), NextState("IDLE")) fsm.act("PRECHARGE-ALL", precharge_all.eq(1), dfi.phases[rdphase].ras_n.eq(0), dfi.phases[rdphase].cas_n.eq(1), dfi.phases[rdphase].we_n.eq(0), NextState("PRE-REFRESH")) fsm.act( "PRECHARGE", # do no reset bank since we are going to re-open it dfi.phases[0].ras_n.eq(0), dfi.phases[0].cas_n.eq(1), dfi.phases[0].we_n.eq(0), NextState("TRP")) fsm.act( "ACTIVATE", activate.eq(1), dfi.phases[0].ras_n.eq(0), dfi.phases[0].cas_n.eq(1), dfi.phases[0].we_n.eq(1), NextState("TRCD"), ) fsm.act("REFRESH", refresh.eq(1), dfi.phases[rdphase].ras_n.eq(0), dfi.phases[rdphase].cas_n.eq(0), dfi.phases[rdphase].we_n.eq(1), NextState("POST-REFRESH")) fsm.delayed_enter("WRITE-LATENCY", "WRITE-ACK", phy_settings.write_latency - 1) fsm.delayed_enter("TRP", "ACTIVATE", timing_settings.tRP - 1) fsm.delayed_enter("TRCD", "IDLE", timing_settings.tRCD - 1) fsm.delayed_enter("PRE-REFRESH", "REFRESH", timing_settings.tRP - 1) fsm.delayed_enter("POST-REFRESH", "IDLE", timing_settings.tRFC - 1) # DFI commands for phase in dfi.phases: if hasattr(phase, "reset_n"): self.comb += phase.reset_n.eq(1) if hasattr(phase, "odt"): self.comb += phase.odt.eq(1) self.comb += [ phase.cke.eq(1), phase.cs_n.eq(0), phase.bank.eq(slicer.bank(bus.adr)), If(precharge_all, phase.address.eq(2**10)).Elif( activate, phase.address.eq(slicer.row(bus.adr))).Elif( write | read, phase.address.eq(slicer.col(bus.adr))) ] # DFI datapath self.comb += [ bus.dat_r.eq(Cat(phase.rddata for phase in dfi.phases)), Cat(phase.wrdata for phase in dfi.phases).eq(bus.dat_w), Cat(phase.wrdata_mask for phase in dfi.phases).eq(~bus.sel), ]
def add_interfaces(obj): obj.result = Source(layout) obj.wb = wishbone.Interface() obj.mem = Memory(32, 3, init=[42, 37, 81]) obj.finalize()
def __init__(self, platform): self.sink = Sink(EndpointDescription([("data", 16)], packetized=True)) self.source = Source([("data", 8)]) self.bus = wishbone.Interface() # # # # chroma upsampler chroma_upsampler = RenameClockDomains(YCbCr422to444(), "encoder") self.submodules += chroma_upsampler self.comb += [ Record.connect(self.sink, chroma_upsampler.sink, leave_out=["data"]), chroma_upsampler.sink.y.eq(self.sink.data[:8]), chroma_upsampler.sink.cb_cr.eq(self.sink.data[8:]) ] # output fifo output_fifo_almost_full = Signal() output_fifo = RenameClockDomains(SyncFIFO([("data", 8)], 1024), "encoder") self.submodules += output_fifo 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, i_fdct_ack=chroma_upsampler.source.ack, i_fdct_stb=chroma_upsampler.source.stb, i_fdct_data=Cat(chroma_upsampler.source.y, chroma_upsampler.source.cb, chroma_upsampler.source.cr), o_ram_byte=output_fifo.sink.data, o_ram_wren=output_fifo.sink.stb, #o_ram_wraddr=, #o_frame_size=, i_outif_almost_full=output_fifo_almost_full) # add vhdl sources platform.add_source_dir( os.path.join(platform.soc_ext_path, "gateware", "encoder", "vhdl")) # add verilog sources platform.add_source( os.path.join(platform.soc_ext_path, "gateware", "encoder", "verilog", "wb_async_reg.v")) # bandwidth self.submodules.bandwidth = EncoderBandwidth() # XXX add CDC self.comb += self.bandwidth.nbytes_inc.eq(self.source.stb & self.source.ack)
def __init__(self, phy, clk_freq): self.wishbone = wishbone.Interface() # # # byte_counter = Counter(3) word_counter = Counter(8) self.submodules += byte_counter, word_counter cmd = Signal(8) cmd_ce = Signal() length = Signal(8) length_ce = Signal() address = Signal(32) address_ce = Signal() data = Signal(32) rx_data_ce = Signal() tx_data_ce = Signal() self.sync += [ If(cmd_ce, cmd.eq(phy.source.data)), If(length_ce, length.eq(phy.source.data)), If(address_ce, address.eq(Cat(phy.source.data, address[0:24]))), If(rx_data_ce, data.eq(Cat(phy.source.data, data[0:24]))).Elif(tx_data_ce, data.eq(self.wishbone.dat_r)) ] fsm = InsertReset(FSM(reset_state="IDLE")) timer = WaitTimer(clk_freq // 10) self.submodules += fsm, timer self.comb += [fsm.reset.eq(timer.done), phy.source.ack.eq(1)] fsm.act( "IDLE", If( phy.source.stb, cmd_ce.eq(1), If((phy.source.data == self.cmds["write"]) | (phy.source.data == self.cmds["read"]), NextState("RECEIVE_LENGTH")), byte_counter.reset.eq(1), word_counter.reset.eq(1))) fsm.act( "RECEIVE_LENGTH", If(phy.source.stb, length_ce.eq(1), NextState("RECEIVE_ADDRESS"))) fsm.act( "RECEIVE_ADDRESS", If( phy.source.stb, address_ce.eq(1), byte_counter.ce.eq(1), If( byte_counter.value == 3, If(cmd == self.cmds["write"], NextState("RECEIVE_DATA")).Elif( cmd == self.cmds["read"], NextState("READ_DATA")), byte_counter.reset.eq(1), ))) fsm.act( "RECEIVE_DATA", If( phy.source.stb, rx_data_ce.eq(1), byte_counter.ce.eq(1), If(byte_counter.value == 3, NextState("WRITE_DATA"), byte_counter.reset.eq(1)))) self.comb += [ self.wishbone.adr.eq(address + word_counter.value), self.wishbone.dat_w.eq(data), self.wishbone.sel.eq(2**flen(self.wishbone.sel) - 1) ] fsm.act( "WRITE_DATA", self.wishbone.stb.eq(1), self.wishbone.we.eq(1), self.wishbone.cyc.eq(1), If( self.wishbone.ack, word_counter.ce.eq(1), If(word_counter.value == (length - 1), NextState("IDLE")).Else(NextState("RECEIVE_DATA")))) fsm.act( "READ_DATA", self.wishbone.stb.eq(1), self.wishbone.we.eq(0), self.wishbone.cyc.eq(1), If(self.wishbone.ack, tx_data_ce.eq(1), NextState("SEND_DATA"))) self.comb += \ chooser(data, byte_counter.value, phy.sink.data, n=4, reverse=True) fsm.act( "SEND_DATA", phy.sink.stb.eq(1), If( phy.sink.ack, byte_counter.ce.eq(1), If( byte_counter.value == 3, word_counter.ce.eq(1), If(word_counter.value == (length - 1), NextState("IDLE")).Else(NextState("READ_DATA"), byte_counter.reset.eq(1))))) self.comb += timer.wait.eq(~fsm.ongoing("IDLE")) if phy.sink.description.packetized: self.comb += [ phy.sink.sop.eq((byte_counter.value == 0) & (word_counter.value == 0)), phy.sink.eop.eq((byte_counter.value == 3) & (word_counter.value == (length - 1))) ] if hasattr(phy.sink, "length"): self.comb += phy.sink.length.eq(4 * length)
def __init__(self, pads, rd_timing, wr_timing): self.bus = wishbone.Interface() ### data = TSTriple(16) lsb = Signal() self.specials += data.get_tristate(pads.d) self.comb += [data.oe.eq(pads.oe_n), pads.ce_n.eq(0)] load_lo = Signal() load_hi = Signal() store = Signal() pads.oe_n.reset, pads.we_n.reset = 1, 1 self.sync += [ pads.oe_n.eq(1), pads.we_n.eq(1), # Register data/address to avoid off-chip glitches If( self.bus.cyc & self.bus.stb, pads.adr.eq(Cat(lsb, self.bus.adr)), If( self.bus.we, # Only 16-bit writes are supported. Assume sel=0011 or 1100. If(self.bus.sel[0], data.o.eq(self.bus.dat_w[:16])).Else( data.o.eq(self.bus.dat_w[16:]) )).Else(pads.oe_n.eq(0))), If(load_lo, self.bus.dat_r[:16].eq(data.i)), If(load_hi, self.bus.dat_r[16:].eq(data.i)), If(store, pads.we_n.eq(0)) ] # Typical timing of the flash chips: # - 110ns address to output # - 50ns write pulse width counter = Signal(max=max(rd_timing, wr_timing) + 1) counter_en = Signal() counter_wr_mode = Signal() counter_done = Signal() self.comb += counter_done.eq( counter == Mux(counter_wr_mode, wr_timing, rd_timing)) self.sync += If(counter_en & ~counter_done, counter.eq(counter + 1)).Else(counter.eq(0)) fsm = FSM() self.submodules += fsm fsm.act( "IDLE", If(self.bus.cyc & self.bus.stb, If(self.bus.we, NextState("WR")).Else(NextState("RD_HI")))) fsm.act("RD_HI", lsb.eq(0), counter_en.eq(1), If(counter_done, load_hi.eq(1), NextState("RD_LO"))) fsm.act("RD_LO", lsb.eq(1), counter_en.eq(1), If(counter_done, load_lo.eq(1), NextState("ACK"))) fsm.act( "WR", # supported cases: sel=0011 [lsb=1] and sel=1100 [lsb=0] lsb.eq(self.bus.sel[0]), counter_wr_mode.eq(1), 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, drive_fud=False, bus=None): if bus is None: bus = wishbone.Interface() self.bus = bus # # # dts = TSTriple(8) self.specials += dts.get_tristate(pads.d) dr = Signal(8) rx = Signal() self.sync += [ pads.a.eq(bus.adr), dts.o.eq(bus.dat_w), dr.eq(dts.i), dts.oe.eq(~rx) ] gpio = Signal(flen(pads.sel) + flen(pads.p) + 1) gpio_load = Signal() self.sync += If(gpio_load, gpio.eq(bus.dat_w)) self.comb += [ Cat(pads.sel, pads.p).eq(gpio), pads.rst_n.eq(~gpio[-1]), ] bus_r_gpio = Signal() self.comb += If(bus_r_gpio, bus.dat_r.eq(gpio)).Else(bus.dat_r.eq(dr)) if drive_fud: fud = Signal() self.sync += pads.fud_n.eq(~fud) pads.wr_n.reset = 1 pads.rd_n.reset = 1 wr = Signal() rd = Signal() self.sync += pads.wr_n.eq(~wr), pads.rd_n.eq(~rd) fsm = FSM("IDLE") self.submodules += fsm fsm.act( "IDLE", If( bus.cyc & bus.stb, If( bus.adr[6], If(bus.adr[0], NextState("GPIO")).Else( NextState("FUD") if drive_fud else None)).Else( If(bus.we, NextState("WRITE")).Else(NextState("READ"))))) fsm.act( "WRITE", # 3ns A setup to WR active wr.eq(1), NextState("WRITE0")) fsm.act( "WRITE0", # 3.5ns D setup to WR inactive # 0ns D and A hold to WR inactive bus.ack.eq(1), NextState("IDLE")) fsm.act( "READ", # 15ns D valid to A setup # 15ns D valid to RD active rx.eq(1), rd.eq(1), NextState("READ0")) fsm.act("READ0", rx.eq(1), rd.eq(1), NextState("READ1")) fsm.act("READ1", rx.eq(1), rd.eq(1), NextState("READ2")) fsm.act("READ2", rx.eq(1), rd.eq(1), NextState("READ3")) fsm.act("READ3", rx.eq(1), rd.eq(1), NextState("READ4")) fsm.act("READ4", rx.eq(1), NextState("READ5")) fsm.act( "READ5", # 5ns D three-state to RD inactive # 10ns A hold to RD inactive rx.eq(1), bus.ack.eq(1), NextState("IDLE")) if drive_fud: fsm.act( "FUD", # 4ns FUD setup to SYNCLK # 0ns FUD hold to SYNCLK fud.eq(1), bus.ack.eq(1), NextState("IDLE")) fsm.act("GPIO", bus.ack.eq(1), bus_r_gpio.eq(1), If(bus.we, gpio_load.eq(1)), NextState("IDLE"))
def __init__(self): self.wishbone = wishbone.Interface() self.csr = csr.Interface()
def __init__(self, cachesize, lasmim): self.wishbone = wishbone.Interface() ### data_width = flen(self.wishbone.dat_r) if lasmim.dw > data_width and (lasmim.dw % data_width) != 0: raise ValueError( "LASMI data width must be a multiple of {dw}".format( dw=data_width)) if lasmim.dw < data_width and (data_width % lasmim.dw) != 0: raise ValueError( "WISHBONE data width must be a multiple of {dw}".format( dw=lasmim.dw)) # Split address: # TAG | LINE NUMBER | LINE OFFSET offsetbits = log2_int(max(lasmim.dw // data_width, 1)) addressbits = lasmim.aw + offsetbits linebits = log2_int(cachesize) - offsetbits tagbits = addressbits - linebits wordbits = log2_int(max(data_width // lasmim.dw, 1)) adr_offset, adr_line, adr_tag = split(self.wishbone.adr, offsetbits, linebits, tagbits) word = Signal(wordbits) if wordbits else None # Data memory data_mem = Memory(lasmim.dw * 2**wordbits, 2**linebits) data_port = data_mem.get_port(write_capable=True, we_granularity=8) self.specials += data_mem, data_port write_from_lasmi = Signal() write_to_lasmi = Signal() if adr_offset is None: adr_offset_r = None else: adr_offset_r = Signal(offsetbits) self.sync += adr_offset_r.eq(adr_offset) self.comb += [ data_port.adr.eq(adr_line), If(write_from_lasmi, displacer(lasmim.dat_r, word, data_port.dat_w), displacer(Replicate(1, lasmim.dw // 8), word, data_port.we)).Else( data_port.dat_w.eq( Replicate(self.wishbone.dat_w, max(lasmim.dw // data_width, 1))), If( self.wishbone.cyc & self.wishbone.stb & self.wishbone.we & self.wishbone.ack, displacer(self.wishbone.sel, adr_offset, data_port.we, 2**offsetbits, reverse=True))), If(write_to_lasmi, chooser(data_port.dat_r, word, lasmim.dat_w), lasmim.dat_we.eq(2**(lasmim.dw // 8) - 1)), chooser(data_port.dat_r, adr_offset_r, self.wishbone.dat_r, reverse=True) ] # Tag memory tag_layout = [("tag", tagbits), ("dirty", 1)] tag_mem = Memory(layout_len(tag_layout), 2**linebits) tag_port = tag_mem.get_port(write_capable=True) self.specials += tag_mem, tag_port tag_do = Record(tag_layout) tag_di = Record(tag_layout) self.comb += [ tag_do.raw_bits().eq(tag_port.dat_r), tag_port.dat_w.eq(tag_di.raw_bits()) ] self.comb += [tag_port.adr.eq(adr_line), tag_di.tag.eq(adr_tag)] if word is not None: self.comb += lasmim.adr.eq(Cat(word, adr_line, tag_do.tag)) else: self.comb += lasmim.adr.eq(Cat(adr_line, tag_do.tag)) # Lasmim word computation, word_clr and word_inc will be simplified # at synthesis when wordbits=0 word_clr = Signal() word_inc = Signal() if word is not None: self.sync += \ If(word_clr, word.eq(0), ).Elif(word_inc, word.eq(word+1) ) def word_is_last(word): if word is not None: return word == 2**wordbits - 1 else: return 1 # Control FSM assert (lasmim.write_latency >= 1 and lasmim.read_latency >= 1) fsm = FSM(reset_state="IDLE") self.submodules += fsm fsm.delayed_enter("EVICT_DATAD", "EVICT_DATA", lasmim.write_latency - 1) fsm.delayed_enter("REFILL_DATAD", "REFILL_DATA", lasmim.read_latency - 1) fsm.act( "IDLE", If(self.wishbone.cyc & self.wishbone.stb, NextState("TEST_HIT"))) fsm.act( "TEST_HIT", word_clr.eq(1), If(tag_do.tag == adr_tag, self.wishbone.ack.eq(1), If(self.wishbone.we, tag_di.dirty.eq(1), tag_port.we.eq(1)), NextState("IDLE")).Else( If(tag_do.dirty, NextState("EVICT_REQUEST")).Else( NextState("REFILL_WRTAG")))) fsm.act("EVICT_REQUEST", lasmim.stb.eq(1), lasmim.we.eq(1), If(lasmim.req_ack, NextState("EVICT_WAIT_DATA_ACK"))) fsm.act("EVICT_WAIT_DATA_ACK", If(lasmim.dat_ack, NextState("EVICT_DATAD"))) fsm.act( "EVICT_DATA", write_to_lasmi.eq(1), word_inc.eq(1), If( word_is_last(word), NextState("REFILL_WRTAG"), ).Else(NextState("EVICT_REQUEST"))) fsm.act( "REFILL_WRTAG", # Write the tag first to set the LASMI address tag_port.we.eq(1), word_clr.eq(1), NextState("REFILL_REQUEST")) fsm.act("REFILL_REQUEST", lasmim.stb.eq(1), If(lasmim.req_ack, NextState("REFILL_WAIT_DATA_ACK"))) fsm.act("REFILL_WAIT_DATA_ACK", If(lasmim.dat_ack, NextState("REFILL_DATAD"))) fsm.act( "REFILL_DATA", write_from_lasmi.eq(1), word_inc.eq(1), If( word_is_last(word), NextState("TEST_HIT"), ).Else(NextState("REFILL_REQUEST")))
def __init__(self): self.bus = wishbone.Interface() self.ack_en = Signal() self.prng = Random(763627)
def __init__(self, pads, read_wait_cycles=10, hiz_wait_cycles=3, bus=None): if bus is None: bus = wishbone.Interface(data_width=flen(pads.d)) self.bus = bus # # # dts = TSTriple(flen(pads.d)) self.specials += dts.get_tristate(pads.d) hold_address = Signal() dr = Signal(flen(pads.d)) rx = Signal() self.sync += [ If(~hold_address, pads.a.eq(bus.adr)), dts.o.eq(bus.dat_w), dr.eq(dts.i), dts.oe.eq(~rx) ] if hasattr(pads, "sel"): sel_len = flen(pads.sel) else: sel_len = flen(pads.sel_n) gpio = Signal(sel_len + 1) gpio_load = Signal() self.sync += If(gpio_load, gpio.eq(bus.dat_w)) if hasattr(pads, "rst"): self.comb += pads.rst.eq(gpio[0]) else: self.comb += pads.rst_n.eq(~gpio[0]) if hasattr(pads, "sel"): self.comb += pads.sel.eq(gpio[1:]) else: self.comb += pads.sel_n.eq(~gpio[1:]) bus_r_gpio = Signal() self.comb += If(bus_r_gpio, bus.dat_r.eq(gpio) ).Else( bus.dat_r.eq(dr) ) fud = Signal() if hasattr(pads, "fud"): self.sync += pads.fud.eq(fud) else: self.sync += pads.fud_n.eq(~fud) pads.wr_n.reset = 1 pads.rd_n.reset = 1 wr = Signal() rd = Signal() self.sync += pads.wr_n.eq(~wr), pads.rd_n.eq(~rd) self.submodules.read_timer = WaitTimer(read_wait_cycles) self.submodules.hiz_timer = WaitTimer(hiz_wait_cycles) fsm = FSM("IDLE") self.submodules += fsm fsm.act("IDLE", If(bus.cyc & bus.stb, If(bus.adr[flen(pads.a)], If(bus.adr[0], NextState("GPIO") ).Else( NextState("FUD") ) ).Else( If(bus.we, NextState("WRITE") ).Else( NextState("READ") ) ) ) ) fsm.act("WRITE", # 3ns A setup to WR active wr.eq(1), NextState("WRITE0") ) fsm.act("WRITE0", # 3.5ns D setup to WR inactive # 0ns D and A hold to WR inactive bus.ack.eq(1), NextState("IDLE") ) fsm.act("READ", # 15ns D valid to A setup # 15ns D valid to RD active rx.eq(1), rd.eq(1), self.read_timer.wait.eq(1), If(self.read_timer.done, bus.ack.eq(1), NextState("WAIT_HIZ") ) ) fsm.act("WAIT_HIZ", rx.eq(1), # For some reason, AD9858 has an address hold time to RD inactive. hold_address.eq(1), self.hiz_timer.wait.eq(1), If(self.hiz_timer.done, NextState("IDLE")) ) fsm.act("FUD", # 4ns FUD setup to SYNCLK # 0ns FUD hold to SYNCLK fud.eq(1), bus.ack.eq(1), NextState("IDLE") ) fsm.act("GPIO", bus.ack.eq(1), bus_r_gpio.eq(1), If(bus.we, gpio_load.eq(1)), NextState("IDLE") )
def __init__(self, cachesize, lasmim, wbm=None): if wbm is None: wbm = wishbone.Interface() self.wishbone = wbm ### data_width = flen(self.wishbone.dat_r) if lasmim.dw < data_width: raise ValueError("LASMI data width must be >= {dw}".format(dw=data_width)) if (lasmim.dw % data_width) != 0: raise ValueError("LASMI data width must be a multiple of {dw}".format(dw=data_width)) # Split address: # TAG | LINE NUMBER | LINE OFFSET offsetbits = log2_int(lasmim.dw//data_width) addressbits = lasmim.aw + offsetbits linebits = log2_int(cachesize) - offsetbits tagbits = addressbits - linebits adr_offset, adr_line, adr_tag = split(self.wishbone.adr, offsetbits, linebits, tagbits) # Data memory data_mem = Memory(lasmim.dw, 2**linebits) data_port = data_mem.get_port(write_capable=True, we_granularity=8) self.specials += data_mem, data_port write_from_lasmi = Signal() write_to_lasmi = Signal() if adr_offset is None: adr_offset_r = None else: adr_offset_r = Signal(offsetbits) self.sync += adr_offset_r.eq(adr_offset) self.comb += [ data_port.adr.eq(adr_line), If(write_from_lasmi, data_port.dat_w.eq(lasmim.dat_r), data_port.we.eq(Replicate(1, lasmim.dw//8)) ).Else( data_port.dat_w.eq(Replicate(self.wishbone.dat_w, lasmim.dw//data_width)), If(self.wishbone.cyc & self.wishbone.stb & self.wishbone.we & self.wishbone.ack, displacer(self.wishbone.sel, adr_offset, data_port.we, 2**offsetbits, reverse=True) ) ), If(write_to_lasmi, lasmim.dat_w.eq(data_port.dat_r), lasmim.dat_we.eq(2**(lasmim.dw//8)-1) ), chooser(data_port.dat_r, adr_offset_r, self.wishbone.dat_r, reverse=True) ] # Tag memory tag_layout = [("tag", tagbits), ("dirty", 1)] tag_mem = Memory(layout_len(tag_layout), 2**linebits) tag_port = tag_mem.get_port(write_capable=True) self.specials += tag_mem, tag_port tag_do = Record(tag_layout) tag_di = Record(tag_layout) self.comb += [ tag_do.raw_bits().eq(tag_port.dat_r), tag_port.dat_w.eq(tag_di.raw_bits()) ] self.comb += [ tag_port.adr.eq(adr_line), tag_di.tag.eq(adr_tag), lasmim.adr.eq(Cat(adr_line, tag_do.tag)) ] # Control FSM assert(lasmim.write_latency >= 1 and lasmim.read_latency >= 1) fsm = FSM() self.submodules += fsm fsm.delayed_enter("EVICT_DATAD", "EVICT_DATA", lasmim.write_latency-1) fsm.delayed_enter("REFILL_DATAD", "REFILL_DATA", lasmim.read_latency-1) fsm.act("IDLE", If(self.wishbone.cyc & self.wishbone.stb, NextState("TEST_HIT")) ) fsm.act("TEST_HIT", If(tag_do.tag == adr_tag, self.wishbone.ack.eq(1), If(self.wishbone.we, tag_di.dirty.eq(1), tag_port.we.eq(1) ), NextState("IDLE") ).Else( If(tag_do.dirty, NextState("EVICT_REQUEST") ).Else( NextState("REFILL_WRTAG") ) ) ) fsm.act("EVICT_REQUEST", lasmim.stb.eq(1), lasmim.we.eq(1), If(lasmim.req_ack, NextState("EVICT_WAIT_DATA_ACK")) ) fsm.act("EVICT_WAIT_DATA_ACK", If(lasmim.dat_ack, NextState("EVICT_DATAD")) ) fsm.act("EVICT_DATA", write_to_lasmi.eq(1), NextState("REFILL_WRTAG") ) fsm.act("REFILL_WRTAG", # Write the tag first to set the LASMI address tag_port.we.eq(1), NextState("REFILL_REQUEST") ) fsm.act("REFILL_REQUEST", lasmim.stb.eq(1), If(lasmim.req_ack, NextState("REFILL_WAIT_DATA_ACK")) ) fsm.act("REFILL_WAIT_DATA_ACK", If(lasmim.dat_ack, NextState("REFILL_DATAD")) ) fsm.act("REFILL_DATA", write_from_lasmi.eq(1), NextState("TEST_HIT") )