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 moudule port list (function arguments). fbus.wr = wr fbus.wdata = datain fbus.rd = rd fbus.rdata = dataout fbus.clear = clear @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 = m_fifo_fast(clock, reset, 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 moudule 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 = m_fifo_fast(clock, reset, fbus) return rtl_assign1, rtl_assign2, gfifo
def _test(): # @todo: use args.fast, args.use_srl_prim tbdut = m_fifo_fast(clock, reset, fbus, use_srl_prim=False) @always(delay(10)) def tbclk(): clock.next = not clock @instance def tbstim(): fbus.wdata.next = 0xFE reset.next = reset.active yield delay(33) reset.next = not reset.active for ii in range(5): yield clock.posedge # test the normal cases for num_bytes in range(1, args.size+1): # write some bytes for ii in range(num_bytes): #print('nbyte %x wdata %x' % (num_bytes, ii)) yield clock.posedge fbus.wdata.next = ii fbus.wr.next = True yield clock.posedge fbus.wr.next = False fbus.wdata.next = 0xFE # if 16 bytes written make sure FIFO is full yield clock.posedge if num_bytes == args.size: assert fbus.full, "FIFO should be full!" assert not fbus.empty, "FIFO should not be empty" for ii in range(num_bytes): fbus.rd.next = True yield clock.posedge #print("rdata %x ii %x " % (fbus.rdata, ii)) assert fbus.rvld assert fbus.rdata == ii, "rdata %x ii %x " % (fbus.rdata, ii) fbus.rd.next = False yield clock.posedge assert fbus.empty # Test overflows # Test underflows # Test write / read same time raise StopSimulation return tbdut, tbclk, tbstim
def m_fifo_2clock_cascade( wclk, # in: write side clock datain, # in: write data src_rdy_i, # in: dst_rdy_o, # out: space, # out: how many can be written rclk, # in: read side clock dataout, # out: read data src_rdy_o, # out: dst_rdy_i, # in: occupied, # out: number in the fifo reset, # in: system reset ): wr = Signal(bool(0)) # wr1 #wr2 = Signal(bool(0)) # rd1 wr3 = Signal(bool(0)) rd1 = Signal(bool(0)) rd2 = Signal(bool(0)) rd = Signal(bool(0)) # rd3 ed1 = Signal(bool(1)) args = Namespace(width=36, size=128, name='fifo_2clock_cascade') fbus2 = FIFOBus(args=args) args.size = 16 fbus1 = FIFOBus(args=args) fbus3 = FIFOBus(args=args) # need to update the fbus refernces to reference the Signals in # the moudule port list (function arguments). fbus1.wr = wr fbus1.wdata = datain fbus1.rd = rd1 fbus2.wr = rd1 fbus2.wdata = fbus1.rdata fbus2.rd = rd2 fbus3.wr = wr3 fbus3.wdata = fbus2.rdata fbus3.rd = rd fbus3.rdata = dataout @always_comb def rtl_assign1(): wr.next = src_rdy_i and dst_rdy_o rd.next = dst_rdy_i and src_rdy_o rd1.next = not fbus1.empty and not fbus2.full rd2.next = not ed1 and not fbus3.full wr3.next = fbus2.rvld @always_comb def rtl_assign2(): dst_rdy_o.next = not fbus1.full src_rdy_o.next = not fbus3.empty # @todo: fix the m_fifo_async bug!!! # hackery, need to fix the simultaneous write and read issue # with the async FIFO! @always_seq(rclk.posedge, reset=reset) def rtl_ed1(): if ed1: ed1.next = fbus2.empty else: ed1.next = True # the original was a chain: # m_fifo_fast (16) # m_fifo_async (64)tx, (512)rx # m_fifo_fast (16) # the two small FIFOs were used to simplify the interface to # the async FIFO, the async FIFOs have some odd behaviors, the # up front fast fifo wasn't really needed. # the small fast FIFOs have a simpler (reactive) interface # it works more like a register with enable(s). gfifo1 = m_fifo_fast(wclk, reset, fbus1) gfifo2 = m_fifo_async(reset, wclk, rclk, fbus2) gfifo3 = m_fifo_fast(rclk, reset, fbus3) return rtl_assign1, rtl_assign2, rtl_ed1, gfifo1, gfifo2, gfifo3