def sim_hdl_pi(Kp, Ki): plant = tf([1], [1, 10, 20]) config['sim/clk_freq'] = 1000 # seq = [0.] * 2 + [1.] * config['sim/clk_freq'] * 2 seq = [0.] * 2 + [1.] * 500 set_point = drv(t=Float, seq=seq) plant_out = set_point \ | hdl_pi_sys(Kp=Kp, Ki=Ki, plant=plant) find('/hdl_pi_sys/plant.x').producer | scope(title="PI Output") plant_out | scope(title="Plant Output") sim('/tools/home/tmp', timeout=len(seq))
def test_val_map(tmpdir, sim_cls): tin = Tuple['a':Uint[1], 'b':Uint[2], 'c':Uint[3], 'd':Uint[4]] tout = Tuple['f':Uint[1], 'g':Uint[3]] directed(drv(t=tin, seq=[(1, 2, 3, 4)] * 3), f=repack(t=tout, sim_cls=sim_cls, name_map={ 'f': 'a', 'g': 'c' }, val_map={'g': 2}), ref=[(1, 2)] * 3) sim(tmpdir)
def test_loop_state(lang): @gear async def test(din: Uint) -> b'din': i = Uint[3](0) async with din as d: while i != d: yield i yield i + 1 i += 1 directed(drv(t=Uint[4], seq=[4, 2]), f=test, ref=[0, 1, 1, 2, 2, 3, 3, 4, 0, 1, 1, 2]) cosim('/test', 'verilator', lang=lang) sim()
def svgen_cascade(xml_file, img_size, outdir): cascade_hw = CascadeHW(xml_file, img_size=img_size) din_t = Queue[Uint[8], 1] detected_addr, interrupt = cascade_classifier(din=drv(t=din_t, seq=[]), casc_hw=cascade_hw) detected_addr | shred interrupt | shred bind('debug/trace', []) hdlgen('/cascade_classifier', outdir=outdir, wrapper=True, copy_files=True) # print(list_hdl_files('/cascade_classifier', outdir='/tools/tmp/', language='sv')) # print("Copying svlib files to project") # copy_svlib() print("Replacing producer, consumer strings with master, slave") sed_intf(producer='master', consumer='slave')
def test_leave_looped(din_delay, dout_delay): @gear async def test(din: Bool) -> Bool: c = Bool(True) while c: async with din as c: if c: yield 0 else: yield 1 verif(drv(t=Bool, seq=[True, False, False, True]) | delay_rng(din_delay, din_delay), f=test(name='dut'), ref=test, delays=[delay_rng(dout_delay, dout_delay)]) cosim('/dut', 'verilator') sim()
def test_second_const_op(): @gear(hdl={'compile': True}) async def test(din) -> Uint[4]: async with din as d: yield d + 1 async with din as d: yield d + 2 async with din as d: yield d + 3 directed( drv(t=Uint[3], seq=[1, 2, 3]), f=test(__sim__='verilator'), ref=[2, 4, 6], ) sim(timeout=3)
def test_second_dif_type_const_op(): @gear(hdl={'compile': True}) async def test(din) -> Ufixp[5, 5]: async with din as d: yield d + Ufixp[4, 4](1) async with din as d: yield d + Ufixp[4, 4](2) async with din as d: yield d + Ufixp[4, 4](3) directed( drv(t=Uint[3], seq=[1, 2, 3]), f=test(__sim__='verilator'), ref=[2, 4, 6], ) sim()
def test_optional_loop_assign(din_delay, dout_delay): @gear async def test(din: Queue[Bool]) -> Bool: flag = False async for d, eot in din: if d: flag = True yield flag verif(drv(t=Queue[Bool], seq=[[True, False, False, True]]) | delay_rng(din_delay, din_delay), f=test(name='dut'), ref=test, delays=[delay_rng(dout_delay, dout_delay)]) cosim('/dut', 'verilator') sim()
def test_optional_loop(din_delay, dout_delay): @gear async def test(din: Uint[4]) -> Uint[4]: async with din as c: if c > 1: for i in range(2): yield i else: for i in range(3): yield i verif(drv(t=Uint[4], seq=[1, 2, 3, 4, 1, 2, 3, 4]) | delay_rng(din_delay, din_delay), f=test(name='dut'), ref=test, delays=[delay_rng(dout_delay, dout_delay)]) cosim('/dut', 'verilator') sim()
def test_basic_loop(din_delay, dout_delay): @gear async def test(din: Bool) -> Uint[4]: a = Uint[4](0) c = True while c: async with din as c: yield a a += 1 verif(drv(t=Bool, seq=[True, False, False, True]) | delay_rng(din_delay, din_delay), f=test(name='dut'), ref=test, delays=[delay_rng(dout_delay, dout_delay)]) cosim('/dut', 'verilator') sim()
def test_loop_after_async_with(din_delay, dout_delay): @gear async def test(din: Uint[4]) -> Uint[4]: async with din as d: yield 1 d = 0 while d < 3: async with din as d: yield 0 verif(drv(t=Uint[4], seq=[1, 2, 3, 4, 1, 2, 3, 4]) | delay_rng(din_delay, din_delay), f=test(name='dut'), ref=test, delays=[delay_rng(dout_delay, dout_delay)]) cosim('/dut', 'verilator') sim()
def test_double_loop_seq_explicit_split(din_delay, dout_delay): @gear async def test(din: Queue[Uint[4]]) -> Uint[5]: async for d, _ in din: yield d + 1 await clk() async for d, _ in din: yield d + 2 verif(drv(t=Queue[Uint[4]], seq=[[1, 2, 3] * 2] * 2) | delay_rng(din_delay, din_delay), f=test(name='dut'), ref=test, delays=[delay_rng(dout_delay, dout_delay)]) cosim('/dut', 'verilator') sim()
def test_cond_state(din_delay, dout_delay): @gear async def test(din: Uint[4]) -> Uint[4]: async with din as c: if c < 12: yield 1 yield 2 if c > 4: yield 3 verif(drv(t=Uint[4], seq=[2, 6, 10, 14]) | delay_rng(din_delay, din_delay), f=test(name='dut'), ref=test, delays=[delay_rng(dout_delay, dout_delay)]) cosim('/dut', 'verilator') sim()
def test_same_op(): @gear async def test(din) -> Uint[4]: async with din as d: yield d + d async with din as d: yield d + d async with din as d: yield d + d directed( drv(t=Uint[3], seq=[1, 2, 3]), f=test(__sim__='verilator'), ref=[2, 4, 6], ) sim(timeout=3)
def test_first_dif_type_const_op(): @gear async def test(din) -> Ufixp[5, 5]: async with din as d: yield Ufixp[4, 4](1) + d async with din as d: yield Ufixp[4, 4](2) + d async with din as d: yield Ufixp[4, 4](3) + d directed( drv(t=Uint[3], seq=[1, 2, 3]), f=test(__sim__='verilator'), ref=[2, 4, 6], ) sim()
def test_cond_2state_symetric(lang, din_delay, dout_delay): @gear async def test(din: Bool) -> Bool: async with din as d: if d: yield True yield d else: yield False yield not d directed(drv(t=Bool, seq=[True, False, True, False]) | delay_rng(din_delay, din_delay), f=test, ref=[True, True, False, True, True, True, False, True], delays=[delay_rng(dout_delay, dout_delay)]) cosim('/test', 'verilator', lang=lang) sim()
def test_qrange(din_delay, dout_delay): @gear async def test(stop: Integer) -> b'stop': cnt = stop.dtype(0) last: Bool async with stop as s: last = False while not last: last = cnt == s yield cnt cnt += 1 verif(drv(t=Uint[4], seq=[2, 4]) | delay_rng(din_delay, din_delay), f=test(name='dut'), ref=test, delays=[delay_rng(dout_delay, dout_delay)]) cosim('/dut', 'verilator') sim()
def test_double_loop_seq(din_delay, dout_delay): @gear async def test(din: Uint[4]) -> Uint[4]: c = Uint[4](0) while c[:1] == 0: async with din as c: yield c c = Uint[4](0) while c[:1] == 0: async with din as c: yield code(2 * c, Uint[4]) verif(drv(t=Uint[4], seq=[1, 2, 3, 4, 1, 2, 3, 4]) | delay_rng(din_delay, din_delay), f=test(name='dut'), ref=test, delays=[delay_rng(dout_delay, dout_delay)]) cosim('/dut', 'verilator') sim()
def test_cond_nested_loop_multistate(din_delay, dout_delay): @gear async def test(din: Queue[Bool]) -> Uint[4]: a = Uint[4](0) while a < 4: if a < 2: async for d in din: yield a # Influences above condition, but should not make a # difference while loop is running a += 1 a += 1 verif(drv(t=Queue[Bool], seq=[[True] * 4, [True], [True], [True] * 4]) | delay_rng(din_delay, din_delay), f=test(name='dut'), ref=test, delays=[delay_rng(dout_delay, dout_delay)]) cosim('/dut', 'verilator') sim()
def comp_pid_lti_comb_ref(Kp, Ki, Kd, Nfilt): plant = tf([1], [1, 10, 20]) config['sim/clk_freq'] = 1000 seq = [0.] * 2 + [1.] * config['sim/clk_freq'] set_point = drv(t=Float, seq=seq) plant_out = set_point \ | pid_lti_comb(Kp=Kp, Ki=Ki, Kd=Kd, Nfilt=Nfilt, plant=plant) plant_out | scope(title="Plant Output") ref_out = set_point \ | pid_lti_feedback(Kp=Kp, Ki=Ki, Kd=Kd, Nfilt=Nfilt, plant=plant) ref_out | scope(title="Continuous Reference") report = [] scoreboard(plant_out, ref_out, report=report, tolerance=2e-2) sim(timeout=len(seq))
def test_unfold_array(lang): @gear async def test(din: Array[Maybe, 'num']) -> b'Array[Uint[bitw(num-1)], num]': num = len(din.dtype) TIndex = Uint[bitw(num - 1)] data = Array[TIndex, num]() async with din as d: cnt = TIndex(0) for i in range(num): data[i] = cnt if d[i].ctrl: cnt += 1 yield data TMaybe = Maybe[Uint[4]] seq = [ (1, 2, 3, 4), (2, None, None, 3), (None, None, 1, 2), (1, 2, 3, None), (None, None, None, None), ] seq = [[TMaybe() if v is None else TMaybe.some(v) for v in arv] for arv in seq] ref = [ (0, 1, 2, 3), (0, 1, 1, 1), (0, 0, 0, 1), (0, 1, 2, 3), (0, 0, 0, 0), ] directed(drv(t=Array[TMaybe, 4], seq=seq), f=test, ref=ref) cosim('/test', 'verilator', lang=lang) sim()
def comp_pid_pg_comb_lti_comb(Kp, Ki, Kd, Nfilt): plant = tf([1], [1, 10, 20]) config['sim/clk_freq'] = 1000 seq = [0.] * 2 + [1.] * config['sim/clk_freq'] set_point = drv(t=Float, seq=seq) plant_out = set_point \ | pid_pg_comb(Kp=Kp, Ki=Ki, Kd=Kd, Nfilt=Nfilt, plant=plant) find('/pid_pg_comb/pid.x').producer | scope(title="PID Input") find('/pid_pg_comb/pid.dout').consumer | scope(title="PID Output") plant_out | scope(title="Plant Output") ref_out = set_point \ | pid_lti_comb(Kp=Kp, Ki=Ki, Kd=Kd, Nfilt=Nfilt, plant=plant) ref_out | scope(title="Continuous Reference") report = [] scoreboard(plant_out, ref_out, report=report, tolerance=2e-2) sim(timeout=len(seq))
def test_optional_loop_assign_complex(din_delay, dout_delay): @gear async def test(din: Queue) -> Uint[8]: max_el = din.dtype.data.min max_idx = Uint[8](0) cnt = Uint[8](0) async for d, eot in din: if d >= max_el: max_el = d max_idx = cnt cnt += 1 yield max_idx seq = list(range(4)) + list(range(4, 0, -1)) verif(drv(t=Queue[Uint[4]], seq=[seq, seq]) | delay_rng(din_delay, din_delay), f=test(name='dut'), ref=test, delays=[delay_rng(dout_delay, dout_delay)]) cosim('/dut', 'verilator') sim()
def run_matrix(impl, mat1, mat2, cols_per_row, col_only: bool = False): reg['trace/level'] = 0 reg['gear/memoize'] = False # Add one more dimension to the matrix to support input type for design mat1 = mat1.reshape(1, mat1.shape[0], mat1.shape[1]) mat2 = mat2.reshape(mat2.shape[0], 1, mat2.shape[1]) # configuration driving cfg = create_valid_cfg(cols_per_row, mat1) cfg_drv = drv(t=TCfg, seq=[cfg]) row_t = Queue[Array[Int[16], cfg['num_cols']]] mat1_drv = drv(t=Queue[row_t], seq=[mat1]) res_list = [] if col_only: # remove the extra dimension that was previously added since colum mult accepts mat2 = np.squeeze(mat2) # for columtn multiplication second operand needs to be only one row mat2_drv = drv(t=row_t, seq=[mat2]) res = column_multiplication(cfg_drv, mat1_drv, mat2_drv) # column multiplication returns result in a queue so flatening makes it a regular list collect(res | flatten, result=res_list) if impl == 'hw': cosim('/column_multiplication', 'verilator', outdir='/tmp/column_multiplication', rebuild=True, timeout=100) else: mat2_drv = drv(t=Queue[row_t], seq=[mat2]) res = matrix_multiplication(cfg_drv, mat1_drv, mat2_drv, cols_per_row=cols_per_row) collect(res, result=res_list) if impl == 'hw': cosim('/matrix_multiplication', 'verilator', outdir='/tmp/matrix_multiplication', rebuild=True, timeout=100) try: sim() # convert PG results into regular 'int' if col_only: pg_res = [int(el) for el in res_list] else: pg_res = [int(el) for row_chunk in res_list for el in row_chunk] # calculate reference NumPy resutls np_res = np.dot(np.squeeze(mat1), np.transpose(mat2.squeeze())) # reshape PG results into the same format as pg_res = np.array(pg_res).reshape(np_res.shape) sim_assert( np.equal(pg_res, np_res).all(), "Error in compatring results") log.info("\033[92m //==== PASS ====// \033[90m") except: # printing stack trace traceback.print_exc() log.info("\033[91m //==== FAILED ====// \033[90m")
def test_sqrt(sim_cls): drv(t=Ufixp[8, 8], seq=[0, 4, 64, 121]) \ | funclut(f=math.sqrt, precision=4, sim_cls=sim_cls) \ | check(ref=[0, 2, 8, 11]) sim()
def test_sin_signed(sim_cls): drv(t=Fixp[2, 16], seq=[math.pi/12*i for i in range(-6, 5)]) \ | funclut(f=math.sin, sim_cls=sim_cls) \ | check(ref=[math.sin(math.pi/12*i) for i in range(-6, 5)], cmp=lambda x, y: abs(x-y) <= 1) sim()
from pygears.lib import drv, check, rng, flatten, decouple from pygears.typing import Uint rng_vals = drv(t=Uint[4], seq=[6]) | rng | flatten rng_vals_incr = (rng_vals | decouple) + 1 rng_vals_incr | check(ref=[1, 2, 3, 4, 5, 6])
from pygears.lib import qdeal, check, drv from pygears.typing import Uint, Queue seq = [[1, 2], [3, 4], [5, 6], [7, 8]] din = drv(t=Queue[Uint[4], 2], seq=[seq]) do1, do2 = din | qdeal(num=2, lvl=1) do1 | check(ref=[[1, 2], [5, 6]]) do2 | check(ref=[[3, 4], [7, 8]])
from pygears.lib import drv, check, chop from pygears.typing import Uint, Queue drv(t=Queue[Uint[4]], seq=[list(range(10))]) \ | chop(size=4) \ | check(ref=[list(range(4)), list(range(4, 8)), list(range(8, 10))])
from pygears.lib import check, drv, flatten from pygears.typing import Uint, Queue seq = [[[0, 1], [10, 11]], [[100, 101], [110, 111]]] ref = [[0, 1, 10, 11], [100, 101, 110, 111]] drv(t=Queue[Uint[8], 3], seq=[seq]) \ | flatten \ | check(ref=[ref])