def fifo_short(clock, reset, clear, datain, src_rdy_i, dst_rdy_o, dataout, src_rdy_o, dst_rdy_i): wr = Signal(bool(0)) rd = Signal(bool(0)) args = Namespace(width=36, size=16, name='fifo_2clock_cascade') fbus = FIFOBus(size=args.size, width=args.width) # need to update the fbus refernces to reference the Signals in # the module port list (function arguments). fbus.write = wr fbus.write_data = datain fbus.read = rd fbus.read_data = dataout @always_comb def rtl_assign1(): wr.next = src_rdy_i & dst_rdy_o rd.next = dst_rdy_i & src_rdy_o @always_comb def rtl_assign2(): dst_rdy_o.next = not fbus.full src_rdy_o.next = not fbus.empty gfifo = fifo_fast(reset, clock, fbus) return rtl_assign1, rtl_assign2, gfifo
def m_fifo_short(clock, reset, clear, datain, src_rdy_i, dst_rdy_o, dataout, src_rdy_o, dst_rdy_i): wr = Signal(bool(0)) rd = Signal(bool(0)) args = Namespace(width=36, size=16, name='fifo_2clock_cascade') fbus = FIFOBus(args=args) # need to update the fbus refernces to reference the Signals in # the module port list (function arguments). fbus.wr = wr fbus.wdata = datain fbus.rd = rd fbus.rdata = dataout @always_comb def rtl_assign1(): wr.next = src_rdy_i & dst_rdy_o rd.next = dst_rdy_i & src_rdy_o @always_comb def rtl_assign2(): dst_rdy_o.next = not fbus.full src_rdy_o.next = not fbus.empty gfifo = fifo_fast(clock, reset, fbus) return rtl_assign1, rtl_assign2, gfifo
def fifo_short(clock, reset, clear, datain, src_rdy_i, dst_rdy_o, dataout, src_rdy_o, dst_rdy_i): glbl = Global(clock, reset) wr = Signal(bool(0)) rd = Signal(bool(0)) args = Namespace(width=36, size=16, name='fifo_2clock_cascade') fbus = FIFOBus(width=args.width) # need to update the fbus refernces to reference the Signals in # the module port list (function arguments). fbus.write = wr fbus.write_data = datain fbus.read = rd fbus.read_data = dataout @always_comb def beh_assign1(): wr.next = src_rdy_i & dst_rdy_o rd.next = dst_rdy_i & src_rdy_o @always_comb def beh_assign2(): dst_rdy_o.next = not fbus.full src_rdy_o.next = not fbus.empty fifo_inst = fifo_fast(glbl, fbus, size=args.size) return myhdl.instances()
def _bench_command_bridge(): tbclk = clock.gen() tbdut = memmap_command_bridge(glbl, fbtx, fbrx, memmap) tbfii = fifo_fast(clock, reset, fbtx) tbfio = fifo_fast(clock, reset, fbrx) # @todo: add other bus types tbmem = memmap_peripheral_bb(clock, reset, memmap) # save the data read ... read_value = [] @instance def tbstim(): yield reset.pulse(32) try: # test a single address pkt = CommandPacket(True, 0x0000) yield pkt.put(fbtx) yield pkt.get(fbrx, read_value, [0]) pkt = CommandPacket(False, 0x0000, [0x5555AAAA]) yield pkt.put(fbtx) yield pkt.get(fbrx, read_value, [0x5555AAAA]) # test a bunch of random addresses for ii in range(nloops): randaddr = randint(0, (2**20)-1) randdata = randint(0, (2**32)-1) pkt = CommandPacket(False, randaddr, [randdata]) yield pkt.put(fbtx) yield pkt.get(fbrx, read_value, [randdata]) except Exception as err: print("Error: {}".format(str(err))) traceback.print_exc() yield delay(2000) raise StopSimulation return tbclk, tbdut, tbfii, tbfio, tbmem, tbstim
def _bench_command_bridge(): tbclk = clock.gen() tbdut = memmap_command_bridge(glbl, fbtx, fbrx, memmap) tbfii = fifo_fast(clock, reset, fbtx) tbfio = fifo_fast(clock, reset, fbrx) # @todo: add other bus types tbmem = memmap_peripheral_bb(clock, reset, memmap) # save the data read ... read_value = [] @instance def tbstim(): yield reset.pulse(32) try: # test a single address pkt = CommandPacket(True, 0x0000) yield pkt.put(fbtx) yield pkt.get(fbrx, read_value, [0]) pkt = CommandPacket(False, 0x0000, [0x5555AAAA]) yield pkt.put(fbtx) yield pkt.get(fbrx, read_value, [0x5555AAAA]) # test a bunch of random addresses for ii in range(nloops): randaddr = randint(0, (2**20) - 1) randdata = randint(0, (2**32) - 1) pkt = CommandPacket(False, randaddr, [randdata]) yield pkt.put(fbtx) yield pkt.get(fbrx, read_value, [randdata]) except Exception as err: print("Error: {}".format(str(err))) traceback.print_exc() yield delay(2000) raise StopSimulation return tbclk, tbdut, tbfii, tbfio, tbmem, tbstim
def spi_slave_fifo(glbl, spibus, fifobus): """ This is an SPI slave peripheral, when the master starts clocking any data in the TX FIFO (fifobus.write) will be sent (the next byte) and the received byte will be copied to RX FIFO (fifobus.read). The `cso` interface can be used to configure how the SPI slave peripheral behaves. (Arguments == Ports) Arguments: glbl (Global): global clock and reset spibus (SPIBus): the external SPI interface fifobus (FIFOBus): the fifo interface cso (ControlStatus): the control status signals """ fifosize = 8 # Use an async FIFO to transfer from the SPI SCK clock domain and # the internal clock domain. This allows for high-speed SCK. clock, reset = glbl.clock, glbl.reset assert isinstance(spibus, SPIBus) assert isinstance(fifobus, FIFOBus) sck, csn = spibus.sck, spibus.csn # the FIFOs for the receive and transmit (external perspective) readpath = FIFOBus(width=fifobus.width) writepath = FIFOBus(width=fifobus.width) # the FIFO instances tx_fifo_inst = fifo_fast(glbl, writepath, size=fifosize) rx_fifo_inst = fifo_fast(glbl, readpath, size=fifosize) mp_fifo_inst = fifobus.assign_read_write_paths(readpath, writepath) spi_start = Signal(bool(0)) ireg, icap, icaps = Signals(intbv(0)[8:], 3) oreg, ocap = Signals(intbv(0)[8:], 2) bitcnt, b2, b3 = Signals(intbv(0, min=0, max=10), 3) @always(sck.posedge, csn.negedge) def csn_falls(): if sck: spi_start.next = False elif not csn: spi_start.next = True # SCK clock domain, this allows high SCK rates @always(sck.posedge, csn.posedge) def sck_capture_send(): if csn: b2.next = 0 bitcnt.next = 0 else: if bitcnt == 0 or spi_start: spibus.miso.next = ocap[7] oreg.next = (ocap << 1) & 0xFF else: spibus.miso.next = oreg[7] oreg.next = (oreg << 1) & 0xFF ireg.next = concat(ireg[7:0], spibus.mosi) bitcnt.next = bitcnt + 1 if bitcnt == (8 - 1): bitcnt.next = 0 b2.next = 8 icap.next = concat(ireg[7:0], spibus.mosi) else: b2.next = 0 # synchronize the SCK domain to the clock domain syncro(clock, icap, icaps) syncro(clock, b2, b3) gotit = Signal(bool(0)) @always(clock.posedge) def beh_io_capture(): # default no writes readpath.write.next = False writepath.read.next = False if b3 == 0: gotit.next = False elif b3 == 8 and not gotit: readpath.write.next = True readpath.write_data.next = icaps gotit.next = True ocap.next = writepath.read_data if not writepath.empty: writepath.read.next = True return myhdl.instances()
def bench_command_bridge(): tbclk = clock.gen() tbdut = command_bridge(glbl, fifobus, memmap) readpath, writepath = FIFOBus(), FIFOBus() readpath.clock = writepath.clock = clock tbmap = fifobus.assign_read_write_paths(readpath, writepath) tbftx = fifo_fast(reset, clock, writepath) # user write path tbfrx = fifo_fast(reset, clock, readpath) # user read path # @todo: add other bus types tbmem = memmap_peripheral_bb(clock, reset, memmap) # save the data read ... read_value = [] @instance def tbstim(): yield reset.pulse(32) fifobus.read.next = False fifobus.write.next = False assert not fifobus.full assert fifobus.empty assert fifobus.read_data == 0 fifobus.write_data.next = 0 try: # test a single address pkt = CommandPacket(True, 0x0000) yield pkt.put(readpath) yield pkt.get(writepath, read_value, [0]) pkt = CommandPacket(False, 0x0000, [0x5555AAAA]) yield pkt.put(readpath) yield pkt.get(writepath, read_value, [0x5555AAAA]) # test a bunch of random addresses for ii in range(nloops): randaddr = randint(0, (2**20)-1) randdata = randint(0, (2**32)-1) pkt = CommandPacket(False, randaddr, [randdata]) yield pkt.put(readpath) yield pkt.get(writepath, read_value, [randdata]) except Exception as err: print("Error: {}".format(str(err))) traceback.print_exc() yield delay(2000) raise StopSimulation wp_read, wp_valid = Signals(bool(0), 2) wp_read_data = Signal(intbv(0)[8:]) wp_empty, wp_full = Signals(bool(0), 2) @always_comb def tbmon(): wp_read.next = writepath.read wp_read_data.next = writepath.read_data wp_valid.next = writepath.read_valid wp_full.next = writepath.full wp_empty.next = writepath.empty return tbclk, tbdut, tbmap, tbftx, tbfrx, tbmem, tbstim, tbmon
def spi_slave_fifo(glbl, spibus, fifobus): """ This is an SPI slave peripheral, when the master starts clocking any data in the TX FIFO (fifobus.write) will be sent (the next byte) and the received byte will be copied to RX FIFO (fifobus.read). The `cso` interface can be used to configure how the SPI slave peripheral behaves. (Arguments == Ports) Arguments: glbl (Global): global clock and reset spibus (SPIBus): the external SPI interface fifobus (FIFOBus): the fifo interface cso (ControlStatus): the control status signals """ fifosize = 8 # Use an async FIFO to transfer from the SPI SCK clock domain and # the internal clock domain. This allows for high-speed SCK. clock, reset = glbl.clock, glbl.reset assert isinstance(spibus, SPIBus) assert isinstance(fifobus, FIFOBus) sck, csn = spibus.sck, spibus.csn # the FIFOs for the receive and transmit (external perspective) readpath = FIFOBus(width=fifobus.width) writepath = FIFOBus(width=fifobus.width) # the FIFO instances tx_fifo_inst = fifo_fast(glbl, writepath, size=fifosize) rx_fifo_inst = fifo_fast(glbl, readpath, size=fifosize) mp_fifo_inst = fifobus.assign_read_write_paths(readpath, writepath) spi_start = Signal(bool(0)) ireg, icap, icaps = Signals(intbv(0)[8:], 3) oreg, ocap = Signals(intbv(0)[8:], 2) bitcnt, b2, b3 = Signals(intbv(0, min=0, max=10), 3) @always(sck.posedge, csn.negedge) def csn_falls(): if sck: spi_start.next = False elif not csn: spi_start.next = True # SCK clock domain, this allows high SCK rates @always(sck.posedge, csn.posedge) def sck_capture_send(): if csn: b2.next = 0 bitcnt.next = 0 else: if bitcnt == 0 or spi_start: spibus.miso.next = ocap[7] oreg.next = (ocap << 1) & 0xFF else: spibus.miso.next = oreg[7] oreg.next = (oreg << 1) & 0xFF ireg.next = concat(ireg[7:0], spibus.mosi) bitcnt.next = bitcnt + 1 if bitcnt == (8-1): bitcnt.next = 0 b2.next = 8 icap.next = concat(ireg[7:0], spibus.mosi) else: b2.next = 0 # synchronize the SCK domain to the clock domain syncro(clock, icap, icaps) syncro(clock, b2, b3) gotit = Signal(bool(0)) @always(clock.posedge) def beh_io_capture(): # default no writes readpath.write.next = False writepath.read.next = False if b3 == 0: gotit.next = False elif b3 == 8 and not gotit: readpath.write.next = True readpath.write_data.next = icaps gotit.next = True ocap.next = writepath.read_data if not writepath.empty: writepath.read.next = True return myhdl.instances()
def bench_command_bridge(): tbclk = clock.gen() tbdut = command_bridge(glbl, fifobus, memmap) readpath, writepath = FIFOBus(), FIFOBus() readpath.clock = writepath.clock = clock tbmap = fifobus.assign_read_write_paths(readpath, writepath) tbftx = fifo_fast(reset, clock, writepath) # user write path tbfrx = fifo_fast(reset, clock, readpath) # user read path # @todo: add other bus types tbmem = memmap_peripheral_bb(clock, reset, memmap) # save the data read ... read_value = [] @instance def tbstim(): yield reset.pulse(32) fifobus.read.next = False fifobus.write.next = False assert not fifobus.full assert fifobus.empty assert fifobus.read_data == 0 fifobus.write_data.next = 0 try: # test a single address pkt = CommandPacket(True, 0x0000) yield pkt.put(readpath) yield pkt.get(writepath, read_value, [0]) pkt = CommandPacket(False, 0x0000, [0x5555AAAA]) yield pkt.put(readpath) yield pkt.get(writepath, read_value, [0x5555AAAA]) # test a bunch of random addresses for ii in range(nloops): randaddr = randint(0, (2**20) - 1) randdata = randint(0, (2**32) - 1) pkt = CommandPacket(False, randaddr, [randdata]) yield pkt.put(readpath) yield pkt.get(writepath, read_value, [randdata]) except Exception as err: print("Error: {}".format(str(err))) traceback.print_exc() yield delay(2000) raise StopSimulation wp_read, wp_valid = Signals(bool(0), 2) wp_read_data = Signal(intbv(0)[8:]) wp_empty, wp_full = Signals(bool(0), 2) @always_comb def tbmon(): wp_read.next = writepath.read wp_read_data.next = writepath.read_data wp_valid.next = writepath.read_valid wp_full.next = writepath.full wp_empty.next = writepath.empty return tbclk, tbdut, tbmap, tbftx, tbfrx, tbmem, tbstim, tbmon