def __init__(self, user_data_width, native_data_width, mem_depth, separate_rw=True, read_latency=0): self.separate_rw = separate_rw if separate_rw: self.write_user_port = LiteDRAMNativeWritePort( address_width=32, data_width=user_data_width) self.write_crossbar_port = LiteDRAMNativeWritePort( address_width=32, data_width=native_data_width) self.read_user_port = LiteDRAMNativeReadPort( address_width=32, data_width=user_data_width) self.read_crossbar_port = LiteDRAMNativeReadPort( address_width=32, data_width=native_data_width) self.write_driver = NativePortDriver(self.write_user_port) self.read_driver = NativePortDriver(self.read_user_port) else: self.write_user_port = LiteDRAMNativePort( mode="both", address_width=32, data_width=user_data_width) self.write_crossbar_port = LiteDRAMNativePort( mode="both", address_width=32, data_width=native_data_width) self.write_driver = NativePortDriver(self.write_user_port) self.read_user_port = self.write_user_port self.read_crossbar_port = self.write_crossbar_port self.read_driver = self.write_driver self.driver_generators = [ self.write_driver.write_data_handler(), self.read_driver.read_data_handler(latency=read_latency) ] # Memory self.memory = DRAMMemory(native_data_width, mem_depth)
def test_wishbone_64bit(self): # Verify Wishbone with 64-bit data width. data = self.pattern_test_data["64bit"] wb = wishbone.Interface(adr_width=30, data_width=64) port = LiteDRAMNativePort("both", address_width=30, data_width=64) self.wishbone_readback_test(data["pattern"], data["expected"], wb, port)
def test_wishbone_32bit_to_8bit(self): # Verify Wishbone with 32-bit data width down-converted to 8-bit data width. data = self.pattern_test_data["32bit_to_8bit"] wb = wishbone.Interface(adr_width=30, data_width=32) port = LiteDRAMNativePort("both", address_width=30, data_width=8) self.wishbone_readback_test(data["pattern"], data["expected"], wb, port)
def __init__(self, wishbone, port, base_address=0x00000000): wishbone_data_width = len(wishbone.dat_w) port_data_width = 2**int(log2(len( port.wdata.data))) # Round to lowest power 2 if wishbone_data_width != port_data_width: if wishbone_data_width > port_data_width: addr_shift = -log2_int(wishbone_data_width // port_data_width) else: addr_shift = log2_int(port_data_width // wishbone_data_width) new_port = LiteDRAMNativePort(mode=port.mode, address_width=port.address_width + addr_shift, data_width=wishbone_data_width) self.submodules += LiteDRAMNativePortConverter(new_port, port) port = new_port # # # adr_offset = base_address >> log2_int(port.data_width // 8) # latch ready signals of cmd/wdata and then wait until all are ready cmd_consumed = Signal() wdata_consumed = Signal() self.sync += [ If( wishbone.ack, cmd_consumed.eq(0), wdata_consumed.eq(0), ).Else( If(port.cmd.valid & port.cmd.ready, cmd_consumed.eq(1)), If(port.wdata.valid & port.wdata.ready, wdata_consumed.eq(1)), ), ] ack_cmd = Signal() ack_wdata = Signal() ack_rdata = Signal() self.comb += [ port.cmd.addr.eq(wishbone.adr - adr_offset), port.cmd.we.eq(wishbone.we), port.wdata.data.eq(wishbone.dat_w), port.wdata.we.eq(wishbone.sel), wishbone.dat_r.eq(port.rdata.data), # always wait for reads, flush write when transaction ends port.flush.eq(~wishbone.cyc), port.cmd.last.eq(~wishbone.we), # make sure cmd/wdata won't stay valid after it is consumed port.cmd.valid.eq(wishbone.cyc & wishbone.stb & ~cmd_consumed), port.wdata.valid.eq((port.cmd.valid | cmd_consumed) & port.cmd.we & ~wdata_consumed), port.rdata.ready.eq((port.cmd.valid | cmd_consumed) & ~port.cmd.we), wishbone.ack.eq(ack_cmd & ( (wishbone.we & ack_wdata) | (~wishbone.we & ack_rdata))), ack_cmd.eq((port.cmd.valid & port.cmd.ready) | cmd_consumed), ack_wdata.eq((port.wdata.valid & port.wdata.ready) | wdata_consumed), ack_rdata.eq(port.rdata.valid & port.rdata.ready), ]
def test_wishbone_data_width_not_smaller(self): with self.assertRaises(AssertionError): wb = wishbone.Interface(data_width=32) port = LiteDRAMNativePort("both", address_width=32, data_width=wb.data_width * 2) LiteDRAMWishbone2Native(wb, port)
def test_wishbone_32bit_to_8bit_base_address(self): # Verify Wishbone with 32-bit data width down-converted to 8-bit data width and non-zero base address. data = self.pattern_test_data["32bit_to_8bit"] wb = wishbone.Interface(adr_width=30, data_width=32) port = LiteDRAMNativePort("both", address_width=30, data_width=8) origin = 0x10000000 pattern = [(adr + origin//(32//8), data) for adr, data in data["pattern"]] self.wishbone_readback_test(pattern, data["expected"], wb, port, base_address=origin)
def __init__(self, wishbone, port, base_address=0x00000000): wishbone_data_width = len(wishbone.dat_w) port_data_width = 2**int(log2(len( port.wdata.data))) # Round to lowest power 2 ratio = wishbone_data_width / port_data_width if wishbone_data_width != port_data_width: if wishbone_data_width > port_data_width: addr_shift = -log2_int(wishbone_data_width // port_data_width) else: addr_shift = log2_int(port_data_width // wishbone_data_width) new_port = LiteDRAMNativePort(mode=port.mode, address_width=port.address_width + addr_shift, data_width=wishbone_data_width) self.submodules += LiteDRAMNativePortConverter(new_port, port) port = new_port # # # aborted = Signal() offset = base_address >> log2_int(port.data_width // 8) self.submodules.fsm = fsm = FSM(reset_state="CMD") self.comb += [ port.cmd.addr.eq(wishbone.adr - offset), port.cmd.we.eq(wishbone.we), port.cmd.last.eq(~wishbone.we), # Always wait for reads. port.flush.eq(~wishbone.cyc) # Flush writes when transaction ends. ] fsm.act( "CMD", port.cmd.valid.eq(wishbone.cyc & wishbone.stb), If(port.cmd.valid & port.cmd.ready & wishbone.we, NextState("WRITE")), If(port.cmd.valid & port.cmd.ready & ~wishbone.we, NextState("READ")), NextValue(aborted, 0), ) self.comb += [ port.wdata.valid.eq(wishbone.stb & wishbone.we), If(ratio <= 1, If(~fsm.ongoing("WRITE"), port.wdata.valid.eq(0))), port.wdata.data.eq(wishbone.dat_w), port.wdata.we.eq(wishbone.sel), ] fsm.act( "WRITE", NextValue(aborted, ~wishbone.cyc | aborted), If(port.wdata.valid & port.wdata.ready, wishbone.ack.eq(wishbone.cyc & ~aborted), NextState("CMD")), ) self.comb += port.rdata.ready.eq(1) fsm.act( "READ", NextValue(aborted, ~wishbone.cyc | aborted), If(port.rdata.valid, wishbone.ack.eq(wishbone.cyc & ~aborted), wishbone.dat_r.eq(port.rdata.data), NextState("CMD")))
def add_memory_buses(self, address_width, data_width): VexRiscvSMP.litedram_width = data_width VexRiscvSMP.generate_cluster_name() from litedram.common import LiteDRAMNativePort if (not VexRiscvSMP.wishbone_memory): ibus = LiteDRAMNativePort(mode="both", address_width=32, data_width=VexRiscvSMP.litedram_width) dbus = LiteDRAMNativePort(mode="both", address_width=32, data_width=VexRiscvSMP.litedram_width) self.memory_buses.append(ibus) self.memory_buses.append(dbus) self.cpu_params.update( # Instruction Memory Bus (Master) o_iBridge_dram_cmd_valid=ibus.cmd.valid, i_iBridge_dram_cmd_ready=ibus.cmd.ready, o_iBridge_dram_cmd_payload_we=ibus.cmd.we, o_iBridge_dram_cmd_payload_addr=ibus.cmd.addr, o_iBridge_dram_wdata_valid=ibus.wdata.valid, i_iBridge_dram_wdata_ready=ibus.wdata.ready, o_iBridge_dram_wdata_payload_data=ibus.wdata.data, o_iBridge_dram_wdata_payload_we=ibus.wdata.we, i_iBridge_dram_rdata_valid=ibus.rdata.valid, o_iBridge_dram_rdata_ready=ibus.rdata.ready, i_iBridge_dram_rdata_payload_data=ibus.rdata.data, # Data Memory Bus (Master) o_dBridge_dram_cmd_valid=dbus.cmd.valid, i_dBridge_dram_cmd_ready=dbus.cmd.ready, o_dBridge_dram_cmd_payload_we=dbus.cmd.we, o_dBridge_dram_cmd_payload_addr=dbus.cmd.addr, o_dBridge_dram_wdata_valid=dbus.wdata.valid, i_dBridge_dram_wdata_ready=dbus.wdata.ready, o_dBridge_dram_wdata_payload_data=dbus.wdata.data, o_dBridge_dram_wdata_payload_we=dbus.wdata.we, i_dBridge_dram_rdata_valid=dbus.rdata.valid, o_dBridge_dram_rdata_ready=dbus.rdata.ready, i_dBridge_dram_rdata_payload_data=dbus.rdata.data, )
def test_wishbone_32bit_to_8bit_base_address(self): data = self.pattern_test_data["32bit_to_8bit"] wb = wishbone.Interface(adr_width=30, data_width=32) port = LiteDRAMNativePort("both", address_width=30, data_width=8) origin = 0x10000000 pattern = [(adr + origin // (32 // 8), data) for adr, data in data["pattern"]] self.wishbone_readback_test(pattern, data["expected"], wb, port, base_address=origin)
def __init__(self): from litedram.common import LiteDRAMNativePort self.dram_port = LiteDRAMNativePort(address_width=32, data_width=32 * 4, mode='both') self.submodules.reader = Reader(self.dram_port) self.w0 = self.reader.memory_w0.get_port(write_capable=True) self.w1 = self.reader.memory_w1.get_port(write_capable=True) self.w2 = self.reader.memory_w2.get_port(write_capable=True) self.w3 = self.reader.memory_w3.get_port(write_capable=True) self.specials += self.w0, self.w1, self.w2, self.w3
def __init__(self): self.dram_port = LiteDRAMNativePort(address_width=32, data_width=32 * 4, mode='both') self.submodules.pattern_mem = PatternMemory( self.dram_port.data_width, 16) self.submodules.writer = Writer(self.dram_port, self.pattern_mem) self.writer.add_csrs() self.data = self.pattern_mem.data.get_port(write_capable=True) self.specials += self.data
def __init__(self): self.submodules.rx_streamer = PacketStreamer(gtp_layout) self.submodules.tx_streamer = PacketStreamer(gtp_layout) self.time = 0 # ---------- RX ------------- RX_RING_BUFFER_BASE_ADDRESS = 0 RX_RING_BUFFER_SIZE = 0x100000 rx_port = LiteDRAMNativePort("write", address_width=32, data_width=256) self.submodules.rx_capture = CapturePipeline( "sys", rx_port, RX_RING_BUFFER_BASE_ADDRESS, RX_RING_BUFFER_SIZE) self.specials.rx_trig_wrport = self.rx_capture.trigger.mem.get_port( write_capable=True, clock_domain="sys") # ---------- TX ------------- TX_RING_BUFFER_BASE_ADDRESS = 0x100000 TX_RING_BUFFER_SIZE = 0x100000 tx_port = LiteDRAMNativePort("write", address_width=32, data_width=256) self.submodules.tx_capture = CapturePipeline( "sys", tx_port, TX_RING_BUFFER_BASE_ADDRESS, TX_RING_BUFFER_SIZE) self.specials.tx_trig_wrport = self.tx_capture.trigger.mem.get_port( write_capable=True, clock_domain="sys") self.comb += [ self.tx_capture.forced.eq(self.rx_capture.record), self.rx_capture.forced.eq(self.tx_capture.record), self.tx_capture.trigExt.eq(self.rx_capture.trigOut), self.rx_capture.trigExt.eq(self.tx_capture.trigOut), self.rx_streamer.source.connect(self.rx_capture.sink), self.tx_streamer.source.connect(self.tx_capture.sink), ]
def __init__(self, address_width=32, data_width=128, pattern_mem_length=32): self.dram_port = LiteDRAMNativePort(address_width=address_width, data_width=data_width, mode='both') self.submodules.pattern_mem = PatternMemory(self.dram_port.data_width, pattern_mem_length) self.submodules.reader = Reader(self.dram_port, self.pattern_mem) self.reader.add_csrs() self.data = self.pattern_mem.data.get_port(write_capable=True) self.addr = self.pattern_mem.addr.get_port(write_capable=True) self.specials += self.data, self.addr
def __init__(self, address_width=32, data_width=128, pattern_mem_length=32, pattern_init=None, rowbits=5, row_shift=10): self.address_width = address_width self.data_width = data_width self.pattern_mem_length = pattern_mem_length self.submodules.pattern_mem = PatternMemory(data_width, pattern_mem_length, addr_width=address_width, pattern_init=pattern_init) self.data = self.pattern_mem.data.get_port(write_capable=True) self.addr = self.pattern_mem.addr.get_port(write_capable=True) self.specials += self.data, self.addr inverter_kwargs = dict(rowbits=rowbits, row_shift=row_shift) self.read_port = LiteDRAMNativePort(address_width=address_width, data_width=data_width, mode='read') self.submodules.reader = Reader(self.read_port, self.pattern_mem, **inverter_kwargs) self.reader.add_csrs() self.write_port = LiteDRAMNativePort(address_width=address_width, data_width=data_width, mode='write') self.submodules.writer = Writer(self.write_port, self.pattern_mem, **inverter_kwargs) self.writer.add_csrs() # storage for port_handler (addr, we, data) self.commands = []
def test_wishbone_32bit_to_8bit(self): data = self.pattern_test_data["32bit_to_8bit"] wb = wishbone.Interface(adr_width=30, data_width=32) port = LiteDRAMNativePort("both", address_width=30, data_width=8) self.wishbone_readback_test(data["pattern"], data["expected"], wb, port)
def __init__(self, platform, variant): self.platform = platform self.variant = "variant" 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.cbus = cbus = wishbone.Interface() self.plicbus = plicbus = wishbone.Interface() self.periph_buses = [pbus] self.memory_buses = [] # Added dynamically VexRiscvSMP.generate_cluster_name() print(f"VexRiscv cluster : {self.cluster_name}") if not path.exists(f"verilog/{self.cluster_name}.v"): self.generate_netlist() os.system("cp images/{}.dtb images/dtb".format(variant)) # FIXME: generate dts/dtb dynamically # # # 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, # CLINT Bus (Slave) i_clintWishbone_CYC = cbus.cyc, i_clintWishbone_STB = cbus.stb, o_clintWishbone_ACK = cbus.ack, i_clintWishbone_WE = cbus.we, i_clintWishbone_ADR = cbus.adr, o_clintWishbone_DAT_MISO = cbus.dat_r, i_clintWishbone_DAT_MOSI = cbus.dat_w, # PLIC Bus (Slave) i_plicWishbone_CYC = plicbus.cyc, i_plicWishbone_STB = plicbus.stb, o_plicWishbone_ACK = plicbus.ack, i_plicWishbone_WE = plicbus.we, i_plicWishbone_ADR = plicbus.adr, o_plicWishbone_DAT_MISO = plicbus.dat_r, i_plicWishbone_DAT_MOSI = plicbus.dat_w ) if self.coherent_dma: self.dma_bus = dma_bus = wishbone.Interface(data_width=64) dma_bus_stall = Signal() dma_bus_inhibit = Signal() self.cpu_params.update( 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) ) ] if "mp" in variant: ncpus = int(variant[-2]) # FIXME for n in range(ncpus): ibus = LiteDRAMNativePort(mode="both", address_width=32, data_width=128) dbus = LiteDRAMNativePort(mode="both", address_width=32, data_width=128) self.memory_buses.append(ibus) self.memory_buses.append(dbus) self.cpu_params.update({ # Instruction Memory Bus (Master) f"o_io_iMem_{n}_cmd_valid" : ibus.cmd.valid, f"i_io_iMem_{n}_cmd_ready" : ibus.cmd.ready, f"o_io_iMem_{n}_cmd_payload_we" : ibus.cmd.we, f"o_io_iMem_{n}_cmd_payload_addr" : ibus.cmd.addr, f"o_io_iMem_{n}_wdata_valid" : ibus.wdata.valid, f"i_io_iMem_{n}_wdata_ready" : ibus.wdata.ready, f"o_io_iMem_{n}_wdata_payload_data" : ibus.wdata.data, f"o_io_iMem_{n}_wdata_payload_we" : ibus.wdata.we, f"i_io_iMem_{n}_rdata_valid" : ibus.rdata.valid, f"o_io_iMem_{n}_rdata_ready" : ibus.rdata.ready, f"i_io_iMem_{n}_rdata_payload_data" : ibus.rdata.data, # Data Memory Bus (Master) f"o_io_dMem_{n}_cmd_valid" : dbus.cmd.valid, f"i_io_dMem_{n}_cmd_ready" : dbus.cmd.ready, f"o_io_dMem_{n}_cmd_payload_we" : dbus.cmd.we, f"o_io_dMem_{n}_cmd_payload_addr" : dbus.cmd.addr, f"o_io_dMem_{n}_wdata_valid" : dbus.wdata.valid, f"i_io_dMem_{n}_wdata_ready" : dbus.wdata.ready, f"o_io_dMem_{n}_wdata_payload_data" : dbus.wdata.data, f"o_io_dMem_{n}_wdata_payload_we" : dbus.wdata.we, f"i_io_dMem_{n}_rdata_valid" : dbus.rdata.valid, f"o_io_dMem_{n}_rdata_ready" : dbus.rdata.ready, f"i_io_dMem_{n}_rdata_payload_data" : dbus.rdata.data, }) else: ibus = LiteDRAMNativePort(mode="both", address_width=32, data_width=128) dbus = LiteDRAMNativePort(mode="both", address_width=32, data_width=128) self.memory_buses.append(ibus) self.memory_buses.append(dbus) self.cpu_params.update( # Instruction Memory Bus (Master) o_iBridge_dram_cmd_valid = ibus.cmd.valid, i_iBridge_dram_cmd_ready = ibus.cmd.ready, o_iBridge_dram_cmd_payload_we = ibus.cmd.we, o_iBridge_dram_cmd_payload_addr = ibus.cmd.addr, o_iBridge_dram_wdata_valid = ibus.wdata.valid, i_iBridge_dram_wdata_ready = ibus.wdata.ready, o_iBridge_dram_wdata_payload_data = ibus.wdata.data, o_iBridge_dram_wdata_payload_we = ibus.wdata.we, i_iBridge_dram_rdata_valid = ibus.rdata.valid, o_iBridge_dram_rdata_ready = ibus.rdata.ready, i_iBridge_dram_rdata_payload_data = ibus.rdata.data, # Data Memory Bus (Master) o_dBridge_dram_cmd_valid = dbus.cmd.valid, i_dBridge_dram_cmd_ready = dbus.cmd.ready, o_dBridge_dram_cmd_payload_we = dbus.cmd.we, o_dBridge_dram_cmd_payload_addr = dbus.cmd.addr, o_dBridge_dram_wdata_valid = dbus.wdata.valid, i_dBridge_dram_wdata_ready = dbus.wdata.ready, o_dBridge_dram_wdata_payload_data = dbus.wdata.data, o_dBridge_dram_wdata_payload_we = dbus.wdata.we, i_dBridge_dram_rdata_valid = dbus.rdata.valid, o_dBridge_dram_rdata_ready = dbus.rdata.ready, i_dBridge_dram_rdata_payload_data = dbus.rdata.data, ) # Add verilog sources self.add_sources(platform, variant)
def test_axi2native(self): class Access: def __init__(self, addr, data, id): self.addr = addr self.data = data self.id = id class Write(Access): pass class Read(Access): pass def writes_cmd_data_generator(axi_port, writes): for write in writes: # send command yield axi_port.aw.valid.eq(1) yield axi_port.aw.addr.eq(write.addr << 2) yield axi_port.aw.id.eq(write.id) yield while (yield axi_port.aw.ready) == 0: yield yield axi_port.aw.valid.eq(0) yield # send data yield axi_port.w.valid.eq(1) yield axi_port.w.last.eq(1) yield axi_port.w.data.eq(write.data) yield while (yield axi_port.w.ready) == 0: yield yield axi_port.w.valid.eq(0) def writes_response_generator(axi_port, writes): self.writes_id_errors = 0 yield axi_port.b.ready.eq(1) # always accepting write response for write in writes: # wait response while (yield axi_port.b.valid) == 0: yield if (yield axi_port.b.id) != write.id: self.writes_id_errors += 1 yield def reads_cmd_generator(axi_port, reads): for read in reads: # send command yield axi_port.ar.valid.eq(1) yield axi_port.ar.addr.eq(read.addr << 2) yield axi_port.ar.id.eq(read.id) yield while (yield axi_port.ar.ready) == 0: yield yield axi_port.ar.valid.eq(0) yield def reads_response_data_generator(axi_port, reads): self.reads_data_errors = 0 self.reads_id_errors = 0 self.reads_last_errors = 0 yield axi_port.r.ready.eq(1) # always accepting read response for read in reads: # wait data / response while (yield axi_port.r.valid) == 0: yield if (yield axi_port.r.data) != read.data: self.reads_data_errors += 1 if (yield axi_port.r.id) != read.id: self.reads_id_errors += 1 if (yield axi_port.r.last) != 1: self.reads_last_errors += 1 yield # dut axi_port = LiteDRAMAXIPort(32, 32, 8) dram_port = LiteDRAMNativePort("both", 32, 32) dut = LiteDRAMAXI2Native(axi_port, dram_port) mem = DRAMMemory(32, 128) # generate writes/reads prng = random.Random(42) writes = [] for i in range(64): # incrementing addr, random data &id writes.append(Write(i, prng.randrange(2**32), prng.randrange(2**8))) # incrementing addr, data & id (debug) #writes.append(Write(i, i, i)) reads = [] for i in range(64): # dummy reads while content not yet written reads.append(Read(64, 0x00000000, 0x00)) for i in range(64): # incrementing addr, written data, random id reads.append(Read(i, writes[i].data, prng.randrange(2**8))) # incrementing addr, written data, incrementing id (debug) #reads.append(Read(i, writes[i].data, i)) # simulation generators = [ writes_cmd_data_generator(axi_port, writes), writes_response_generator(axi_port, writes), reads_cmd_generator(axi_port, reads), reads_response_data_generator(axi_port, reads), mem.read_handler(dram_port), mem.write_handler(dram_port) ] run_simulation(dut, generators, vcd_name="axi2native.vcd") #mem.show_content() self.assertEqual(self.writes_id_errors, 0) self.assertEqual(self.reads_data_errors, 0) self.assertEqual(self.reads_id_errors, 0) self.assertEqual(self.reads_last_errors, 0)
def __init__(self, platform, variant): variant = "2c" if variant == "standard" else variant assert variant in CPU_VARIANTS, "Unsupported variant %s" % variant self.platform = platform self.variant = variant self.human_name = self.human_name + "-" + variant.upper() self.cluster_name = "VexRiscvLitexSmp{mp}Cluster_{n}c".format( mp="Mp" if "mp" in variant else "", n=variant[-2]) # FIXME 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.cbus = cbus = wishbone.Interface() self.plicbus = plicbus = wishbone.Interface() self.periph_buses = [pbus] self.memory_buses = [] # Added dynamically os.system("cp images/{}.dtb images/dtb".format( variant)) # FIXME: generate dts/dtb dynamically # # # self.cpu_params = dict( # Clk / Rst i_clk=ClockSignal(), i_reset=ResetSignal() | self.reset, i_debugResetIn=ResetSignal() | self.reset, o_io_debugReset=Open(), # Interrupts i_io_interrupts=self.interrupt, # JTAG i_jtag_clk=self.jtag_clk, i_io_jtagInstruction_enable=self.jtag_enable, i_io_jtagInstruction_capture=self.jtag_capture, i_io_jtagInstruction_shift=self.jtag_shift, i_io_jtagInstruction_update=self.jtag_update, i_io_jtagInstruction_reset=self.jtag_reset, i_io_jtagInstruction_tdi=self.jtag_tdi, o_io_jtagInstruction_tdo=self.jtag_tdo, # Peripheral Bus (Master) o_io_peripheral_CYC=pbus.cyc, o_io_peripheral_STB=pbus.stb, i_io_peripheral_ACK=pbus.ack, o_io_peripheral_WE=pbus.we, o_io_peripheral_ADR=pbus.adr, i_io_peripheral_DAT_MISO=pbus.dat_r, o_io_peripheral_DAT_MOSI=pbus.dat_w, o_io_peripheral_SEL=pbus.sel, i_io_peripheral_ERR=pbus.err, o_io_peripheral_CTI=pbus.cti, o_io_peripheral_BTE=pbus.bte, # CLINT Bus (Slave) i_io_clint_CYC=cbus.cyc, i_io_clint_STB=cbus.stb, o_io_clint_ACK=cbus.ack, i_io_clint_WE=cbus.we, i_io_clint_ADR=cbus.adr, o_io_clint_DAT_MISO=cbus.dat_r, i_io_clint_DAT_MOSI=cbus.dat_w, # PLIC Bus (Slave) i_io_plic_CYC=plicbus.cyc, i_io_plic_STB=plicbus.stb, o_io_plic_ACK=plicbus.ack, i_io_plic_WE=plicbus.we, i_io_plic_ADR=plicbus.adr, o_io_plic_DAT_MISO=plicbus.dat_r, i_io_plic_DAT_MOSI=plicbus.dat_w, ) if "mp" in variant: ncpus = int(variant[-2]) # FIXME for n in range(ncpus): ibus = LiteDRAMNativePort(mode="both", address_width=32, data_width=128) dbus = LiteDRAMNativePort(mode="both", address_width=32, data_width=128) self.memory_buses.append(ibus) self.memory_buses.append(dbus) self.cpu_params.update({ # Instruction Memory Bus (Master) "o_io_iMem_{}_cmd_valid".format(n): ibus.cmd.valid, "i_io_iMem_{}_cmd_ready".format(n): ibus.cmd.ready, "o_io_iMem_{}_cmd_payload_we".format(n): ibus.cmd.we, "o_io_iMem_{}_cmd_payload_addr".format(n): ibus.cmd.addr, "o_io_iMem_{}_wdata_valid".format(n): ibus.wdata.valid, "i_io_iMem_{}_wdata_ready".format(n): ibus.wdata.ready, "o_io_iMem_{}_wdata_payload_data".format(n): ibus.wdata.data, "o_io_iMem_{}_wdata_payload_we".format(n): ibus.wdata.we, "i_io_iMem_{}_rdata_valid".format(n): ibus.rdata.valid, "o_io_iMem_{}_rdata_ready".format(n): ibus.rdata.ready, "i_io_iMem_{}_rdata_payload_data".format(n): ibus.rdata.data, # Data Memory Bus (Master) "o_io_dMem_{}_cmd_valid".format(n): dbus.cmd.valid, "i_io_dMem_{}_cmd_ready".format(n): dbus.cmd.ready, "o_io_dMem_{}_cmd_payload_we".format(n): dbus.cmd.we, "o_io_dMem_{}_cmd_payload_addr".format(n): dbus.cmd.addr, "o_io_dMem_{}_wdata_valid".format(n): dbus.wdata.valid, "i_io_dMem_{}_wdata_ready".format(n): dbus.wdata.ready, "o_io_dMem_{}_wdata_payload_data".format(n): dbus.wdata.data, "o_io_dMem_{}_wdata_payload_we".format(n): dbus.wdata.we, "i_io_dMem_{}_rdata_valid".format(n): dbus.rdata.valid, "o_io_dMem_{}_rdata_ready".format(n): dbus.rdata.ready, "i_io_dMem_{}_rdata_payload_data".format(n): dbus.rdata.data, }) else: ibus = LiteDRAMNativePort(mode="both", address_width=32, data_width=128) dbus = LiteDRAMNativePort(mode="both", address_width=32, data_width=128) self.memory_buses.append(ibus) self.memory_buses.append(dbus) self.cpu_params.update( # Instruction Memory Bus (Master) o_io_iMem_cmd_valid=ibus.cmd.valid, i_io_iMem_cmd_ready=ibus.cmd.ready, o_io_iMem_cmd_payload_we=ibus.cmd.we, o_io_iMem_cmd_payload_addr=ibus.cmd.addr, o_io_iMem_wdata_valid=ibus.wdata.valid, i_io_iMem_wdata_ready=ibus.wdata.ready, o_io_iMem_wdata_payload_data=ibus.wdata.data, o_io_iMem_wdata_payload_we=ibus.wdata.we, i_io_iMem_rdata_valid=ibus.rdata.valid, o_io_iMem_rdata_ready=ibus.rdata.ready, i_io_iMem_rdata_payload_data=ibus.rdata.data, # Data Memory Bus (Master) o_io_dMem_cmd_valid=dbus.cmd.valid, i_io_dMem_cmd_ready=dbus.cmd.ready, o_io_dMem_cmd_payload_we=dbus.cmd.we, o_io_dMem_cmd_payload_addr=dbus.cmd.addr, o_io_dMem_wdata_valid=dbus.wdata.valid, i_io_dMem_wdata_ready=dbus.wdata.ready, o_io_dMem_wdata_payload_data=dbus.wdata.data, o_io_dMem_wdata_payload_we=dbus.wdata.we, i_io_dMem_rdata_valid=dbus.rdata.valid, o_io_dMem_rdata_ready=dbus.rdata.ready, i_io_dMem_rdata_payload_data=dbus.rdata.data, ) # Add verilog sources self.add_sources(platform, variant)
def __init__(self, platform): self.clock_domains.cd_sys = ClockDomain() # sdram parameters sdram_aw = 24 sdram_dw = 128 # sdram bist sdram_generator_port = LiteDRAMNativePort("both", sdram_aw, sdram_dw, id=0) self.submodules.sdram_generator = _LiteDRAMBISTGenerator(sdram_generator_port) sdram_checker_port = LiteDRAMNativePort("both", sdram_aw, sdram_dw, id=1) self.submodules.sdram_checker = _LiteDRAMBISTChecker(sdram_checker_port) # micron model ddram_a = Signal(14) ddram_ba = Signal(3) ddram_ras_n = Signal() ddram_cas_n = Signal() ddram_we_n = Signal() ddram_cs_n = Signal() ddram_dm = Signal(2) ddram_dq = Signal(16) ddram_dqs_p = Signal(2) ddram_dqs_n = Signal(2) ddram_clk_p = Signal() ddram_clk_n = Signal() ddram_cke = Signal() ddram_odt = Signal() ddram_reset_n = Signal() self.specials += Instance("ddr3", i_rst_n=ddram_reset_n, i_ck=ddram_clk_p, i_ck_n=ddram_clk_n, i_cke=ddram_cke, i_cs_n=ddram_cs_n, i_ras_n=ddram_ras_n, i_cas_n=ddram_cas_n, i_we_n=ddram_we_n, io_dm_tdqs=ddram_dm, i_ba=ddram_ba, i_addr=ddram_a, io_dq=ddram_dq, io_dqs=ddram_dqs_p, io_dqs_n=ddram_dqs_n, #o_tdqs_n=, i_odt=ddram_odt ) # LiteDRAM standalone core instance init_done = Signal() init_error = Signal() self.specials += Instance("litedram_core", # clk / reset input i_clk=platform.request("clk"), i_rst=platform.request("rst"), # dram pins o_ddram_a=ddram_a, o_ddram_ba=ddram_ba, o_ddram_ras_n=ddram_ras_n, o_ddram_cas_n=ddram_cas_n, o_ddram_we_n=ddram_we_n, o_ddram_cs_n=ddram_cs_n, o_ddram_dm=ddram_dm, io_ddram_dq=ddram_dq, o_ddram_dqs_p=ddram_dqs_p, o_ddram_dqs_n=ddram_dqs_n, o_ddram_clk_p=ddram_clk_p, o_ddram_clk_n=ddram_clk_n, o_ddram_cke=ddram_cke, o_ddram_odt=ddram_odt, o_ddram_reset_n=ddram_reset_n, # dram init o_init_done=init_done, o_init_error=init_error, # user clk / reset o_user_clk=self.cd_sys.clk, o_user_rst=self.cd_sys.rst, # user port 0 # cmd i_user_port0_cmd_valid=sdram_generator_port.cmd.valid, o_user_port0_cmd_ready=sdram_generator_port.cmd.ready, i_user_port0_cmd_we=sdram_generator_port.cmd.we, i_user_port0_cmd_addr=sdram_generator_port.cmd.addr, # wdata i_user_port0_wdata_valid=sdram_generator_port.wdata.valid, o_user_port0_wdata_ready=sdram_generator_port.wdata.ready, i_user_port0_wdata_we=sdram_generator_port.wdata.we, i_user_port0_wdata_data=sdram_generator_port.wdata.data, # rdata o_user_port0_rdata_valid=sdram_generator_port.rdata.valid, i_user_port0_rdata_ready=sdram_generator_port.rdata.ready, o_user_port0_rdata_data=sdram_generator_port.rdata.data, # user port 1 # cmd i_user_port1_cmd_valid=sdram_checker_port.cmd.valid, o_user_port1_cmd_ready=sdram_checker_port.cmd.ready, i_user_port1_cmd_we=sdram_checker_port.cmd.we, i_user_port1_cmd_addr=sdram_checker_port.cmd.addr, # wdata i_user_port1_wdata_valid=sdram_checker_port.wdata.valid, o_user_port1_wdata_ready=sdram_checker_port.wdata.ready, i_user_port1_wdata_we=sdram_checker_port.wdata.we, i_user_port1_wdata_data=sdram_checker_port.wdata.data, # rdata o_user_port1_rdata_valid=sdram_checker_port.rdata.valid, i_user_port1_rdata_ready=sdram_checker_port.rdata.ready, o_user_port1_rdata_data=sdram_checker_port.rdata.data ) # test self.comb += [ self.sdram_generator.base.eq(0x00000000), self.sdram_generator.length.eq(0x00000100), self.sdram_checker.base.eq(0x00000000), self.sdram_checker.length.eq(0x00000100), ] self.submodules.fsm = fsm = FSM(reset_state="IDLE") fsm.act("IDLE", If(init_done, NextState("GENERATOR_START") ) ) fsm.act("GENERATOR_START", self.sdram_generator.start.eq(1), NextState("GENERATOR_WAIT") ) fsm.act("GENERATOR_WAIT", If(self.sdram_generator.done, NextState("CHECKER_START") ) ) fsm.act("CHECKER_START", self.sdram_checker.start.eq(1), NextState("CHECKER_WAIT") ) fsm.act("CHECKER_WAIT", If(self.sdram_checker.done, NextState("DONE") ) ) fsm.act("DONE")