def doublefifo(clock, reset, dfifo_bus, width=8, depth=16): """double fifo core function""" fifo_data_in = Signal(intbv(0)[width:]) glbl = Global(clock, reset) fbus1 = FIFOBus(width=width) fbus2 = FIFOBus(width=width) assert isinstance(glbl, Global) assert isinstance(fbus1, FIFOBus) assert isinstance(fbus2, FIFOBus) fifo_sync1 = fifo_sync(glbl, fbus1, depth) fifo_sync2 = fifo_sync(glbl, fbus2, depth) @always_comb def assign(): """write into fifo bus""" fbus1.write_data.next = fifo_data_in fbus2.write_data.next = fifo_data_in @always_seq(clock.posedge, reset=reset) def mux2_logic(): """select which buffer to enable""" if dfifo_bus.buffer_sel == 0: fbus1.write.next = dfifo_bus.write_enable else: fbus2.write.next = dfifo_bus.write_enable fifo_data_in.next = dfifo_bus.data_in @always_comb def logic(): """read or write into buffer""" fbus1.read.next = dfifo_bus.read_req if ( dfifo_bus.buffer_sel == 1) else 0 fbus2.read.next = dfifo_bus.read_req if ( dfifo_bus.buffer_sel == 0) else 0 dfifo_bus.data_out.next = fbus1.read_data if ( dfifo_bus.buffer_sel == 1) else fbus2.read_data dfifo_bus.fifo_empty.next = fbus1.empty if ( dfifo_bus.buffer_sel == 1) else fbus2.empty return ( fifo_sync1, fifo_sync2, assign, mux2_logic, logic)
def _test(): # @todo: use args.fast, args.use_srl_prim tbdut = fifo_sync(clock, reset, fbus) @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" fbus.rd.next = True yield clock.posedge for ii in range(num_bytes): yield clock.posedge fbus.rd.next = True # 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 bench_fifo_sync(): # @todo: use args.fast, args.use_srl_prim tbdut = fifo_sync(clock, reset, fbus) @always(delay(10)) def tbclk(): clock.next = not clock @instance def tbstim(): fbus.write_data.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): yield clock.posedge fbus.write_data.next = ii fbus.write.next = True yield clock.posedge fbus.write.next = False fbus.write_data.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" fbus.read.next = True yield clock.posedge for ii in range(num_bytes): yield clock.posedge fbus.read.next = True assert fbus.read_valid assert fbus.read_data == ii, "rdata %x ii %x " % ( fbus.read_data, ii) fbus.read.next = False yield clock.posedge assert fbus.empty # Test overflows # Test underflows # Test write / read same time raise StopSimulation return tbdut, tbclk, tbstim
def doublefifo(clock, reset, dfifo_bus, buffer_sel, depth=16): """ I/O ports: dfifo_bus : A FIFOBus connection interace buffer_sel : select a buffer Constants : depth : depth of the fifo used width_data : width of the data to be stored in FIFO """ # width of the input data width_data = len(dfifo_bus.write_data) # input to both the FIFO's fifo_data_in = Signal(intbv(0)[width_data:]) # FIFOBus instantiation from rhea glbl = Global(clock, reset) fbus1 = FIFOBus(width=width_data) fbus2 = FIFOBus(width=width_data) assert isinstance(glbl, Global) assert isinstance(fbus1, FIFOBus) assert isinstance(fbus2, FIFOBus) # instantiate two sync FIFO's fifo_sync1 = fifo_sync(glbl, fbus1, depth) fifo_sync2 = fifo_sync(glbl, fbus2, depth) @always_comb def assign(): """write data into FIFO's""" fbus1.write_data.next = fifo_data_in fbus2.write_data.next = fifo_data_in @always_seq(clock.posedge, reset=reset) def mux2_logic(): """select buffer to pump data""" if not buffer_sel: fbus1.write.next = dfifo_bus.write else: fbus2.write.next = dfifo_bus.write fifo_data_in.next = dfifo_bus.write_data @always_comb def logic(): """read or write into buffer""" fbus1.read.next = dfifo_bus.read if ( buffer_sel) else False fbus2.read.next = dfifo_bus.read if ( not buffer_sel) else False dfifo_bus.read_data.next = fbus1.read_data if ( buffer_sel) else fbus2.read_data dfifo_bus.empty.next = fbus1.empty if ( buffer_sel) else fbus2.empty return ( fifo_sync1, fifo_sync2, assign, mux2_logic, logic)
def bench(): reset = ResetSignal(0, active=1, async=True) clock = Signal(bool(0)) fbus = FIFOBus(width=args.width, size=args.size) tbdut = fifo_sync(clock, reset, fbus) @instance def tbclk(): clock.next = False while True: yield delay(5) clock.next = not clock @instance def tbstim(): print("start simulation") fbus.read.next = False fbus.write.next = False fbus.clear.next = False reset.next = True yield delay(20) reset.next = False yield clock.posedge print("r, w, e, f") print("%d, %d, %d, %d, should be empty" % ( fbus.read, fbus.write, fbus.empty, fbus.full, )) assert fbus.empty fbus.write.next = True fbus.write_data.next = 0xAA yield clock.posedge fbus.write.next = False yield clock.posedge print("%d, %d, %d, %d, should not be empty" % ( fbus.read, fbus.write, fbus.empty, fbus.full, )) assert not fbus.empty print("FIFO count %d (%d%d%d%d)" % (fbus.count, fbus.read, fbus.write, fbus.empty, fbus.full)) print("more writes") fbus.write.next = True fbus.write_data.next = 1 for ii in range(15): yield clock.posedge print( "FIFO count %d (%d%d%d%d)" % (fbus.count, fbus.read, fbus.write, fbus.empty, fbus.full)) fbus.write_data.next = ii + 2 fbus.write.next = False yield clock.posedge print("FIFO count %d (%d%d%d%d)" % (fbus.count, fbus.read, fbus.write, fbus.empty, fbus.full)) yield clock.posedge print("%d, %d, %d, %d, should be full" % ( fbus.read, fbus.write, fbus.empty, fbus.full, )) # assert fbus.full fbus.read.next = True assert fbus.read_data == 0xAA yield fbus.read_valid.posedge fbus.read.next = False yield delay(1) print("%d, %d, %d, %d" % ( fbus.read, fbus.write, fbus.empty, fbus.full, )) yield clock.posedge yield clock.posedge fbus.read.next = True for ii in range(15): print("FIFO count %d data %d (%d%d%d%d)" % (fbus.count, fbus.read_data, fbus.read, fbus.write, fbus.empty, fbus.full)) yield clock.posedge fbus.read.next = False yield clock.posedge print("%d, %d, %d, %d" % ( fbus.read, fbus.write, fbus.empty, fbus.full, )) print("end simulation") raise StopSimulation return tbdut, tbclk, tbstim
def bench_fifo_sync(): tbdut = fifo_sync(glbl, fbus, size=args.size) tbclk = clock.gen() @instance def tbstim(): fbus.write_data.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): yield clock.posedge fbus.write_data.next = ii + 0xCE fbus.write.next = True yield clock.posedge fbus.write.next = False fbus.write_data.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" # fbus.read.next = True # yield clock.posedge for ii in range(5): yield clock.posedge if not fbus.empty: break for ii in range(num_bytes): fbus.read.next = True yield clock.posedge assert fbus.read_valid assert fbus.read_data == ii + 0xCE, \ "rdata %x ii %x " % (fbus.read_data, ii + 0xCE) fbus.read.next = False yield clock.posedge assert fbus.empty raise StopSimulation w = args.width write_data, read_data = Signals(intbv(0)[w:], 2) @always_comb def tbmon(): write_data.next = fbus.write_data read_data.next = fbus.read_data return tbdut, tbclk, tbstim, tbmon
def bench_convserion_fifo_sync(): args = Namespace(width=8, size=16, name='test') reset = ResetSignal(0, active=1, async=True) clock = Signal(bool(0)) glbl = Global(clock, reset) fbus = FIFOBus(width=args.width) tbdut = fifo_sync(glbl, fbus, size=args.size) @instance def tbclk(): clock.next = False while True: yield delay(5) clock.next = not clock @instance def tbstim(): print("start simulation") fbus.read.next = False fbus.write.next = False fbus.clear.next = False fbus.write_data.next = 0 reset.next = True yield delay(20) reset.next = False yield clock.posedge print("r, w, e, f") print("%d, %d, %d, %d, should be empty" % ( fbus.read, fbus.write, fbus.empty, fbus.full,)) assert fbus.empty fbus.write.next = True fbus.write_data.next = 0xAA yield clock.posedge fbus.write.next = False yield clock.posedge print("%d, %d, %d, %d, should not be empty" % ( fbus.read, fbus.write, fbus.empty, fbus.full,)) assert not fbus.empty print("FIFO count %d (%d%d%d%d)" % ( fbus.count, fbus.read, fbus.write, fbus.empty, fbus.full)) print("more writes") fbus.write.next = True fbus.write_data.next = 1 for ii in range(15): yield clock.posedge print("FIFO count %d (%d%d%d%d)" % ( fbus.count, fbus.read, fbus.write, fbus.empty, fbus.full)) fbus.write_data.next = ii + 2 fbus.write.next = False yield clock.posedge print("FIFO count %d (%d%d%d%d)" % ( fbus.count, fbus.read, fbus.write, fbus.empty, fbus.full)) yield clock.posedge print("%d, %d, %d, %d, should be full" % ( fbus.read, fbus.write, fbus.empty, fbus.full,)) # assert fbus.full fbus.read.next = True assert fbus.read_data == 0xAA yield fbus.read_valid.posedge fbus.read.next = False yield delay(1) print("%d, %d, %d, %d" % ( fbus.read, fbus.write, fbus.empty, fbus.full,)) yield clock.posedge yield clock.posedge fbus.read.next = True for ii in range(15): print("FIFO count %d data %d (%d%d%d%d)" % ( fbus.count, fbus.read_data, fbus.read, fbus.write, fbus.empty, fbus.full)) yield clock.posedge fbus.read.next = False yield clock.posedge print("%d, %d, %d, %d" % ( fbus.read, fbus.write, fbus.empty, fbus.full,)) print("end simulation") raise StopSimulation @instance def tbmon(): clockticks = 0 init_mem = False read_data = 0 while True: if not reset: if not init_mem: read_data = 0 else: read_data = int(fbus.read_data) print("%d: %d %d %d %d .. (w) %d %d .. (r) %d %d %d" % ( clockticks, fbus.clear, fbus.empty, fbus.full, fbus.count, fbus.write, fbus.write_data, fbus.read, fbus.read_valid, read_data, )) clockticks = clockticks + 1 if not fbus.empty: init_mem = True yield clock.posedge return tbdut, tbclk, tbstim, tbmon
def bench_fifo_sync(): tbdut = fifo_sync(glbl, fbus, size=args.size) tbclk = clock.gen() @instance def tbstim(): fbus.write_data.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): yield clock.posedge fbus.write_data.next = ii + 0xCE fbus.write.next = True yield clock.posedge fbus.write.next = False fbus.write_data.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" # fbus.read.next = True # yield clock.posedge for ii in range(5): yield clock.posedge if not fbus.empty: break for ii in range(num_bytes): fbus.read.next = True yield clock.posedge assert fbus.read_valid assert fbus.read_data == ii + 0xCE, \ "rdata %x ii %x " % (fbus.read_data, ii + 0xCE) fbus.read.next = False yield clock.posedge assert fbus.empty raise StopSimulation w = args.width write_data, read_data = Signals(intbv(0)[w:], 2) @always_comb def tbmon(): write_data.next = fbus.write_data read_data.next = fbus.read_data return tbdut, tbclk, tbstim, tbmon
def bench_convserion_fifo_sync(): args = Namespace(width=8, size=16, name='test') reset = ResetSignal(0, active=1, async=True) clock = Signal(bool(0)) glbl = Global(clock, reset) fbus = FIFOBus(width=args.width) tbdut = fifo_sync(glbl, fbus, size=args.size) @instance def tbclk(): clock.next = False while True: yield delay(5) clock.next = not clock @instance def tbstim(): print("start simulation") fbus.read.next = False fbus.write.next = False fbus.clear.next = False fbus.write_data.next = 0 reset.next = True yield delay(20) reset.next = False yield clock.posedge print("r, w, e, f") print("%d, %d, %d, %d, should be empty" % ( fbus.read, fbus.write, fbus.empty, fbus.full, )) assert fbus.empty fbus.write.next = True fbus.write_data.next = 0xAA yield clock.posedge fbus.write.next = False yield clock.posedge print("%d, %d, %d, %d, should not be empty" % ( fbus.read, fbus.write, fbus.empty, fbus.full, )) assert not fbus.empty print("FIFO count %d (%d%d%d%d)" % (fbus.count, fbus.read, fbus.write, fbus.empty, fbus.full)) print("more writes") fbus.write.next = True fbus.write_data.next = 1 for ii in range(15): yield clock.posedge print("FIFO count %d (%d%d%d%d)" % (fbus.count, fbus.read, fbus.write, fbus.empty, fbus.full)) fbus.write_data.next = ii + 2 fbus.write.next = False yield clock.posedge print("FIFO count %d (%d%d%d%d)" % (fbus.count, fbus.read, fbus.write, fbus.empty, fbus.full)) yield clock.posedge print("%d, %d, %d, %d, should be full" % ( fbus.read, fbus.write, fbus.empty, fbus.full, )) # assert fbus.full fbus.read.next = True assert fbus.read_data == 0xAA yield fbus.read_valid.posedge fbus.read.next = False yield delay(1) print("%d, %d, %d, %d" % ( fbus.read, fbus.write, fbus.empty, fbus.full, )) yield clock.posedge yield clock.posedge fbus.read.next = True for ii in range(15): print("FIFO count %d data %d (%d%d%d%d)" % (fbus.count, fbus.read_data, fbus.read, fbus.write, fbus.empty, fbus.full)) yield clock.posedge fbus.read.next = False yield clock.posedge print("%d, %d, %d, %d" % ( fbus.read, fbus.write, fbus.empty, fbus.full, )) print("end simulation") raise StopSimulation @instance def tbmon(): clockticks = 0 init_mem = False read_data = 0 while True: if not reset: if not init_mem: read_data = 0 else: read_data = int(fbus.read_data) print("%d: %d %d %d %d .. (w) %d %d .. (r) %d %d %d" % ( clockticks, fbus.clear, fbus.empty, fbus.full, fbus.count, fbus.write, fbus.write_data, fbus.read, fbus.read_valid, read_data, )) clockticks = clockticks + 1 if not fbus.empty: init_mem = True yield clock.posedge return tbdut, tbclk, tbstim, tbmon
def bench(): reset = ResetSignal(0, active=1, async=True) clock = Signal(bool(0)) fbus = FIFOBus(width=args.width, size=args.size) tbdut = fifo_sync(clock, reset, fbus) @instance def tbclk(): clock.next = False while True: yield delay(5) clock.next = not clock @instance def tbstim(): print("start simulation") fbus.read.next = False fbus.write.next = False fbus.clear.next = False reset.next = True yield delay(20) reset.next = False yield clock.posedge print("r, w, e, f") print("%d, %d, %d, %d, should be empty" % ( fbus.read, fbus.write, fbus.empty, fbus.full,)) assert fbus.empty fbus.write.next = True fbus.write_data.next = 0xAA yield clock.posedge fbus.write.next = False yield clock.posedge print("%d, %d, %d, %d, should not be empty" % ( fbus.read, fbus.write, fbus.empty, fbus.full,)) assert not fbus.empty print("FIFO count %d (%d%d%d%d)" % ( fbus.count, fbus.read, fbus.write, fbus.empty, fbus.full)) print("more writes") fbus.write.next = True fbus.write_data.next = 1 for ii in range(15): yield clock.posedge print("FIFO count %d (%d%d%d%d)" % ( fbus.count, fbus.read, fbus.write, fbus.empty, fbus.full)) fbus.write_data.next = ii + 2 fbus.write.next = False yield clock.posedge print("FIFO count %d (%d%d%d%d)" % ( fbus.count, fbus.read, fbus.write, fbus.empty, fbus.full)) yield clock.posedge print("%d, %d, %d, %d, should be full" % ( fbus.read, fbus.write, fbus.empty, fbus.full,)) # assert fbus.full fbus.read.next = True assert fbus.read_data == 0xAA yield fbus.read_valid.posedge fbus.read.next = False yield delay(1) print("%d, %d, %d, %d" % ( fbus.read, fbus.write, fbus.empty, fbus.full,)) yield clock.posedge yield clock.posedge fbus.read.next = True for ii in range(15): print("FIFO count %d data %d (%d%d%d%d)" % ( fbus.count, fbus.read_data, fbus.read, fbus.write, fbus.empty, fbus.full)) yield clock.posedge fbus.read.next = False yield clock.posedge print("%d, %d, %d, %d" % ( fbus.read, fbus.write, fbus.empty, fbus.full,)) print("end simulation") raise StopSimulation return tbdut, tbclk, tbstim