def I2S_Transmitter(left, right, load_left, load_right, sdata, ws, sclk, reset): """ I2S Transmitter. Left and right data is multiplexed by ws. Ws= 0 means left. Sdata will be changed on negedge of sclk. :param left: Left Data parallel input :param right: Right Data parallel input :param load_left: Load left data :param load_right: Load right data :param sdata: Serial data output :param ws: Word clock output :param sclk: Clock input :param reset: Reset input :return: """ left_buf, right_buf, left_right = create_signals(3, (left.min, left.max)) wsd, nwsd, wsp = create_signals(3) left_buffer = DataBuffer(left, load_left, wsp, nwsd, left_buf, sclk, reset) right_buffer = DataBuffer(right, load_right, wsp, wsd, right_buf, sclk, reset) ws_select = WordSelect(ws, wsd, nwsd, wsp, sclk) shifter = ShiftRegister(left_right, False, wsp, sdata, sclk, reset) @always_comb def buffed_or(): left_right.next = left_buf | right_buf return left_buffer, right_buffer, ws_select, shifter, buffed_or
def bench_async(): q, d = create_signals(2, 8) p_rst = create_signals(1) clock, reset = create_clock_reset(rst_active=False, rst_async=True) dffa_inst = ff.dff(clock, d, q, reset=reset) clock_gen = clocker(clock) @always(clock.negedge) def stimulus(): if reset and p_rst: assert d == q p_rst.next = reset d.next = randrange(2) @instance def reset_gen(): yield delay(5) reset.next = 1 while True: yield delay(randrange(500, 1000)) reset.next = 0 yield delay(randrange(80, 140)) reset.next = 1 return dffa_inst, clock_gen, stimulus, reset_gen
def convert_multiplier(): BITS = 35 a, b = create_signals(2, BITS, signed=True, delay=None) p = create_signals(1, 2 * BITS, signed=True, delay=None) clk, rst = create_clock_reset() toVHDL(mult.Multiplier35Bit, a, b, p, clk, rst)
def I2S_Receiver(sdata, ws, left, right, left_ready, right_ready, sclk, reset): buf = create_signals(1, (left.min, left.max)) wsd, nwsd, wsp = create_signals(3) ws_select = WordSelect(ws, wsd, nwsd, wsp, sclk) s2p = Serial2Parallel(sdata, wsp, buf, sclk) @always(sclk.posedge) def clocked_logic(): if reset: left.next = 0 right.next = 0 else: if nwsd and wsp: left.next = buf elif wsd and wsp: right.next = buf @always_comb def logic(): left_ready.next = not (nwsd and wsp) right_ready.next = not (wsd and wsp) return ws_select, s2p, clocked_logic, logic
def Serial2Parallel(sdata, start, dout, sclk): M = len(dout) assert M > 2 buf = create_signals(M) en = create_signals(M - 1) shift_msb = ff.dff_set(en[M - 2], False, start, sclk) buf_msb = ff.dffe(buf[M - 1], sdata, start, sclk) shifts = [ff.dff_reset(en[M - 3 - i], en[M - 2 - i], sclk, start) for i in range(M - 2)] bufs = [ff.dffe_rst(buf[M - 2 - i], sdata, en[M - 2 - i], sclk, start) for i in range(M - 1)] if dout.min < 0: @always(sclk.posedge) def logic(): if start: t = intbv(0, _nrbits=M) for i in range(M): t[i] = buf[i] dout.next = t.signed() else: @always(sclk.posedge) def logic(): if start: t = intbv(0, _nrbits=M) for i in range(M): t[i] = buf[i] dout.next = t return shift_msb, shifts, buf_msb, bufs, logic
def convert_transmitter(): left, right = create_signals(2, 32, signed=True, delay=None) # left, right = [Signal(intbv(0)[32:]) for _ in range(2)] load_left, load_right, sdata, ws, sclk, reset = create_signals(6, delay=None) toVHDL(I2S_Transmitter, left, right, load_left, load_right, sdata, ws, sclk, reset)
def convert_tx(): cs1, valid1, user1, cs2, valid2, user2, frame0, ce_word, ce_bit, \ ce_bp, sdata, clk, rst = create_signals(13) audio_ch1, audio_ch2 = create_signals(2, 24, signed=True) toVHDL(AES3_TX, audio_ch1, cs1, valid1, user1, audio_ch2, cs2, valid2, user2, frame0, ce_word, ce_bit, ce_bp, sdata, clk, rst)
def convert_receiver(): left, right = create_signals(2, 32, signed=True, delay=None) # left, right = [Signal(intbv(0)[32:]) for _ in range(2)] left_ready, right_ready, sdata, ws, sclk, reset = create_signals(6, delay=None) toVHDL(I2S_Receiver, sdata, ws, left, right, left_ready, right_ready, sclk, reset)
def bench_async(): q, d = create_signals(2, 8) p_rst = create_signals(1) clock, reset = create_clock_reset(rst_active=False, rst_async=True) dffa_inst = ff.dff_reset(q, d, clock, reset) clock_gen = clocker(clock) @always(clock.negedge) def stimulus(): if reset and p_rst: assert d == q p_rst.next = reset d.next = randrange(2) @instance def reset_gen(): yield delay(5) reset.next = 1 while True: yield delay(randrange(500, 1000)) reset.next = 0 yield delay(randrange(80, 140)) reset.next = 1 return dffa_inst, clock_gen, stimulus, reset_gen
def convert_receiver(): left, right = create_signals(2, 32, signed=True, delay=None) # left, right = [Signal(intbv(0)[32:]) for _ in range(2)] left_ready, right_ready, sdata, ws, sclk, reset = create_signals( 6, delay=None) toVHDL(I2S_Receiver, sdata, ws, left, right, left_ready, right_ready, sclk, reset)
def convert_rx(): din, valid1, user1, cs1, out_en, valid2, user2, cs2, parity_error, frame0, \ locked, clk, rst = create_signals(13) audio_ch1, audio_ch2 = create_signals(2, 24, signed=True) frames = create_signals(1, 8) toVHDL(AES3_RX_DEMUXED, din, audio_ch1, valid1, user1, cs1, out_en, audio_ch2, valid2, user2, cs2, parity_error, frames, frame0, locked, clk, rst)
def convert_three_port_multiplier(): BITS = 35 a, b, c, d, e, f = create_signals(6, BITS, signed=True, delay=None) load = create_signals(1, (0, 4)) clk_ena = create_signals(1) clk, rst = create_clock_reset() ab_rdy, cd_rdy, ef_rdy = create_signals(3) ab, cd, ef = create_signals(3, 2 * BITS, signed=True, delay=None) toVHDL(mult.ThreePortMultiplier35Bit, a, b, c, d, e, f, load, clk_ena, clk, rst, ab, ab_rdy, cd, cd_rdy, ef, ef_rdy)
def convert_addressable_multiplier(): BITS = 35 ADDRESSES = 3 a, b = create_signals(2, BITS, signed=True, delay=None) p = create_signals(1, 2 * BITS, signed=True, delay=None) address_in, address_out = create_signals(2, (0, ADDRESSES + 1), mod=True) ce = create_signals(1) clk, rst = create_clock_reset() toVHDL(mult.AddressableMultiplier35Bit, a, b, p, address_in, address_out, ce, clk, rst)
def bench(bus_width=4): assert bus_width > 2 sdata, start, sclk = create_signals(3) dout = create_signals(1, bus_width, signed=True) s2p = i2s.Serial2Parallel(sdata, start, dout, sclk) output_data = [randrange(-2 ** (bus_width - 1), 2 ** (bus_width - 1)) for _ in range(20)] input_data = [int_to_bit_list(output_data[i], bus_width, signed=True) for i in range(len(output_data))] clockgen = clocker(sclk) start_count = create_signals(1, (0, bus_width * 2)) start_gen = clockdiv(sclk.negedge, start, start_count, bus_width * 2 - 2, True) @instance def stimulus(): for i in range(len(input_data)): for j in range(len(input_data[i])): yield sclk.negedge sdata.next = input_data[i][j] if j == 0: yield start.posedge raise StopSimulation @instance def check(): # printstr = "{{start_count:>{busw}}} | {{sdata:>{busw}}} | {{dout:>{busw}}}" # printstr = printstr.format(busw=bus_width).format # print(printstr(start_count="sc", sdata="sd", dout="ou")) yield sclk.negedge i = 0 for _ in range(50): # print(printstr(start_count=start_count, sdata=int(sdata), # dout=binarystring(dout, prefix=None))) if start_count == 0: if i > 1: # i == 0 is the first load, data is ready at i == 2 assert dout == output_data[i - 2] i += 1 yield sclk.negedge raise StopSimulation # No asserts yet return s2p, clockgen, start_gen, stimulus, check
def bench(): ticks = 5 BITS = 35 MAX = 2**BITS // 2 MAXOUT = 2**(BITS * 2) // 2 a, b = create_signals(2, BITS, signed=True) pipeA, pipeB = [ create_signals(ticks, BITS, signed=True) for _ in range(2) ] p = create_signals(1, 2 * BITS, signed=True) clk, rst = create_signals(2) mult_inst = mult.Multiplier35Bit(a, b, p, clk, rst) clock_gen = clocker(clk) @instance def stimulus(): iA, iB, pA, pB = 0, 0, 1, 1 yield clk.negedge rst.next = False while True: yield clk.negedge a.next = randrange(-MAX, MAX) b.next = randrange(-MAX, MAX) pipeA[iA].next = a pipeB[iB].next = b iA = (iA + 1) % ticks iB = (iB + 1) % ticks if (p != pipeA[pA] * pipeB[pB]): f_a = float(a) f_b = float(b) f_p = float(p) f_pipeA = float(pipeA[pA]) f_pipeB = float(pipeB[pB]) print("{:5.4f}x{:5.4f} = {:5.4f}".format( f_a / float(MAX), f_b / float(MAX), (f_pipeA * f_pipeB) / float(MAXOUT)) + " but got {:5.4f}, error: {:5.4f}".format( f_p / float(MAXOUT), (f_pipeA * f_pipeB - f_p) / float(MAXOUT))) assert p == pipeA[iA] * pipeB[iB], \ "Difference: p - a * b = {}".format( bin(p - pipeA[iA] * pipeB[pB], 2 * BITS)) pA = (pA + 1) % ticks pB = (pB + 1) % ticks return mult_inst, clock_gen, stimulus
def bench(): ticks = 5 BITS = 35 MAX = 2 ** BITS // 2 MAXOUT = 2 ** (BITS * 2) // 2 a, b = create_signals(2, BITS, signed=True) pipeA, pipeB = [create_signals(ticks, BITS, signed=True) for _ in range(2)] p = create_signals(1, 2 * BITS, signed=True) clk, rst = create_signals(2) mult_inst = mult.Multiplier35Bit(a, b, p, clk, rst) clock_gen = clocker(clk) @instance def stimulus(): iA, iB, pA, pB = 0, 0, 1, 1 yield clk.negedge rst.next = False while True: yield clk.negedge a.next = randrange(-MAX, MAX) b.next = randrange(-MAX, MAX) pipeA[iA].next = a pipeB[iB].next = b iA = (iA + 1) % ticks iB = (iB + 1) % ticks if (p != pipeA[pA] * pipeB[pB]): f_a = float(a) f_b = float(b) f_p = float(p) f_pipeA = float(pipeA[pA]) f_pipeB = float(pipeB[pB]) print("{:5.4f}x{:5.4f} = {:5.4f}".format( f_a/float(MAX), f_b/float(MAX), (f_pipeA * f_pipeB)/float(MAXOUT)) + " but got {:5.4f}, error: {:5.4f}".format( f_p/float(MAXOUT), (f_pipeA * f_pipeB - f_p)/float(MAXOUT))) assert p == pipeA[iA] * pipeB[iB], \ "Difference: p - a * b = {}".format( bin(p - pipeA[iA] * pipeB[pB], 2 * BITS)) pA = (pA + 1) % ticks pB = (pB + 1) % ticks return mult_inst, clock_gen, stimulus
def bench(tests=1000, bus_width=24): assert bus_width > 2 bus_width = 24 load_left, load_right, sdata, ws, sclk, reset = create_signals(6) left, right = create_signals(2, bus_width, signed=True) transmitter = i2s.I2S_Transmitter(left, right, load_left, load_right, sdata, ws, sclk, reset) clockgen = clocker(sclk) ws_count = create_signals(1, (0, bus_width)) ws_gen = clockdiv(sclk.negedge, ws, ws_count, bus_width) MAX = 2 ** (bus_width - 1) @always(sclk.negedge) def left_right_gen(): if ws_count == 0 and not ws: right.next = randrange(-MAX, MAX) load_right.next = True load_left.next = False elif ws_count == 0 and ws: left.next = randrange(-MAX, MAX) load_left.next = True load_right.next = False @instance def check(): yield sclk.posedge reset.next = False for i in range(tests): yield sclk.posedge if ws_count == 0: # We start a new ws round but we still need to get the LSB # of the previous data stream if ws: assert left[0] == sdata else: assert right[0] == sdata else: if ws: assert right[bus_width - ws_count] == sdata else: assert left[bus_width - ws_count] == sdata raise StopSimulation return transmitter, clockgen, ws_gen, left_right_gen, check
def ShiftRegister(parallel_in, d, load, sdata, sclk, reset): buf = create_signals(1, (parallel_in.min, parallel_in.max)) M = len(parallel_in) if parallel_in.min < 0: @always(sclk.negedge) def logic(): if reset: buf.next = 0 elif load: buf.next = parallel_in else: buf.next = concat(buf[M - 1:0], d).signed() else: @always(sclk.negedge) def logic(): if reset: buf.next = 0 elif load: buf.next = parallel_in else: buf.next = concat(buf[M - 1:0], d) @always_comb def output_logic(): sdata.next = buf[M - 1] return logic, output_logic
def bench_clks(steps, master_clk): clk44, clk48, prev44, prev48 = create_signals(4) gen44 = generate_external_clock(clk44, 44100, master_clk) gen48 = generate_external_clock(clk48, 48000, master_clk) @instance def check_times(): cnt44, cnt48 = 0, 0 prev44.next = clk44 prev48.next = clk48 yield delay(1) for i in range(steps + 2): if prev44 != clk44 and clk44: cnt44 += 1 if prev48 != clk48 and clk48: cnt48 += 1 prev44.next = clk44 prev48.next = clk48 yield delay(1) print(cnt44, cnt48) raise StopSimulation return check_times, gen44, gen48
def WordSelect(ws, wsd, nwsd, wsp, sclk): """ :param ws: Word Select input :param wsd: Clocked word select :param nwsd: Clocked inverted word select :param wsp: Word Select pulse indicating a change in word select :param sclk: :return: """ wsdd = create_signals(1) @always(sclk.posedge) def logic(): wsd.next = ws nwsd.next = not ws wsdd.next = wsd @always_comb def out_logic(): wsp.next = wsd ^ wsdd return logic, out_logic
def AES_TX_ClockDivider(clk, biphase_enable, bit_enable, word_enable): clken_count = create_signals(1, 9, mod=True) @always(clk.posedge) def counting(): clken_count.next = clken_count + 1 @always_comb def biphase_clocker(): if clken_count[1:0] == 0: biphase_enable.next = 1 else: biphase_enable.next = 0 @always_comb def bit_clocker(): if clken_count[2:0] == 0: bit_enable.next = 1 else: bit_enable.next = 0 @always_comb def word_clocker(): if clken_count == 0: word_enable.next = 1 else: word_enable.next = 0 return counting, biphase_clocker, bit_clocker, word_clocker
def bench(tests=1000): M = 6 load_left, load_right, left_ready, right_ready, sdata, ws, sclk, reset = create_signals(8) left, right, left_out, right_out, left_check, right_check = [Signal(intbv(0,_nrbits=M)) for _ in range(6)] transmitter = i2s.I2S_Transmitter(left, right, load_left, load_right, sdata, ws, sclk, reset) receiver = i2s.I2S_Receiver(sdata, ws, left_out, right_out, left_ready, right_ready, sclk, reset) clockgen = clocker(sclk) ws_count = Signal(intbv(0, min=0, max=M)) ws_gen = clockdiv(sclk.negedge, ws, ws_count, M) @always(sclk.negedge) def left_right_gen(): if ws_count == 0 and not ws: right_check.next = right right.next = randrange(2 ** M) load_right.next = True load_left.next = False elif ws_count == 0 and ws: left_check.next = left left.next = randrange(2 ** M) load_left.next = True load_right.next = False @instance def check(): prev_left = True prev_right = True yield sclk.posedge reset.next = False for i in range(tests): # while True: yield sclk.posedge if ws_count == 0: # We start a new ws round but we still need to get the LSB of the previous data stream if ws: assert left[0] == sdata else: assert right[0] == sdata else: if ws: assert right[M - ws_count] == sdata else: assert left[M - ws_count] == sdata if left_ready ^ prev_left: assert left_out == left_check if right_ready ^ prev_right: assert right_out == right_check prev_left = left_ready prev_right = right_ready raise StopSimulation return transmitter, receiver, clockgen, ws_gen, left_right_gen, check
def bench(tests=1000): M = 6 load_left, load_right, left_ready, right_ready, sdata, ws, sclk, reset = create_signals(8) left, right, left_out, right_out, left_check, right_check = [Signal(intbv(0, _nrbits=M)) for _ in range(6)] transmitter = i2s.I2S_Transmitter(left, right, load_left, load_right, sdata, ws, sclk, reset) receiver = i2s.I2S_Receiver(sdata, ws, left_out, right_out, left_ready, right_ready, sclk, reset) clockgen = clocker(sclk) ws_count = Signal(intbv(0, min=0, max=M)) ws_gen = clockdiv(sclk.negedge, ws, ws_count, M) @always(sclk.negedge) def left_right_gen(): if ws_count == 0 and not ws: right_check.next = right right.next = randrange(2 ** M) load_right.next = True load_left.next = False elif ws_count == 0 and ws: left_check.next = left left.next = randrange(2 ** M) load_left.next = True load_right.next = False @instance def check(): prev_left = True prev_right = True yield sclk.posedge reset.next = False for i in range(tests): # while True: yield sclk.posedge if ws_count == 0: # We start a new ws round but we still need to get the LSB of the previous data stream if ws: assert left[0] == sdata else: assert right[0] == sdata else: if ws: assert right[M - ws_count] == sdata else: assert left[M - ws_count] == sdata if left_ready ^ prev_left: assert left_out == left_check if right_ready ^ prev_right: assert right_out == right_check prev_left = left_ready prev_right = right_ready raise StopSimulation return transmitter, receiver, clockgen, ws_gen, left_right_gen, check
def SharedMultiplier(clk, ce, rst, a_signals, b_signals, load, p_signals, p_rdys): assert len(a_signals) == len(b_signals) == len(p_signals) assert load.max >= len( a_signals ) + 1, "Make sure all signals can be loaded and one extra space for the empty load" assert len(a_signals[0]) == 35 assert len(p_signals[0]) == 70 mult_a, mult_b = create_signals(2, 35, signed=True) mult_out = create_signals(1, 2 * 35, signed=True) addr_in, addr_out = create_signals(2, 3) output_buffers = create_signals(len(p_signals), 2 * 35, signed=True) ready_buffers = create_signals(len(p_signals)) mult_inst = AddressableMultiplier35Bit(mult_a, mult_b, mult_out, addr_in, addr_out, ce, clk, rst) @always(clk.posedge) def load_data(): if load > 0: mult_a.next = a_signals[load - 1] mult_b.next = b_signals[load - 1] addr_in.next = load else: mult_a.next = 0 mult_b.next = 0 addr_in.next = 0 @always(clk.posedge) def clock_output(): for i in range(len(p_signals)): output_buffers[i].next = output_buffers[i] ready_buffers[i].next = False if addr_out == i + 1: output_buffers[i].next = mult_out ready_buffers[i].next = True @always_comb def set_output(): for i in range(len(p_signals)): p_signals[i].next = output_buffers[i] p_rdys[i].next = ready_buffers[i] return mult_inst, load_data, clock_output, set_output
def SharedMultiplier(a_signals, b_signals, load, ce, clk, rst, p_signals, p_rdys): assert len(a_signals) == len(b_signals) == len(p_signals) assert load.max >= len(a_signals) + 1, "Make sure all signals can be loaded and one extra space for the empty load" assert len(a_signals[0]) == 35 assert len(p_signals[0]) == 70 mult_a, mult_b = create_signals(2, 35, signed=True) mult_out = create_signals(1, 2 * 35, signed=True) addr_in, addr_out = create_signals(2, 3) output_buffers = create_signals(len(p_signals), 2 * 35, signed=True) ready_buffers = create_signals(len(p_signals)) mult_inst = AddressableMultiplier35Bit(mult_a, mult_b, mult_out, addr_in, addr_out, ce, clk, rst) @always(clk.posedge) def load_data(): if load > 0: mult_a.next = a_signals[load - 1] mult_b.next = b_signals[load - 1] addr_in.next = load else: mult_a.next = 0 mult_b.next = 0 addr_in.next = 0 @always(clk.posedge) def clock_output(): for i in range(len(p_signals)): output_buffers[i].next = output_buffers[i] ready_buffers[i].next = False if addr_out == i + 1: output_buffers[i].next = mult_out ready_buffers[i].next = True @always_comb def set_output(): for i in range(len(p_signals)): p_signals[i].next = output_buffers[i] p_rdys[i].next = ready_buffers[i] return mult_inst, load_data, clock_output, set_output
def bench(): BITS = 35 MAX = 2**BITS // 2 a, b = create_signals(2, BITS, signed=True) p = create_signals(1, 2 * BITS, signed=True) clk, rst = create_clock_reset() address_in, address_out = create_signals(2, 3, mod=True) pipeline = {i: (0, 0, 0, 0) for i in range(len(address_in))} # Check pipeline mult_inst = mult.AddressableMultiplier35Bit(a, b, p, address_in, address_out, clk, rst) clock_gen = clocker(clk) @instance def stimulus(): yield clk.negedge rst.next = False while True: yield clk.negedge a.next = randrange(-MAX, MAX) b.next = randrange(-MAX, MAX) address_in.next = address_in + 1 check_address, check_a, check_b, check_p = pipeline[int( address_out)] # print('-' * 20) # print(address_out, address_in) # print('-' * 20) # print(pipeline) # print('-' * 20) assert check_address == address_out and check_p == p pipeline[int(address_in)] = int(address_in), int(a), int( b), int(a * b) return mult_inst, clock_gen, stimulus
def bench(): serin, serout, clk = create_signals(3) dout = create_signals(1, 3) crc_poly = myhdl.intbv(0, _nrbits=4) crc_poly[:] = 11 clockgen = clocker(clk) crc_stream = check_crc_stream(serin, clk, crc_poly, dout) # Padded 1 bit to the front and 3 to the back input_stream = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 0, 0, 1, 1, 1, 0, 1, 1, 0, 0, 0, 0, 1, 1, 0, 1, 0, 0, 1, 1, 1, 0, 1, 1, 0, 0, 0, 0, 1, 1, 0, 1, 0, 0, 1, 1, 1, 0, 1, 1, 0, 0, 0, 0, 1, 1, 0, 1, 0, 0, 1, 1, 1, 0, 1, 1, 0, 0, 0, 0] @myhdl.instance def create_input(): i = 0 while True: yield clk.negedge i += 1 if i >= len(input_stream): raise myhdl.StopSimulation serin.next = input_stream[i] @myhdl.always(clk.posedge) def print_out(): if frame_counter == 0: print("ZERO") print("|{:^6}|{:^6}|{:^6}|".format(int(serin), myhdl.bin(dout, dout._nrbits), serout)) frame_counter = create_signals(1, (0, 16), mod=True) @myhdl.always(clk.posedge) def frame_counting(): frame_counter.next = frame_counter + 1 crc2 = check_crc_stream2(serin, serout, clk, crc_poly, frame_counter, 16) return clockgen, crc_stream, create_input, print_out, frame_counting, crc2
def bench(): q, d, clock = create_signals(3) dff_inst = ff.dff(clock, d, q) clock_gen = clocker(clock) @always(clock.negedge) def stimulus(): assert d.val == q.val, ("D ({}) != Q ({})".format(int(d), int(q))) d.next = randrange(2) return dff_inst, clock_gen, stimulus
def generate_clock_div(clk, divided, division=32): counter = create_signals(1, division) # Signal(intbv(0)[32:]) @always(clk.posedge) def clock_gen(): counter.next = counter + 1 if counter >= division: counter.next = counter - division divided.next = not divided return clock_gen
def p2s_msb(din, load, dout, clock, reset): """ Parallel to serial converter On load: load in din to buffer On every clock cycle shift buffer and output dout at upper or lower bound of buffer depending on MSB_FIRST :param din: :param load: :param dout: :param clock: :param reset: :return: """ # MSB_FIRST = True M = len(din) buf, nbuf = create_signals(2, (din.min, din.max)) @always_seq(clock.posedge, reset) def shift_reg(): if load: buf.next = din else: buf.next = nbuf @always_comb def input_logic(): dout.next = buf[M - 1] nbuf.next = concat(buf[M - 1:0], False) # @instance # def shift_reg(): # buf = intbv(0, min=din.min, max=din.max) # while True: # yield clock.posedge, reset.posedge # # if MSB_FIRST: # dout.next = buf[M - 1] # # else: # # dout.next = buf[0] # if load: # buf[:] = din # else: # # if MSB_FIRST: # buf[:] = concat(buf[M-1:0], False) # # buf[:] = buf[M - 1:0] << 1 # # else: # # buf[:] = concat(False, buf[M:1]) return shift_reg, input_logic
def bench(): q, d, clock = create_signals(3) # dff_inst = ff.dff(q, d, clock) dff_inst = dff(q, d, clock) clock_gen = clocker(clock) @always(clock.negedge) def stimulus(): assert d == q d.next = randrange(2) return dff_inst, clock_gen, stimulus
def generate_clock_enable(clk, enable, division=32): counter = create_signals(1, division) # Signal(intbv(0)[32:]) @always(clk.negedge) def clock_gen(): counter.next = counter + 1 enable.next = 0 if counter >= division: counter.next = counter - division enable.next = 1 return clock_gen
def Serial2Parallel(sdata, start, dout, sclk): M = len(dout) assert M > 2 buf = create_signals(M) en = create_signals(M - 1) shift_msb = ff.dff_set(en[M - 2], False, start, sclk) buf_msb = ff.dffe(buf[M - 1], sdata, start, sclk) shifts = [ ff.dff_reset(en[M - 3 - i], en[M - 2 - i], sclk, start) for i in range(M - 2) ] bufs = [ ff.dffe_rst(buf[M - 2 - i], sdata, en[M - 2 - i], sclk, start) for i in range(M - 1) ] if dout.min < 0: @always(sclk.posedge) def logic(): if start: t = intbv(0, _nrbits=M) for i in range(M): t[i] = buf[i] dout.next = t.signed() else: @always(sclk.posedge) def logic(): if start: t = intbv(0, _nrbits=M) for i in range(M): t[i] = buf[i] dout.next = t return shift_msb, shifts, buf_msb, bufs, logic
def check_crc_stream2(serin, serout, clk, crc_poly, frame_counter, bits_per_frame=None): """ Generate stream of data, from 0 till bits_per_frame - crc_poly._nrbits - 1 it is equal to the input, after that it is the remainder of the crc check. In frames == 0 to frames == len(crc_poly) output crc_err value. if bits_per_frame = None use frame_counter.max bits_per_frame = total nr bits per frame, bits_per_frame - len(crc_poly) - 1 = data_length """ lc = len(crc_poly) inp_buf = create_signals(0, lc) out_buf = create_signals(0, lc) @myhdl.always(clk.posedge) def buf_input(): if frame_counter < bits_per_frame - (lc - 1) and inp_buf[lc - 1] == 1: out_buf.next = inp_buf ^ crc_poly else: out_buf.next = inp_buf if frame_counter < bits_per_frame - (lc - 1): inp_buf.next = myhdl.concat(out_buf[lc - 1:], serin) elif frame_counter == 0: inp_buf.next = 0 else: inp_buf.next = out_buf[lc - 1:] << 1 @myhdl.always_comb def output_logic(): if frame_counter >= bits_per_frame - (lc - 1): serout.next = out_buf[lc - 2] else: serout.next = bool(serin) return buf_input, output_logic
def bench(): BITS = 35 MAX = 2 ** BITS // 2 a, b = create_signals(2, BITS, signed=True) p = create_signals(1, 2 * BITS, signed=True) clk, rst = create_clock_reset() address_in, address_out = create_signals(2, 3, mod=True) pipeline = {i: (0, 0, 0, 0) for i in range(len(address_in))} # Check pipeline mult_inst = mult.AddressableMultiplier35Bit(a, b, p, address_in, address_out, clk, rst) clock_gen = clocker(clk) @instance def stimulus(): yield clk.negedge rst.next = False while True: yield clk.negedge a.next = randrange(-MAX, MAX) b.next = randrange(-MAX, MAX) address_in.next = address_in + 1 check_address, check_a, check_b, check_p = pipeline[int(address_out)] # print('-' * 20) # print(address_out, address_in) # print('-' * 20) # print(pipeline) # print('-' * 20) assert check_address == address_out and check_p == p pipeline[int(address_in)] = int(address_in), int(a), int(b), int(a * b) return mult_inst, clock_gen, stimulus
def bench(): M = 16 d, load, sdata, sclk, reset = create_signals(5) p_in = create_signals(1, (0, M)) shifter = i2s.ShiftRegister(p_in, d, load, sdata, sclk, reset) clockgen = clocker(sclk) testData = [] pl = len(p_in) p = intbv(0, min=0, max=M) for i in range(M): p[:] = i testData.append((p[:], False, True, p[pl - 1])) for j in range(pl - 1): testData.append((p[:], False, False, p[pl - 2 - j])) @instance def stimulus(): yield sclk.posedge reset.next = False yield sclk.posedge for p, din, l, sd in testData: p_in.next = p d.next = din load.next = l yield sclk.posedge assert sd == sdata raise StopSimulation return shifter, clockgen, stimulus
def bench_sync(): q, d = create_signals(2, 8) p_rst = create_signals(1) clock, reset = create_clock_reset() dffa_inst = ff.dff_reset(q, d, clock, reset) clock_gen = clocker(clock) @always(clock.negedge) def stimulus(): if not p_rst: assert d == q # print("CLK DOWN | {} | {} | {} | {} | {} ".format(reset, p_rst, d, # q, clock)) d.next = randrange(2) @always(clock.posedge) def reset_buf_dly(): # print("CLK UP | {} | {} | {} | {} | {} ".format(reset, p_rst, d, # q, clock)) p_rst.next = reset @instance def reset_gen(): yield delay(5) reset.next = 0 while True: yield delay(randrange(500, 1000)) reset.next = 1 yield delay(randrange(80, 140)) reset.next = 0 return dffa_inst, clock_gen, stimulus, reset_gen, reset_buf_dly
def bench(): M = 8 load, dout_msb, dout_lsb = create_signals(3) clock, reset = create_clock_reset() din = Signal(intbv(0, min=0, max=2**M)) dut = p2s.p2s_msb(din, load, dout_msb, clock, reset) dut2 = p2s.p2s_lsb(din, load, dout_lsb, clock, reset) clockgen = clocker(clock) def input_gen(): for i in range(2**M): yield i @instance def input_switch(): yield clock.negedge a = input_gen() for i in range(2**M): din.next = next(a) for k in range(M): yield clock.negedge load.next = k == 0 @instance def check(): yield clock.negedge reset.next = False for j in range(2**M): yield load.negedge o_msb = intbv(0, min=din.min, max=din.max) o_lsb = intbv(0, min=din.min, max=din.max) for k in range(M): yield clock.negedge o_msb[M - 1 - k] = dout_msb o_lsb[k] = dout_lsb # print(j, o_msb, o_lsb) # assert j == o_msb == o_lsb raise StopSimulation return dut, dut2, clockgen, input_switch, check
def bench(): M = 8 load, dout_msb, dout_lsb = create_signals(3) clock, reset = create_clock_reset() din = Signal(intbv(0, min=0, max=2**M)) dut = p2s.p2s_msb(din, load, dout_msb, clock, reset) dut2 = p2s.p2s_lsb(din, load, dout_lsb, clock, reset) clockgen = clocker(clock) def input_gen(): for i in range(2 ** M): yield i @instance def input_switch(): yield clock.negedge a = input_gen() for i in range(2 ** M): din.next = next(a) for k in range(M): yield clock.negedge load.next = k == 0 @instance def check(): yield clock.negedge reset.next = False for j in range(2 ** M): yield load.negedge o_msb = intbv(0, min=din.min, max=din.max) o_lsb = intbv(0, min=din.min, max=din.max) for k in range(M): yield clock.negedge o_msb[M - 1 - k] = dout_msb o_lsb[k] = dout_lsb # print(j, o_msb, o_lsb) # assert j == o_msb == o_lsb raise StopSimulation return dut, dut2, clockgen, input_switch, check
def bench(): q, d, g = create_signals(3) latch_inst = ff.latch(q, d, g) @always(delay(7)) def dgen(): d.next = randrange(2) @always(delay(41)) def ggen(): g.next = randrange(2) @always(q.posedge, q.negedge) def qcheck(): assert g and q == d return latch_inst, dgen, ggen, qcheck
def convert_shared_multiplier(): # @TODO (michiel): This fails inputs = create_signals(6, 35, signed=True, delay=None) load = create_signals(1, 2, delay=None) p_sigs = create_signals(3, 2 * 35, signed=True, delay=None) p_rdys = create_signals(3, delay=None) ce = create_signals(1) clk, rst = create_clock_reset() left, right = create_signals(2, 32, signed=True, delay=None) toVHDL(mult.SharedMultiplier, inputs[:3], inputs[3:], load, ce, clk, rst, p_sigs, p_rdys)
def DataBuffer(parallel_in, load, wait, output_enable, dout, sclk, reset): buf = create_signals(1, (parallel_in.min, parallel_in.max)) @always(sclk.posedge) def logic(): if reset: buf.next = 0 elif (load and not wait and not output_enable): buf.next = parallel_in @always_comb def output_logic(): if output_enable: dout.next = buf else: dout.next = 0 return logic, output_logic
def benchEdgeDetect(tests=100): din, p_edge, n_edge, clock, reset = create_signals(5) dut = utils.EdgeDetect(din, p_edge, n_edge, clock, reset) clockgen = clocker(clock) test_stream = [] pos_stream = [] neg_stream = [] for i in range(tests): try: prev_test = test_stream[i - 1] except IndexError: prev_test = False current_test = random.randint(0, 1) p = bool(current_test and not prev_test) n = bool(not current_test and prev_test) test_stream.append(bool(current_test)) pos_stream.append(p) neg_stream.append(n) @instance def check(): yield clock.negedge reset.next = False for t, p, n in zip(test_stream, pos_stream, neg_stream): yield clock.negedge # print "t: %s, p: %s, n: %s" % (t, p, n) din.next = t yield clock.negedge # print "d: %s, p: %s, n: %s" % (din, p_edge, n_edge) assert p == p_edge assert n == n_edge raise StopSimulation return dut, clockgen, check