def test_atomTupleCreator(): width = 8 scope = Scope() T0 = ST_Int() T1 = ST_Bit() T_outer_output = ST_Atom_Tuple(T0, T1) args = ['I0', In(T0.magma_repr()), 'I1', In(T1.magma_repr()), \ 'O', Out(T_outer_output.magma_repr())] + ClockInterface(False, False) testcircuit = DefineCircuit('Test', *args) atomTupleAppender = AtomTupleCreator(T0, T1) wire(testcircuit.I0, atomTupleAppender.I0) wire(testcircuit.I1, atomTupleAppender.I1) wire(testcircuit.O, atomTupleAppender.O) EndCircuit() sim = CoreIRSimulator(testcircuit, testcircuit.CLK) sim.set_value(testcircuit.I0, int2seq(4, width), scope) sim.set_value(testcircuit.I1, True, scope) sim.evaluate() assert seq2int(sim.get_value(testcircuit.O[0], scope)) == 4 assert sim.get_value(testcircuit.O[1], scope) == True
def test_sseqTupleAppender(): width = 8 scope = Scope() testvals = [1, 2, 3] T_inner = ST_TSeq(2, 0, ST_Int()) T_outer_input = ST_SSeq_Tuple(2, ST_Int()) T_outer_output = ST_SSeq_Tuple(3, ST_Int()) args = ['I0', In(T_outer_input.magma_repr()), 'I1', In(T_inner.magma_repr()), \ 'O', Out(T_outer_output.magma_repr())] + ClockInterface(False, False) testcircuit = DefineCircuit('Test', *args) sseqTupleAppender = SSeqTupleAppender(T_inner, 2) wire(testcircuit.I0, sseqTupleAppender.I0) wire(testcircuit.I1, sseqTupleAppender.I1) wire(testcircuit.O, sseqTupleAppender.O) EndCircuit() sim = CoreIRSimulator(testcircuit, testcircuit.CLK) sim.set_value(testcircuit.I0[0], int2seq(testvals[0], width), scope) sim.set_value(testcircuit.I0[1], int2seq(testvals[1], width), scope) sim.set_value(testcircuit.I1, int2seq(testvals[2], width), scope) sim.evaluate() for i in range(len(testvals)): assert seq2int(sim.get_value(testcircuit.O[i], scope)) == testvals[i]
def test_config_register(): WIDTH = 32 ADDR_WIDTH = 8 ADDR_VALUE = 4 # Check that compilation to CoreIR works. Delete JSON file afterwards. cr = define_config_register(WIDTH, m.bits(ADDR_VALUE, ADDR_WIDTH), True) m.compile("config_register", cr, output='coreir') gold_check = check_files_equal("config_register.json", "test_common/gold/config_register.json") assert gold_check res = os.system("\\rm config_register.json") assert res == 0 # Check the module against a simple simulation. simulator = CoreIRSimulator(cr, clock=cr.CLK) def reg_value(): return simulator.get_value(cr.O) def step(I, addr): simulator.set_value(cr.I, I) simulator.set_value(cr.addr, addr) simulator.set_value(cr.CE, 1) simulator.advance(2) return reg_value() assert BitVector(reg_value()) == BitVector(0, WIDTH) sequence = [(0, 0, 0), (12, 4, 12), (0, 0, 12), (9, 4, 9)] for (I, addr, out_expected) in sequence: out = step(BitVector(I, WIDTH), BitVector(addr, ADDR_WIDTH)) assert BitVector(out) == BitVector(out_expected, WIDTH)
def test_two_coreir_muxes(): width = 2 c = coreir.Context() cirb = CoreIRBackend(c) scope = Scope() inType = Array(width, In(BitIn)) outType = Array(width, Out(Bit)) args = ['I', inType, 'S', In(Bit), 'O', outType] + ClockInterface( False, False) testcircuit = DefineCircuit('test_partition', *args) coreir_mux = DefineCoreirMux(None)() coreir_mux(testcircuit.I[0], testcircuit.I[1], testcircuit.S) wire(coreir_mux.out, testcircuit.O[0]) cmux = CommonlibMuxN(cirb, 2, 1) wire(cmux.I.data[0][0], testcircuit.I[0]) wire(cmux.I.data[1][0], testcircuit.I[1]) wire(cmux.I.sel[0], testcircuit.S) wire(cmux.out[0], testcircuit.O[1]) EndCircuit() sim = CoreIRSimulator( testcircuit, testcircuit.CLK, context=c, namespaces=["commonlib", "mantle", "coreir", "global"])
def test_shift_s(): num_in = 4 test_vals = [2, 5, 3, 8] shift_amount = 2 in_type = ST_SSeq(num_in, ST_Int()) scope = Scope() args = ['I', In(in_type.magma_repr()), 'O', Out(in_type.magma_repr())] + ClockInterface(False, False) testcircuit = DefineCircuit('Test', *args) rshift = DefineShift_S(num_in, shift_amount, in_type.t)() wire(rshift.I, testcircuit.I) wire(testcircuit.O, rshift.O) EndCircuit() sim = CoreIRSimulator(testcircuit, testcircuit.CLK) for i, val in enumerate(test_vals): sim.set_value(testcircuit.I[i], int2seq(val, 8), scope) sim.evaluate() for i, val in enumerate(test_vals[shift_amount:]): assert seq2int(sim.get_value( testcircuit.O[i + shift_amount])) == test_vals[i]
def test_downsample_parallel_non_zero_idx(): width = 5 numIn = 4 scope = Scope() outType = Array[width, Out(BitIn)] inType = Array[numIn, In(outType)] args = ['I', inType, 'O', outType] + ClockInterface(False, False) testcircuit = DefineCircuit('Test_Downsample_Parallel', *args) downsampleParallel = DownsampleParallel(numIn, 2, inType.T) wire(downsampleParallel.I, testcircuit.I) wire(testcircuit.O, downsampleParallel.O) EndCircuit() sim = CoreIRSimulator(testcircuit, testcircuit.CLK, namespaces=[ "aetherlinglib", "commonlib", "mantle", "coreir", "global" ]) for i in range(numIn): sim.set_value(testcircuit.I[i], int2seq(i, width), scope) sim.evaluate() assert seq2int(sim.get_value(testcircuit.O, scope)) == 2
def test_reduce_parallel(): width = 11 numIn = 13 c = coreir.Context() cirb = CoreIRBackend(c) scope = Scope() inType = In(Array(numIn, Array(width, BitIn))) outType = Out(Array(width, Bit)) args = ['I', inType, 'O', outType] + ClockInterface(False, False) testcircuit = DefineCircuit('Test_Reduce_Parallel', *args) reducePar = ReduceParallel(cirb, numIn, renameCircuitForReduce(DefineAdd(width))) coreirConst = DefineCoreirConst(width, 0)() wire(reducePar.I.data, testcircuit.I) wire(reducePar.I.identity, coreirConst.out) wire(testcircuit.O, reducePar.out) EndCircuit() sim = CoreIRSimulator(testcircuit, testcircuit.CLK, context=cirb.context, namespaces=[ "aetherlinglib", "commonlib", "mantle", "coreir", "global" ]) for i in range(numIn): sim.set_value(testcircuit.I[i], int2seq(i, width), scope) sim.evaluate() assert seq2int(sim.get_value(testcircuit.O, scope)) == sum(range(numIn))
def test_downsample_parallel(): width = 5 numIn = 2 testVal = 3 c = coreir.Context() cirb = CoreIRBackend(c) scope = Scope() outType = Array(width, Out(BitIn)) inType = Array(numIn, In(outType)) args = ['I', inType, 'O', outType] + ClockInterface(False, False) testcircuit = DefineCircuit('Test_Downsample_Parallel', *args) downsampleParallel = DownsampleParallel(cirb, numIn, inType.T) wire(downsampleParallel.I, testcircuit.I) wire(testcircuit.O, downsampleParallel.O) EndCircuit() sim = CoreIRSimulator(testcircuit, testcircuit.CLK, context=cirb.context, namespaces=[ "aetherlinglib", "commonlib", "mantle", "coreir", "global" ]) for i in range(numIn): sim.set_value(testcircuit.I[i], int2seq(testVal, width), scope) sim.evaluate() assert seq2int(sim.get_value(testcircuit.O, scope)) == testVal
def test_sseqTupleCreator(): width = 8 scope = Scope() testvals = [1, 2] T = ST_TSeq(2, 0, ST_Int()) T_magma = T.magma_repr() args = ['I0', In(T_magma), 'I1', In(T_magma), 'O', Out(Array[2, T_magma])] + ClockInterface(False, False) testcircuit = DefineCircuit('Test', *args) sseqTupleCreator = SSeqTupleCreator(T) wire(testcircuit.I0, sseqTupleCreator.I0) wire(testcircuit.I1, sseqTupleCreator.I1) wire(testcircuit.O, sseqTupleCreator.O) EndCircuit() sim = CoreIRSimulator(testcircuit, testcircuit.CLK) sim.set_value(testcircuit.I0, int2seq(testvals[0], width), scope) sim.set_value(testcircuit.I1, int2seq(testvals[1], width), scope) sim.evaluate() for i in range(len(testvals)): assert seq2int(sim.get_value(testcircuit.O[i], scope)) == testvals[i]
def test_reduce_parallel(): width = 11 numIn = 13 scope = Scope() inType = In(Array[numIn, Array[width, BitIn]]) outType = Out(Array[width, Bit]) args = ['I', inType, 'O', outType] + ClockInterface(False, False) testcircuit = DefineCircuit('Test_Reduce_Parallel', *args) reducePar = ReduceParallel(numIn, DefineAdd(width)) wire(reducePar.I, testcircuit.I) wire(testcircuit.O, reducePar.O) EndCircuit() sim = CoreIRSimulator(testcircuit, testcircuit.CLK, namespaces=[ "aetherlinglib", "commonlib", "mantle", "coreir", "global" ]) for i in range(numIn): sim.set_value(testcircuit.I[i], int2seq(i, width), scope) sim.evaluate() assert seq2int(sim.get_value(testcircuit.O, scope)) == sum(range(numIn))
def test_parallel_simple_add(): from .parallelSimpleAdd import parallelSimpleAdd sim = CoreIRSimulator(parallelSimpleAdd, parallelSimpleAdd.CLK, namespaces=[ "aetherlinglib", "commonlib", "mantle", "coreir", "global" ]) sim.set_value(parallelSimpleAdd.I0, int2seq(1, 8)) sim.set_value(parallelSimpleAdd.I1, int2seq(2, 8)) sim.set_value(parallelSimpleAdd.I2, int2seq(3, 8)) sim.set_value(parallelSimpleAdd.I3, int2seq(4, 8)) sim.evaluate() assert seq2int(sim.get_value(parallelSimpleAdd.O0)) == 2 assert seq2int(sim.get_value(parallelSimpleAdd.O1)) == 3 assert seq2int(sim.get_value(parallelSimpleAdd.O2)) == 4 assert seq2int(sim.get_value(parallelSimpleAdd.O3)) == 5
def run_test_updown_npxPerClock(pxPerClock): upsampleAmount = 7 c = coreir.Context() cirb = CoreIRBackend(c) scope = Scope() args = ClockInterface(False, False) + RAMInterface(imgSrc, True, True, pxPerClock) testcircuit = DefineCircuit( 'Test_UpsampleDownsample_{}PxPerClock'.format(pxPerClock), *args) imgData = loadImage(imgSrc, pxPerClock) pixelType = Array(imgData.bitsPerPixel, Bit) bitsToPixelHydrate = MapParallel(cirb, pxPerClock, Hydrate(cirb, pixelType)) upParallel = MapParallel(cirb, pxPerClock, UpsampleParallel(upsampleAmount, pixelType)) downParallel = MapParallel( cirb, pxPerClock, DownsampleParallel(cirb, upsampleAmount, pixelType)) pixelToBitsDehydrate = MapParallel(cirb, pxPerClock, Dehydrate(cirb, pixelType)) # Note: input image RAM will send data to hydrate, # which converts it to form upsample and downsample can use # note that these do wiriring to connect the RAMs to edge of test circuit and # adjacent node inside circuit InputImageRAM(cirb, testcircuit, bitsToPixelHydrate.I, imgSrc, pxPerClock) OutputImageRAM(cirb, testcircuit, pixelToBitsDehydrate.out, testcircuit.input_ren, imgSrc, pxPerClock) wire(upParallel.I, bitsToPixelHydrate.out) wire(upParallel.O, downParallel.I) wire(downParallel.O, pixelToBitsDehydrate.I) EndCircuit() #GetCoreIRModule(cirb, testcircuit).save_to_file("updown_out{}.json".format(pxPerClock)) sim = CoreIRSimulator(testcircuit, testcircuit.CLK, context=cirb.context, namespaces=[ "aetherlinglib", "commonlib", "mantle", "coreir", "global" ]) LoadImageRAMForSimulation(sim, testcircuit, scope, imgSrc, pxPerClock) # run the simulation for all the rows for i in range(imgData.numRows): sim.evaluate() sim.advance_cycle() sim.evaluate() DumpImageRAMForSimulation(sim, testcircuit, scope, imgSrc, pxPerClock, validIfEqual)
def test_add_cout_one(): args = ['I0', In(Bits(1)), 'I1', In(Bits(1)), 'O', Out(Bits(1)), 'COUT', Out(Bit)] + \ ClockInterface(False, False) testcircuit = DefineCircuit('test_add_cout_one', *args) add = DefineAdd(1, cout=True)() wire(testcircuit.I0, add.I0) wire(testcircuit.I1, add.I1) wire(testcircuit.O, add.O) wire(testcircuit.COUT, add.COUT) EndCircuit() sim = CoreIRSimulator(testcircuit, testcircuit.CLK)
def simulator_nested(simple): width = 8 testValInt = 80 testValBits = int2seq(testValInt) c = coreir.Context() cirb = CoreIRBackend(c) scope = Scope() inDims = [4, 3, width] toNest = Array[inDims[1], Array[inDims[2], Bit]] inType = In(Array[inDims[0], toNest]) if simple: outType = Out(Array[inDims[0], toNest]) else: outType = Out(Array[2, Array[2, toNest]]) args = ['I', inType, 'O', outType] + ClockInterface(False, False) testcircuit = DefineCircuit( 'test_simulator_nested_simple{}'.format(str(simple)), *args) if simple: wire(testcircuit.I, testcircuit.O) else: wire(testcircuit.I[:2], testcircuit.O[0]) wire(testcircuit.I[2:4], testcircuit.O[1]) EndCircuit() sim = CoreIRSimulator(testcircuit, testcircuit.CLK, context=cirb.context, namespaces=[ "aetherlinglib", "commonlib", "mantle", "coreir", "global" ]) for i in range(inDims[0]): for j in range(inDims[1]): get = sim.get_value(testcircuit.I[i][j], scope) assert (len(get) == width) sim.set_value(testcircuit.I[i][j], int2seq((((i * inDims[1]) + j) * inDims[2]), width), scope) sim.evaluate() sim.get_value(testcircuit.I, scope) sim.get_value(testcircuit.O, scope)
def test_simulator_tuple(): width = 8 testValInt = 80 c = coreir.Context() cirb = CoreIRBackend(c) scope = Scope() inDims = [2, width] tupleEl = Array[inDims[1], Bit] nestedTuples = Array[inDims[0], Tuple(sel=tupleEl, data=tupleEl)] tupleValues = {'sel':int2seq(testValInt, width), 'data':int2seq(testValInt+20, width)} inType = In(nestedTuples) outType = Out(Array[2*inDims[0], tupleEl]) args = ['I', inType, 'O', outType] + ClockInterface(False, False) testcircuit = DefineCircuit('test_simulator_tuple', *args) wire(testcircuit.I[0].data, testcircuit.O[0]) wire(testcircuit.I[0].sel, testcircuit.O[1]) wire(testcircuit.I[1].data, testcircuit.O[2]) wire(testcircuit.I[1].sel, testcircuit.O[3]) EndCircuit() sim = CoreIRSimulator(testcircuit, testcircuit.CLK, context=cirb.context, namespaces=["aetherlinglib", "commonlib", "mantle", "coreir", "global"]) sim.set_value(testcircuit.I, [tupleValues, tupleValues], scope) getArrayInTuple = sim.get_value(testcircuit.I[0].data, scope) getTuples = sim.get_value(testcircuit.I, scope) assert getArrayInTuple == tupleValues['data'] assert getTuples[0] == tupleValues assert getTuples[1] == tupleValues
def test_pop_count(): PopCount8 = DefinePopCount(8) m.compile('build/popcount8', PopCount8, output="coreir") assert check_files_equal(__file__, "build/popcount8.json", "gold/popcount8.json") scope = Scope() sim = CoreIRSimulator(PopCount8, None) for I, expected_O in [(1, 1), (2, 1), (3, 2)]: sim.set_value(PopCount8.I, BitVector[8](I), scope) sim.evaluate() assert BitVector[8](sim.get_value(PopCount8.O, scope)).as_int() == expected_O
def test_sequential_simple_add(): from .sequentialSimpleAdd import sequentialSimpleAdd sim = CoreIRSimulator(sequentialSimpleAdd, sequentialSimpleAdd.CLK, namespaces=[ "aetherlinglib", "commonlib", "mantle", "coreir", "global" ]) sim.set_value(sequentialSimpleAdd.I0, int2seq(9, 8)) sim.evaluate() assert seq2int(sim.get_value(sequentialSimpleAdd.O0)) == 10
def test_ceil_floor_updown_counter(): scope = Scope() counter = DefineCeilFloorUpDownCounter(5, False) sim = CoreIRSimulator( counter, counter.CLK, namespaces=["commonlib", "mantle", "coreir", "global"]) # This pattern tests corner cases. # Pattern: set D on first clock to do nothing, then hold by setting U and D for a clock, # then count up to 4, then do nothing by trying to overflow, and finally hold by setting U and D for a clock u_pattern = [False, True, True, True, True, True, True, True] d_pattern = [True, True, False, False, False, False, False, True] out_pattern = [0, 0, 0, 1, 2, 3, 4, 4, 4] for i in range(len(u_pattern)): sim.set_value(counter.U, u_pattern[i], scope) sim.set_value(counter.D, d_pattern[i], scope) sim.evaluate() assert seq2int(sim.get_value(counter.O, scope)) == out_pattern[i] sim.advance_cycle() assert seq2int(sim.get_value(counter.O, scope)) == out_pattern[i + 1]
def test_updown_counter(): width = 2 scope = Scope() counter = DefineUpDownCounter(width, False) sim = CoreIRSimulator( counter, counter.CLK, namespaces=["commonlib", "mantle", "coreir", "global"]) # This pattern tests corner cases. # Pattern: set D on first clock to underflow to 3, then hold by setting U and D for a clock, # finally, counter from 3 to 1 and back to 3 u_pattern = [False, True, False, False, True, True] d_pattern = [True, True, True, True, False, False] out_pattern = [0, 3, 3, 2, 1, 2, 3] for i in range(len(u_pattern)): sim.set_value(counter.U, u_pattern[i], scope) sim.set_value(counter.D, d_pattern[i], scope) sim.evaluate() assert seq2int(sim.get_value(counter.O, scope)) == out_pattern[i] sim.advance_cycle() assert seq2int(sim.get_value(counter.O, scope)) == out_pattern[i + 1]
def test_sized_counter_modm(): args = ['O', Out(Array[2, Bit])] + ClockInterface(False, False) testcircuit = DefineCircuit('sized_counter_modm_test', *args) counter = SizedCounterModM(3, has_ce=True) wire(1, counter.CE) wire(testcircuit.O, counter.O) EndCircuit() #save_CoreIR_json(cirb, testcircuit, "sized_counter_modm.json") sim = CoreIRSimulator(testcircuit, testcircuit.CLK, namespaces=[ "aetherlinglib", "commonlib", "mantle", "coreir", "global" ])
def test_sipo(): args = ['I', In(Bit), 'O', Out(Array[4, Bit])] + ClockInterface( False, False) testcircuit = DefineCircuit('sipo_test', *args) sipo = SIPO(4, 0, has_ce=True) wire(1, sipo.CE) wire(testcircuit.I, sipo.I) wire(testcircuit.O, sipo.O) EndCircuit() #save_CoreIR_json(cirb, testcircuit, "sipo.json") sim = CoreIRSimulator(testcircuit, testcircuit.CLK, namespaces=[ "aetherlinglib", "commonlib", "mantle", "coreir", "global" ])
def test_modm_counter(): width = 5 numCycles = 4 maxCounter = 4 scope = Scope() args = ['O', Out(Bit)] + ClockInterface(False, False) testcircuit = DefineCircuit('TestModM', *args) counter = CounterModM(maxCounter, width, cout=False) decode = Decode(0, width) wire(decode.I, counter.O) wire(testcircuit.O, decode.O) EndCircuit() sim = CoreIRSimulator(testcircuit, testcircuit.CLK) for i in range(maxCounter * numCycles): sim.evaluate() sim.advance_cycle() assert sim.get_value(testcircuit.O, scope) == True
def test_double_nested_sipo(): scope = Scope() args = ['I', In(Bit), 'O', Out(Array[1, Array[1, Array[4, Bit]]])] + ClockInterface( False, False) testcircuit = DefineCircuit('multiple_sipo_test', *args) map_sipo = MapParallel(1, DefineMapParallel(1, DefineSIPO(4, 0, has_ce=True))) wire(1, map_sipo.CE[0][0]) wire(testcircuit.I, map_sipo.I[0][0]) wire(testcircuit.O, map_sipo.O) EndCircuit() # save_CoreIR_json(cirb, testcircuit, "multiple_sipo.json") sim = CoreIRSimulator(testcircuit, testcircuit.CLK, namespaces=[ "aetherlinglib", "commonlib", "mantle", "coreir", "global" ])
def test_multiple_sipo(): args = ['I', In(Bit), 'O', Out(Array[4, Bit])] + ClockInterface( False, False) testcircuit = DefineCircuit('multiple_sipo_test', *args) map_sipo = MapParallel(1, DefineSIPO(4, 0, has_ce=True)) wire(1, map_sipo.CE[0]) wire(testcircuit.I, map_sipo.I[0]) wire(testcircuit.O, map_sipo.O[0]) EndCircuit() #mod = GetCoreIRModule(GetCoreIRBackend(), testcircuit) #for p in ["rungenerators", "wireclocks-coreir", "verifyconnectivity --noclkrst", # "flattentypes", "flatten", "verifyconnectivity --noclkrst", "deletedeadinstances"]: # print("Running pass {}".format(p)) # c.run_passes([p], namespaces=["aetherlinglib", "commonlib", "mantle", "coreir", "global"]) # save_CoreIR_json(cirb, testcircuit, "multiple_sipo.json") sim = CoreIRSimulator(testcircuit, testcircuit.CLK, namespaces=[ "aetherlinglib", "commonlib", "mantle", "coreir", "global" ])
def test_multiple_sipo_and_counter(): args = ['I', In(Bit), 'O_sipo', Out(Array[4, Bit])] + [ 'O_counter', Out(Array[2, Bit]) ] + ClockInterface(False, False) testcircuit = DefineCircuit('multiple_sipo_and_counter_test', *args) map_sipo = MapParallel(1, SIPO(4, 0, has_ce=True)) wire(1, map_sipo.CE[0]) wire(testcircuit.I, map_sipo.I[0]) wire(testcircuit.O_sipo, map_sipo.O[0]) counter = SizedCounterModM(3, has_ce=True) wire(1, counter.CE) wire(testcircuit.O_counter, counter.O) EndCircuit() #save_CoreIR_json(cirb, testcircuit, "multiple_sipo_and_counter.json") sim = CoreIRSimulator(testcircuit, testcircuit.CLK, namespaces=[ "aetherlinglib", "commonlib", "mantle", "coreir", "global" ])
def test_reduce_sequential_without_ce(): width = 11 numIn = 13 scope = Scope() inType = In(Array[width, BitIn]) outType = Out(Array[width, Bit]) args = ['I', inType, 'O', outType, 'ready', Out(Bit), 'valid', Out(Bit)] + ClockInterface(has_ce=False) testcircuit = DefineCircuit('Test_Reduce_Sequential_Without_CE', *args) reduceSeq = ReduceSequential(numIn, DefineAdd(width), has_ce=False) wire(reduceSeq.I, testcircuit.I) wire(testcircuit.O, reduceSeq.out) wire(testcircuit.ready, reduceSeq.ready) wire(testcircuit.valid, reduceSeq.valid) EndCircuit() sim = CoreIRSimulator(testcircuit, testcircuit.CLK, namespaces=[ "aetherlinglib", "commonlib", "mantle", "coreir", "global" ]) for i in range(numIn): sim.set_value(testcircuit.I, int2seq(i, width), scope) sim.evaluate() # exit last time of loop without going to next iteration, time to check results then if i < numIn - 1: assert sim.get_value(testcircuit.valid, scope) == False assert sim.get_value(testcircuit.ready, scope) == True sim.advance_cycle() sim.evaluate() assert seq2int(sim.get_value(testcircuit.O, scope)) == sum(range(numIn)) assert sim.get_value(testcircuit.valid, scope) == True assert sim.get_value(testcircuit.ready, scope) == True
def a_1D_line_buffer_test(scope, in_arrays, magma_type, pixels_per_clock: int, window_width: int, image_size: int, output_stride: int, origin: int): """Simulate a line buffer with the given parameters, token type, and specified input (list-of-lists, outer list is time and inner list represents array of values). Use python int type to represent int; we translate to array of bits at the last second. """ window_count, parallelism, valid_count = internal_params_1D( pixels_per_clock, window_width, image_size, output_stride, origin) expected = expected_valid_outputs_1D(in_arrays, pixels_per_clock, window_width, image_size, output_stride, origin) LineBufferDef = DefineOneDimensionalLineBuffer(magma_type, pixels_per_clock, window_width, image_size, output_stride, origin) #save_CoreIR_json(cirb, LineBufferDef, "native_linebuffer.json") sim = CoreIRSimulator(LineBufferDef, LineBufferDef.CLK, namespaces=[ "aetherlinglib", "commonlib", "mantle", "coreir", "global" ]) sim.set_value(LineBufferDef.CE, 1, scope) # List for recording sequence of valid outputs (in the same format # as specified by expected_valid_outputs_1D), and a two helper # functions. tick_sim_collect_outputs ticks the simulation, # appending any output received when the simulated module asserts # valid. set_value feeds a new array input to the # simulator. There's one version for bit and one for int (annoying # leaky abstraction). actual = [] if magma_type == Bit: def tick_sim_collect_outputs(): sim.evaluate() sim.advance_cycle() if sim.get_value(LineBufferDef.valid, scope): actual.append([[ bool(sim.get_value(LineBufferDef.O[par][pix], scope)) for pix in range(window_width) ] for par in range(parallelism)]) def set_value(bit_array): sim.set_value(LineBufferDef.I, bit_array, scope) else: try: bit_width = magma_type.N if magma_type.T != Bit: raise TypeError("Array not made of Bits.") except Exception as e: raise TypeError("magma_type appears not to be Bit " "or Array of Bit.") from e # So, we need to pad the sequence of bits with zero because if it # doesn't match the expected bit width exactly, we will segfault. def padded_int2seq(x): return int2seq(x, n=bit_width) def tick_sim_collect_outputs(): sim.evaluate() sim.advance_cycle() if sim.get_value(LineBufferDef.valid, scope): actual.append([[ seq2int(sim.get_value(LineBufferDef.O[par][pix], scope)) for pix in range(window_width) ] for par in range(parallelism)]) def set_value(int_array): sim.set_value(LineBufferDef.I, list(map(padded_int2seq, int_array)), scope) for array in in_arrays: set_value(array) tick_sim_collect_outputs() # Wait for a little extra after the last input because the line buffer # may need a bit of extra time to emit the last windows (also, it gives # us a chance to check for excessive valid outputs). extra_cycles = 16 + window_width for i in range(extra_cycles): if len(actual) >= len(expected): break tick_sim_collect_outputs() len_actual, len_expected = len(actual), len(expected) assert len_actual >= len_expected, \ f"Got {len_actual} outputs (counts of valid asserts); expected " \ f"{len_expected} outputs.\n" \ f"Waited {extra_cycles} cycles after last input." assert outputs_match_1D(actual[0:len_expected], expected), \ "Outputs don't match."
def test_reduce_sequential(): width = 11 numIn = 13 c = coreir.Context() cirb = CoreIRBackend(c) scope = Scope() inType = In(Array(width, BitIn)) outType = Out(Array(width, Bit)) args = ['I', inType, 'O', outType, 'valid', Out(Bit)] + ClockInterface(False, False) testcircuit = DefineCircuit('Test_Reduce_Parallel', *args) reduceSeq = ReduceSequential(cirb, numIn, renameCircuitForReduce(DefineAdd(width))) wire(reduceSeq.I, testcircuit.I) wire(testcircuit.O, reduceSeq.out) wire(testcircuit.valid, reduceSeq.valid) EndCircuit() sim = CoreIRSimulator(testcircuit, testcircuit.CLK, context=cirb.context, namespaces=[ "aetherlinglib", "commonlib", "mantle", "coreir", "global" ]) for i in range(numIn): sim.set_value(testcircuit.I, int2seq(i, width), scope) sim.evaluate() # exit last time of loop without going to next iteration, time to check results then if i < numIn - 1: assert sim.get_value(testcircuit.valid, scope) == False sim.advance_cycle() sim.evaluate() assert seq2int(sim.get_value(testcircuit.O, scope)) == sum(range(numIn)) assert sim.get_value(testcircuit.valid, scope) == True
def test_downsample_sequential(): width = 5 numOut = 2 testVal = 3 c = coreir.Context() scope = Scope() outType = Array(width, Out(BitIn)) inType = In(outType) args = ['I', inType, 'O', outType, 'VALID', Out(Bit)] + ClockInterface(False, False) testcircuit = DefineCircuit('Test_Downsample_Sequential', *args) cirb = CoreIRBackend(c) downsampleSequential = DownsampleSequential(numOut, inType) wire(downsampleSequential.I, testcircuit.I) wire(testcircuit.O, downsampleSequential.O) wire(testcircuit.VALID, downsampleSequential.VALID) EndCircuit() #testModule = GetCoreIRModule(cirb, testcircuit) #cirb.context.run_passes(["rungenerators", "verifyconnectivity-noclkrst"], ["aetherlinglib", "commonlib", "mantle", "coreir", "global"]) #testModule.save_to_file("downsampleSequential.json") sim = CoreIRSimulator(testcircuit, testcircuit.CLK, context=cirb.context, namespaces=[ "aetherlinglib", "commonlib", "mantle", "coreir", "global" ]) sim.set_value(testcircuit.I, int2seq(testVal, width), scope) sim.evaluate() for i in range(numOut): assert seq2int(sim.get_value(testcircuit.O, scope)) == testVal assert sim.get_value(testcircuit.VALID, scope) == (i == 0) sim.advance_cycle() sim.evaluate()
def impl_test_2D_line_buffer(parameters: LineBufferParameters): """Instantiate a simulated line buffer with the specified parameters and run it on test data sets.""" print(parameters.as_kwargs()) scope = Scope() LineBufferDef = DefineTwoDimensionalLineBuffer(**parameters.as_kwargs()) window_count, parallelism, valid_count = parameters.internal_parameters() window_x = parameters.window_x window_y = parameters.window_y sim = None # We have to treat int (as bit array) and bit line buffers # differently. Deal with these differences here (different random # data generator, need int2seq/seq2int for ints). Ugly but better # than 2 copies of this function. token = parameters.magma_type if token == Bit: generators = make_bit_generators() def set_value(bits): sim.set_value(LineBufferDef.I, bits, scope) def get_pixel(window_index, y, x): return sim.get_value(LineBufferDef.O[window_index][y][x], scope) else: try: bit_width = token.N if token.T != Bit: raise TypeError("Not a bit.") except Exception as e: raise TypeError("Type must be Bit or Array[n, Bit]") from e generators = make_int_generators(bit_width) def set_value(ints): f = lambda px: int2seq(px, bit_width) bit_arrays = [[f(px) for px in row] for row in ints] sim.set_value(LineBufferDef.I, bit_arrays, scope) def get_pixel(window_index, y, x): return seq2int( sim.get_value(LineBufferDef.O[window_index][y][x], scope)) for test_set in generate_test_sets_2D(generators, parameters): sim = CoreIRSimulator(LineBufferDef, LineBufferDef.CLK, namespaces=[ "aetherlinglib", "commonlib", "mantle", "coreir", "global" ]) sim.set_value(LineBufferDef.CE, 1, scope) # List for recording sequence of valid outputs (in 4D format # in header, skipping entries on cycles where valid is not # asserted), and a helper function: # tick_sim_collect_outputs ticks the simulation, appending any # output received when the simulated module asserts valid. actual = [] expected = expected_valid_outputs_2D(test_set, parameters) quijibo = -1 def tick_sim_collect_outputs(): nonlocal quijibo sim.evaluate() quijibo += 1 # test1_scope = Scope(instance=LineBufferDef._instances[0], parent=scope) # test2_scope = Scope(instance=LineBufferDef._instances[0]._instances[0], parent=scope) # #print("testing test2 {}".format(sim.get_value(LineBufferDef._instances[0]._instances[0].O, test2_scope))) # test3_scope = Scope(instance=LineBufferDef._instances[0]._instances[0]._instances[0], parent=test2_scope) # test4_scope = Scope(instance=LineBufferDef._instances[0]._instances[0]._instances[0]._instances[0], parent=test3_scope) # test5_scope = Scope(instance=LineBufferDef._instances[0]._instances[0]._instances[0]._instances[0]._instances[0], # parent=test4_scope) # test6_scope = Scope( # instance=LineBufferDef._instances[0]._instances[0]._instances[0]._instances[0]._instances[1], # parent=test4_scope) # first_rb = LineBufferDef._instances[0]._instances[0]._instances[0]._instances[0]._instances[0]._instances[1] # delayed_buffer_of_first_shift_register = Scope( # instance=first_rb, # parent=test5_scope # ) # first_sipo = LineBufferDef._instances[0]._instances[0]._instances[0]._instances[0]._instances[0]._instances[0] # sipo_of_first_shift_register = Scope( # instance=first_sipo, # parent=test5_scope # ) # second_rb = LineBufferDef._instances[0]._instances[0]._instances[0]._instances[0]._instances[1]._instances[1] # delayed_buffer_of_second_shift_register = Scope( # instance=second_rb, # parent=test5_scope # ) # second_sipo = LineBufferDef._instances[0]._instances[0]._instances[0]._instances[0]._instances[1]._instances[0] # sipo_of_second_shift_register = Scope( # instance=second_sipo, # parent=test5_scope # ) # print("step {}: {}".format(quijibo, sim.get_value(LineBufferDef.valid, scope))) # print("input {}: {}".format(quijibo, sim.get_value(LineBufferDef.I, scope))) # print("lb output {}: {}".format(quijibo, sim.get_value(LineBufferDef._instances[0].O, scope))) # print("lb valid {}: {}".format(quijibo, sim.get_value(LineBufferDef._instances[0].valid, scope))) # print("first sipo input {}: {}".format(quijibo, sim.get_value(first_sipo.I, sipo_of_first_shift_register))) # print("first sipo output {}: {}".format(quijibo, sim.get_value(first_sipo.defn._instances[0].O[2], sipo_of_first_shift_register))) # print("first rb input {}: {}".format(quijibo, sim.get_value(first_sipo.defn._instances[1].I[0], delayed_buffer_of_first_shift_register))) # print("first rb CE {}: {}".format(quijibo, sim.get_value(first_sipo.defn._instances[1].CE, delayed_buffer_of_first_shift_register))) # print("first rb WE {}: {}".format(quijibo, sim.get_value(first_sipo.defn._instances[1].WE, delayed_buffer_of_first_shift_register))) # print("first rb output {}: {}".format(quijibo, sim.get_value(first_rb.O, delayed_buffer_of_first_shift_register))) # print("second sipo input {}: {}".format(quijibo, sim.get_value(second_sipo.I, sipo_of_second_shift_register))) # print("second sipo output {}: {}".format(quijibo, sim.get_value(second_sipo.defn._instances[0].O[2], sipo_of_second_shift_register))) # print("second rb input {}: {}".format(quijibo, sim.get_value(second_sipo.defn._instances[1].I[0], delayed_buffer_of_second_shift_register))) # print("second rb CE {}: {}".format(quijibo, sim.get_value(second_sipo.defn._instances[1].CE, delayed_buffer_of_second_shift_register))) # print("second rb WE {}: {}".format(quijibo, sim.get_value(second_sipo.defn._instances[1].WE, delayed_buffer_of_second_shift_register))) # print("first rb output {}: {}".format(quijibo, sim.get_value(first_rb.O, delayed_buffer_of_first_shift_register))) # # if len(LineBufferDef._instances) > 1: # # print("db input {}: {}".format(quijibo, sim.get_value(LineBufferDef._instances[1].I, scope))) # # print("db output {}: {}".format(quijibo, sim.get_value(LineBufferDef._instances[1].O, scope))) # print("output {}: {}".format(quijibo, sim.get_value(LineBufferDef.O, scope))) # print("\n") if sim.get_value(LineBufferDef.valid, scope): actual.append([ # Parallel output windows [ # Rows [ # Columns get_pixel(window_index, y, x) for x in range(window_x) ] for y in range(window_y) ] for window_index in range(parallelism) ]) sim.advance_cycle() sim.evaluate() for input_window in test_set: set_value(input_window) tick_sim_collect_outputs() # Wait for a little extra after the last input because the # line buffer may need a bit of extra time to emit the last # windows. extra_cycles = 16 + parameters.image_x * window_y + window_x for i in range(extra_cycles): if len(actual) >= len(expected): break tick_sim_collect_outputs() len_actual, len_expected = len(actual), len(expected) actual_parallelism = len(LineBufferDef.O) assert actual_parallelism == parallelism, \ f"Expected {parallelism} outputs per (valid) cycle, seem to " \ f"actually have {actual_parallelism}." assert len_actual >= len_expected, \ f"Got {len_actual} outputs (counts of valid asserts); expected " \ f"{len_expected} outputs.\n" \ f"Waited {extra_cycles} cycles after last input." print(parameters.as_kwargs()) fill_garbage_with_none(actual, expected) print('\x1b[31mActual: ', actual, '\n\x1b[34mExpected: ', expected, '\x1b[0m') assert actual == expected, "Outputs don't match expected values."