def bench_zig_zag(): tdut = zig_zag(inputs, outputs, clock, reset, N) tbclock = clock_driver(clock) tbrst = reset_on_start(reset, clock) print_sig = [ Signal(intbv(0, min=-2**output_bits, max=2**output_bits)) for _ in range(N**2) ] print_sig_1 = [ Signal(intbv(0, min=-2**output_bits, max=2**output_bits)) for _ in range(N**2) ] in_sigs = [ Signal(intbv(0, min=-2**output_bits, max=2**output_bits)) for _ in range(N**2) ] @instance def tbstim(): inputs.data_valid.next = True for i in range(samples): for j in range(N**2): in_sigs[j].next = inputs_rom[i * (N**2) + j] yield clock.posedge print_assign = assign_array(print_sig_1, outputs.out_sigs) input_assign = assign_array(inputs.out_sigs, in_sigs) @instance def monitor(): outputs_count = 0 yield outputs.data_valid.posedge yield delay(1) while (outputs_count != samples): for i in range(N**2): print_sig[i].next = expected_outputs_rom[outputs_count * (N**2) + i] yield delay(1) print("Expected Outputs") for i in range(N**2): print("%d " % print_sig[i]) print("Actual Outputs") for i in range(N**2): print("%d " % print_sig_1[i]) print("------------------------------") outputs_count += 1 yield clock.posedge raise StopSimulation return tdut, tbclock, tbstim, monitor, print_assign, input_assign, tbrst
def bench_zig_zag(): tdut = zig_zag(inputs, outputs, clock, reset, N) tbclock = clock_driver(clock) tbrst = reset_on_start(reset, clock) print_sig = [Signal(intbv(0, min=-2**output_bits, max=2**output_bits)) for _ in range(N**2)] print_sig_1 = [Signal(intbv(0, min=-2**output_bits, max=2**output_bits)) for _ in range(N**2)] in_sigs = [Signal(intbv(0, min=-2**output_bits, max=2**output_bits)) for _ in range(N**2)] @instance def tbstim(): inputs.data_valid.next = True for i in range(samples): for j in range(N**2): in_sigs[j].next = inputs_rom[i*(N**2) + j] yield clock.posedge print_assign = assign_array(print_sig_1, outputs.out_sigs) input_assign = assign_array(inputs.out_sigs, in_sigs) @instance def monitor(): outputs_count = 0 yield outputs.data_valid.posedge yield delay(1) while(outputs_count != samples): for i in range(N**2): print_sig[i].next = expected_outputs_rom[outputs_count * (N**2) + i] yield delay(1) print("Expected Outputs") for i in range(N**2): print("%d " % print_sig[i]) print("Actual Outputs") for i in range(N**2): print("%d " % print_sig_1[i]) print("------------------------------") outputs_count += 1 yield clock.posedge raise StopSimulation return tdut, tbclock, tbstim, monitor, print_assign, input_assign, tbrst
def zig_zag(inputs, outputs, clock, reset, N=8): """Zig-Zag Module This module performs the zig-zag reorderding. According to the zig-zag matrix the input list of signals is reordered. The inputs and the ouputs are parallel. The parameter N defines the size of the NxN block. Inputs: List of signals of a NxN block Outputs: Reordered list of signals of a NxN block Parameters: N = the size of the NxN block """ zig_zag_obj = zig_zag_scan(N) zig_zag_rom = tuple(zig_zag_obj.zig_zag_matrix) index = Signal(intbv(0, min=0, max=N**2)) output_sigs = [ Signal(intbv(0, min=-inputs.out_range, max=inputs.out_range)) for _ in range(N**2) ] input_sigs = [ Signal(intbv(0, min=-inputs.out_range, max=inputs.out_range)) for _ in range(N**2) ] @always_seq(clock.posedge, reset=reset) def zig_zag_assign(): if inputs.data_valid: for i in range(N**2): index = zig_zag_rom[i] output_sigs[int(index)].next = input_sigs[int(i)] outputs.data_valid.next = inputs.data_valid else: outputs.data_valid.next = False output_assignments = assign_array(outputs.out_sigs, output_sigs) input_assignments = assign_array(input_sigs, inputs.out_sigs) return zig_zag_assign, output_assignments, input_assignments
def zig_zag(inputs, outputs, clock, reset, N=8): """Zig-Zag Module This module performs the zig-zag reorderding. According to the zig-zag matrix the input list of signals is reordered. The inputs and the ouputs are parallel. The parameter N defines the size of the NxN block. Inputs: List of signals of a NxN block Outputs: Reordered list of signals of a NxN block Parameters: N = the size of the NxN block """ zig_zag_obj = zig_zag_scan(N) zig_zag_rom = tuple(zig_zag_obj.zig_zag_matrix) index = Signal(intbv(0, min=0, max=N**2)) output_sigs = [Signal(intbv(0, min =-inputs.out_range, max=inputs.out_range)) for _ in range(N**2)] input_sigs = [Signal(intbv(0, min =-inputs.out_range, max=inputs.out_range)) for _ in range(N**2)] @always_seq(clock.posedge, reset=reset) def zig_zag_assign(): if inputs.data_valid: for i in range(N**2): index = zig_zag_rom[i] output_sigs[int(index)].next = input_sigs[int(i)] outputs.data_valid.next = inputs.data_valid else: outputs.data_valid.next = False output_assignments =assign_array(outputs.out_sigs, output_sigs) input_assignments = assign_array(input_sigs, inputs.out_sigs) return zig_zag_assign, output_assignments, input_assignments
def bench_dct_2d(): tdut = dct_2d(inputs, outputs, clock, reset, fract_bits, output_bits, stage_1_prec, N) tbclk = clock_driver(clock) tbrst = reset_on_start(reset, clock) print_sig = [Signal(intbv(0, min=-2**output_bits, max=2**output_bits)) for _ in range(N**2)] print_sig_1 = [Signal(intbv(0, min=-2**output_bits, max=2**output_bits)) for _ in range(N**2)] @instance def tbstim(): yield reset.negedge inputs.data_valid.next =True for i in range(samples * (N**2)): inputs.data_in.next = inputs_rom[i] yield clock.posedge print_assign = assign_array(print_sig_1, outputs.out_sigs) @instance def monitor(): outputs_count = 0 while outputs_count != samples: yield clock.posedge if outputs.data_valid: for i in range(N**2): print_sig[i].next = expected_outputs_rom[outputs_count * (N**2) + i] yield delay(1) print("Expected Outputs") for i in range(N**2): print("%d " % print_sig[i]) print("Actual Outputs") for i in range(N**2): print("%d " % print_sig_1[i]) print("------------------------------") outputs_count += 1 raise StopSimulation return tdut, tbclk, tbstim, monitor, tbrst, print_assign
def dct_1d(input_interface, output_interface, clock, reset, num_fractional_bits=14, out_precision=10, N=8): """1D-DCT Module This module performs the 1D-DCT Transformation. It takes serially N inputs and outputs parallely the vector of N signals. The parameter num_fractional_bits defines how many bits will be used for the fixed point representation of the dct coefficient. The out_precision parameter defines how many bits will be used for the fixed point representation of the outputs signals. This module is the building block for the 2d-dct module. The input interface is the input_1d_1st_stage and the output interface is the output_interface. Inputs: data_in, data_valid, clock, reset Outputs: List of N signals: out_sigs, data_valid Parameters: num_fractional_bits, out_precision, N """ fract_bits = num_fractional_bits nbits = input_interface.nbits output_fract = out_precision increase_range = 1 mult_max_range = 2**(nbits + fract_bits + 1 + increase_range) coeff_range = 2**fract_bits a = fract_bits + output_fract + 1 b = fract_bits c = fract_bits - 1 mult_reg = [Signal(intbv(0, min=-mult_max_range, max=mult_max_range)) for _ in range(N)] adder_reg = [Signal(intbv(0, min=-mult_max_range, max=mult_max_range)) for _ in range(N)] coeffs = [Signal(intbv(0, min=-coeff_range, max=coeff_range)) for _ in range(N)] mux_flush = [Signal(intbv(0, min=-mult_max_range, max=mult_max_range)) for _ in range(N)] inputs_counter = Signal(intbv(0, min=0, max=N)) cycles_counter = Signal(intbv(0, min=0, max=N+4)) first_row_passed = Signal(bool(0)) data_in_reg = Signal(intbv(0, min=-2**nbits, max=2**nbits)) # coefficient rom dct_1d_obj = dct_1d_transformation(N) coeff_matrix = dct_1d_obj.dct_int_coeffs(fract_bits) coeff_rom = tuple_construct(coeff_matrix) output_sigs = [Signal(intbv(0, min=-2**output_fract, max=2**output_fract)) for _ in range(N)] @always_seq(clock.posedge, reset=reset) def input_reg(): """input register""" if input_interface.data_valid: data_in_reg.next = input_interface.data_in @always_seq(clock.posedge, reset=reset) def coeff_assign(): """coefficient assignment from rom""" if input_interface.data_valid: for i in range(N): coeffs[i].next = coeff_rom[i * N + int(inputs_counter)] @always_seq(clock.posedge, reset=reset) def mul_add(): """multiplication and addition""" if input_interface.data_valid: for i in range(N): mult_reg[i].next = data_in_reg * coeffs[i] adder_reg[i].next = mux_flush[i] + mult_reg[i] @always_comb def mux_after_adder_reg(): """after 8 inputs flush one of the inputs of the adder""" if cycles_counter == (N + 2) or (cycles_counter == (N - 1) and first_row_passed): for i in range(N): mux_flush[i].next = 0 else: for i in range(N): mux_flush[i].next = adder_reg[i] @always_seq(clock.posedge, reset=reset) def counters(): """inputs and cycles counter""" if input_interface.data_valid: if cycles_counter == (N + 2) or (cycles_counter == (N - 1) and first_row_passed): cycles_counter.next = 0 first_row_passed.next = True else: cycles_counter.next = cycles_counter + 1 if inputs_counter == N - 1: inputs_counter.next = 0 else: inputs_counter.next = inputs_counter + 1 @always_seq(clock.posedge, reset=reset) def outputs(): """rounding""" for i in range(N): output_sigs[i].next = adder_reg[i][a:b].signed() + adder_reg[i][c] if cycles_counter == N + 2 or (first_row_passed and cycles_counter == N - 1): output_interface.data_valid.next = True else: output_interface.data_valid.next = False # avoid verilog indexing error outputs_assignment = assign_array(output_interface.out_sigs,output_sigs) return (input_reg, outputs, counters, mul_add, coeff_assign, mux_after_adder_reg, outputs_assignment)