示例#1
0
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
示例#2
0
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
示例#3
0
    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