def test_color_translation_v2(): """ In the current test are tested the outputs of the rgb2ycbcr_v2 module with the outputs of a python color space conversion function """ samples, frac_bits, nbits = 8, 14, 8 pixel_bits, num_fractional_bits = nbits, frac_bits rgb, ycbcr = RGB(pixel_bits), YCbCr_v2(pixel_bits) clock = Signal(bool(0)) reset = ResetSignal(1, active=True, async=True) in_out_data = InputsAndOutputs(samples) in_out_data.initialize() @myhdl.block def bench_color_trans(): tbdut = rgb2ycbcr_v2(rgb, ycbcr, clock, reset, num_fractional_bits) tbclk = clock_driver(clock) @instance def tbstim(): yield pulse_reset(reset, clock) rgb.data_valid.next = True for i in range(samples): for j in range(3): # rgb signal assignment in the dut rgb.red.next = in_out_data.inputs['red'][i] rgb.green.next = in_out_data.inputs['green'][i] rgb.blue.next = in_out_data.inputs['blue'][i] rgb.color_mode.next = j yield clock.posedge @instance def monitor(): samples_count = 0 output_list = [] yield ycbcr.data_valid.posedge yield delay(1) while samples_count != samples: for i in range(3): output_list.append(int(ycbcr.data_out)) yield clock.posedge yield delay(1) print_results(in_out_data.expected_outputs, output_list, samples_count) output_list = [] samples_count += 1 raise StopSimulation return tbdut, tbclk, tbstim, monitor run_testbench(bench_color_trans)
def test_color_translation(): """ In the current test are tested the outputs of the rgb2ycbcr module with the outputs of a python color space conversion function """ samples, frac_bits, nbits = 50, 14, 8 pixel_bits, num_fractional_bits = nbits, frac_bits rgb, ycbcr = RGB(pixel_bits), YCbCr(pixel_bits) clock = Signal(bool(0)) reset = ResetSignal(1, active=True, async=True) in_out_data = InputsAndOutputs(samples) in_out_data.initialize() @myhdl.block def bench_color_trans(): tbdut = rgb2ycbcr(rgb, ycbcr, clock, reset, num_fractional_bits) tbclk = clock_driver(clock) @instance def tbstim(): yield pulse_reset(reset, clock) rgb.data_valid.next = True for i in range(samples): # rgb signal assignment in the dut rgb.red.next = in_out_data.inputs['red'][i] rgb.green.next = in_out_data.inputs['green'][i] rgb.blue.next = in_out_data.inputs['blue'][i] if ycbcr.data_valid == 1: for ycbcr_act, val in zip(('y', 'cb', 'cr'), (int(ycbcr.y), int(ycbcr.cb), int(ycbcr.cr))): in_out_data.actual_outputs[ycbcr_act].append(val) yield clock.posedge print_results(in_out_data.inputs, in_out_data.expected_outputs, in_out_data.actual_outputs) raise StopSimulation return tbdut, tbclk, tbstim run_testbench(bench_color_trans)
def test_color_translation(): """ In the current test are tested the outputs of the rgb2ycbcr module with the outputs of a python color space conversion function """ samples, frac_bits, nbits = 50, 14, 8 pixel_bits, num_fractional_bits = nbits, frac_bits rgb, ycbcr = RGB(pixel_bits), YCbCr(pixel_bits) clock = Signal(bool(0)) reset = ResetSignal(1, active=True, async=True) in_out_data = InputsAndOutputs(samples) in_out_data.initialize() @myhdl.block def bench_color_trans(): tbdut = rgb2ycbcr(rgb, ycbcr, clock, reset, num_fractional_bits) tbclk = clock_driver(clock) @instance def tbstim(): yield pulse_reset(reset, clock) rgb.data_valid.next = True for i in range(samples): # rgb signal assignment in the dut rgb.red.next = in_out_data.inputs['red'][i] rgb.green.next = in_out_data.inputs['green'][i] rgb.blue.next = in_out_data.inputs['blue'][i] if ycbcr.data_valid == 1: for ycbcr_act, val in zip( ('y', 'cb', 'cr'), (int(ycbcr.y), int(ycbcr.cb), int(ycbcr.cr))): in_out_data.actual_outputs[ycbcr_act].append(val) yield clock.posedge print_results(in_out_data.inputs, in_out_data.expected_outputs, in_out_data.actual_outputs) raise StopSimulation return tbdut, tbclk, tbstim run_testbench(bench_color_trans)
def test_dct_2d(): """2D-DCT MyHDL Test In this test is verified the correct behavior of the 2d-dct module """ samples, fract_bits, output_bits, stage_1_prec, N = 5, 14, 10, 10, 8 clock = Signal(bool(0)) reset = ResetSignal(1, active=True, async=True) inputs = input_interface() outputs = outputs_2d(output_bits, N) in_out_data = InputsAndOutputs(samples, N) in_out_data.initialize() @myhdl.block def bench_dct_2d(): tdut = dct_2d(inputs, outputs, clock, reset, fract_bits, stage_1_prec, output_bits, N) tbclock = clock_driver(clock) @instance def tbstim(): yield pulse_reset(reset, clock) inputs.data_valid.next = True for i in range(samples): for j in in_out_data.inputs[i]: for k in j: inputs.data_in.next = k yield clock.posedge @instance def monitor(): outputs_count = 0 while outputs_count != samples: yield clock.posedge yield delay(1) if outputs.data_valid: out_print(in_out_data.outputs[outputs_count], outputs.out_sigs, N) outputs_count += 1 raise StopSimulation return tdut, tbclock, tbstim, monitor run_testbench(bench_dct_2d)
def test_zig_zag(): """Zig Zag Scan MyHDL Test In this test is verified the correct behavior of the zig zag module """ samples, output_bits, N = 5, 10, 8 clock = Signal(bool(0)) reset = ResetSignal(1, active=True, async=True) inputs = outputs_2d(output_bits, N) outputs = outputs_2d(output_bits, N) in_out_data = InputsAndOutputs(samples, N, output_bits) in_out_data.initialize() @block def bench_zig_zag(): tdut = zig_zag(inputs, outputs, clock, reset, N) tbclock = clock_driver(clock) @instance def tbstim(): yield pulse_reset(reset, clock) inputs.data_valid.next = True for i in range(samples): for j in range(N**2): inputs.out_sigs[j].next = in_out_data.inputs[i][j] yield clock.posedge @instance def monitor(): outputs_count = 0 yield outputs.data_valid.posedge yield delay(1) while(outputs_count != samples): out_print(in_out_data.outputs[outputs_count], outputs.out_sigs, N) yield clock.posedge yield delay(1) outputs_count += 1 raise StopSimulation return tdut, tbclock, tbstim, monitor run_testbench(bench_zig_zag)
def test_zig_zag(): """Zig Zag Scan MyHDL Test In this test is verified the correct behavior of the zig zag module """ samples, output_bits, N = 5, 10, 8 clock = Signal(bool(0)) reset = ResetSignal(1, active=True, async=True) inputs = outputs_2d(output_bits, N) outputs = outputs_2d(output_bits, N) in_out_data = InputsAndOutputs(samples, N, output_bits) in_out_data.initialize() @block def bench_zig_zag(): tdut = zig_zag(inputs, outputs, clock, reset, N) tbclock = clock_driver(clock) @instance def tbstim(): yield pulse_reset(reset, clock) inputs.data_valid.next = True for i in range(samples): for j in range(N**2): inputs.out_sigs[j].next = in_out_data.inputs[i][j] yield clock.posedge @instance def monitor(): outputs_count = 0 yield outputs.data_valid.posedge yield delay(1) while (outputs_count != samples): out_print(in_out_data.outputs[outputs_count], outputs.out_sigs, N) yield clock.posedge yield delay(1) outputs_count += 1 raise StopSimulation return tdut, tbclock, tbstim, monitor run_testbench(bench_zig_zag)
def test_dct_1d(): samples, fract_bits, out_prec, N = 10, 14, 10, 9 clock = Signal(bool(0)) reset = ResetSignal(1, active=True, async=True) inputs = input_1d_1st_stage() outputs = output_interface(out_prec, N) in_out_data = InputsAndOutputs(samples, N) in_out_data.initialize() @myhdl.block def bench_dct_1d(): tdut = dct_1d(inputs, outputs, clock, reset, fract_bits, out_prec, N) tbclk = clock_driver(clock) @instance def tbstim(): yield pulse_reset(reset, clock) inputs.data_valid.next = True for i in range(samples): for j in range(N): inputs.data_in.next = in_out_data.inputs[i][j] yield clock.posedge @instance def monitor(): outputs_count = 0 while(outputs_count != samples): yield clock.posedge yield delay(1) if outputs.data_valid: # convert flat signal to array of signals out_print(in_out_data.outputs[outputs_count], outputs.out_sigs) outputs_count += 1 raise StopSimulation return tdut, tbclk, tbstim, monitor run_testbench(bench_dct_1d)
def test_entropycoder(): """We will test the functionality of entropy coder in this block""" # constants for size required and width of input data width = 12 size_data = (width-1).bit_length() clock = Signal(bool(0)) reset = ResetSignal(0, active=True, async=True) # input data to the block data_in = Signal(intbv(0)[(width+1):].signed()) # output data from the block size = Signal(intbv(0)[size_data:]) amplitude = Signal(intbv(0)[(width+1):].signed()) @block def bench_entropycoder(): inst = entropycoder(width, clock, reset, data_in, size, amplitude) inst_clock = clock_driver(clock) @instance def tbstim(): """stimulus generates inputs for entropy coder""" yield pulse_reset(reset, clock) for i in range(-2**(width-1), 2**(width-1), 1): data_in.next = i yield clock.posedge yield clock.posedge amplitude_ref, size_ref = entropy_encode(int(data_in)) # comparing with the data present in reference assert size == size_ref assert amplitude == amplitude_ref raise StopSimulation return tbstim, inst, inst_clock run_testbench(bench_entropycoder)
def test_block_buffer(): clock = Signal(bool(0)) reset = ResetSignal(0, active=1, async=False) pxl = PixelStream() bmem = ImageBlock(pxl, ) @myhdl.block def bench_block_buffers(): pxl.clock = clock tbdut = mdl_block_buffer(pxl, bmem) tbpxl = pxl.generate_stream() @always(delay(5)) def tbclk(): clock.next = not clock @instance def tbstim(): print("start simulation ...") reset.next = reset.active yield delay(33) reset.next = not reset.active yield delay(13) yield clock.posedge for ii in range(200): yield delay(1000) yield clock.posedge print("end simulation ...") raise StopSimulation return tbdut, tbpxl, tbclk, tbstim run_testbench(bench_block_buffers)
def test_rle(): """This test checks the functionality of the Run Length Encoder""" @block def bench_rle(): """bench to test the functionality of RLE""" # clock and reset signals clock = Signal(bool(0)) reset = ResetSignal(0, active=1, async=True) # color component class component = Component() assert isinstance(component, Component) # width of the input data width_data = 12 # width of the address register width_addr = 6 # width of the register to store size width_size = width_data.bit_length() # width to store the runlength width_runlength = 4 # input data stream into the register datastream = DataStream(width_data, width_addr) assert isinstance(datastream, DataStream) # connection between rlecore output bus and Double FIFO bufferdatabus = BufferDataBus(width_data, width_size, width_runlength) assert isinstance(bufferdatabus, BufferDataBus) # selects the color component, manages start and ready values rleconfig = RLEConfig() assert isinstance(rleconfig, RLEConfig) # instantiation for clock and rletop module inst = rlencoder(clock, reset, datastream, bufferdatabus, rleconfig) inst_clock = clock_driver(clock) @instance def tbstim(): """RLE input tests given here""" # reset the stimulus before sending data in yield pulse_reset(reset, clock) # write y1 component into 1st buffer bufferdatabus.buffer_sel.next = False yield clock.posedge yield write_block( clock, red_pixels_1, datastream, rleconfig, component.y1_space ) yield clock.posedge print ("============================") # read y1 component from 1st Buffer yield read_block(True, bufferdatabus, clock) # write y2 component into 2nd Buffer yield write_block( clock, red_pixels_2, datastream, rleconfig, component.y2_space ) yield clock.posedge print ("============================") # read y2 component from 2nd Buffer yield read_block(False, bufferdatabus, clock) # write cb Component into 1st Buffer yield write_block( clock, green_pixels_1, datastream, rleconfig, component.cb_space ) yield clock.posedge print ("=============================") # read cb component from 1st Buffer yield read_block(True, bufferdatabus, clock) # write cb Component into 2nd Buffer yield write_block( clock, green_pixels_2, datastream, rleconfig, component.cb_space ) yield clock.posedge print ("==============================") # read cb component from 2nd Buffer yield read_block(False, bufferdatabus, clock) # write cr Component into 1st Buffer yield write_block( clock, blue_pixels_1, datastream, rleconfig, component.cr_space ) yield clock.posedge print ("==============================") # read cr component from 1st Buffer yield read_block(True, bufferdatabus, clock) # write cr Component into 2nd Buffer yield write_block( clock, blue_pixels_2, datastream, rleconfig, component.cr_space ) yield clock.posedge print ("==============================") # read cr component from 1st Buffer yield read_block(False, bufferdatabus, clock) print ("==============================") # end of stream when sof asserts yield clock.posedge rleconfig.sof.next = True yield clock.posedge raise StopSimulation return tbstim, inst_clock, inst run_testbench(bench_rle)
def test_frontend(): """Frontend Part of the JPEG Encoder MyHDL Test In this test is verified the correct behavior of the frontend part of the endocer """ samples, N = 2, 8 clock = Signal(bool(0)) reset = ResetSignal(1, active=True, async=True) inputs = inputs_frontend_new() outputs = outputs_frontend_new() in_out_data = InputsAndOutputs(samples, N) in_out_data.initialize() @block def bench_frontend(): tdut = frontend_top_level_v2(inputs, outputs, clock, reset) tbclock = clock_driver(clock) @instance def tbstim(): yield pulse_reset(reset, clock) inputs.data_valid.next = True for i in range(samples): for n in range(3): for j in range(N): for k in range(N): inputs.red.next = in_out_data.inputs[i][0][j][k] inputs.green.next = in_out_data.inputs[i][1][j][k] inputs.blue.next = in_out_data.inputs[i][2][j][k] yield clock.posedge @instance def monitor(): samples_count = 0 outputs_count = 0 outputs_list = [] clock_cycle_counter = 0 while(outputs.data_valid == False): yield clock.posedge clock_cycle_counter += 1 while samples_count != samples: print("Processing Block %d" %(samples_count+1)) for i in range(3): while(outputs_count != 64): outputs_list.append(int(outputs.data_out)) outputs_count += 1 clock_cycle_counter += 1 yield clock.posedge out_print(in_out_data.outputs[samples_count], outputs_list, N, i) outputs_count = 0 outputs_list = [] samples_count += 1 print("Clock Cycles taken for the block conversion:", clock_cycle_counter) raise StopSimulation return tdut, tbclock, tbstim, monitor run_testbench(bench_frontend)
def test_huffman(): """This test checks the functionality of the Run Length Encoder""" # clock and reset signals clock = Signal(bool(0)) reset = ResetSignal(0, active=1, async=True) # width of the runlength width_runlength = 4 # width of the vli size width_size = 4 # width of the vli amplitude ref width_amplitude = 12 # width of address register width_addr = 6 # width of the output data width_packed_byte = 8 # image width width = 8 # image height height = 8 huffmandatastream = HuffmanDataStream( width_runlength, width_size, width_amplitude, width_addr) assert isinstance(huffmandatastream, HuffmanDataStream) bufferdatabus = HuffBufferDataBus(width_packed_byte) assert isinstance(bufferdatabus, HuffBufferDataBus) huffmancntrl = HuffmanCntrl() assert isinstance(huffmancntrl, HuffmanCntrl) # color component class component = Component() assert isinstance(component, Component) # image size class img_size = ImgSize(width, height) assert isinstance(img_size, ImgSize) # input fifo is empty rle_fifo_empty = Signal(bool(0)) @block def bench_huffman(): """bench to test the functionality of RLE""" inst = huffman(clock, reset, huffmancntrl, bufferdatabus, huffmandatastream, img_size, rle_fifo_empty) inst_clock = clock_driver(clock) @instance def tbstim(): """Huffman input tests given here""" # reset the stimulus before sending data in yield pulse_reset(reset, clock) bufferdatabus.buffer_sel.next = False # send y1 component into the module color = component.y1_space yield write_block(huffmandatastream, huffmancntrl, rle_fifo_empty, color, vli_test_y, runlength_test_y, vli_size_test_y, clock) print ("=======================================") # read y1 component from the double FIFO bufferdatabus.buffer_sel.next = True yield read_block(bufferdatabus, clock) print ("==============================") # send cb component into the module color = component.cb_space yield write_block(huffmandatastream, huffmancntrl, rle_fifo_empty, color, vli_test_cb, runlength_test_cb, vli_size_test_cb, clock) print ("==========================================") # read cb component from the double FIFO bufferdatabus.buffer_sel.next = False yield clock.posedge yield read_block(bufferdatabus, clock) print ("==============================") # send cr component into the module color = component.cr_space yield write_block(huffmandatastream, huffmancntrl, rle_fifo_empty, color, vli_test_cr, runlength_test_cr, vli_size_test_cr, clock) print ("============================") # read cr component from the double FIFO bufferdatabus.buffer_sel.next = True yield clock.posedge yield read_block(bufferdatabus, clock) print ("==============================") yield toggle_signal(huffmancntrl.sof, clock) raise StopSimulation return tbstim, inst_clock, inst run_testbench(bench_huffman)
def test_backend(): """ We will test the functionality of entropy coder in this block constants: width_data : width of the input data size_data : size required to store the data width_addr : width of the address """ # width of the input data width_data = 12 write_addr = 7 # clock and reset signals clock = Signal(bool(0)) reset = ResetSignal(0, active=True, async=True) # declaration of input signal data_in = Signal(intbv(0)[width_data:]) write_addr = Signal(modbv(0)[7:]) ready = Signal(bool(0)) data_out = Signal(intbv(0)[width_data:]) valid_data = Signal(bool(0)) start_block = Signal(bool(0)) addr = Signal(intbv(0)[24:]) num_enc_bytes = Signal(intbv(0)[24:]) @block def bench_backend(): """This bench is used to test the functionality""" # instantiate module and clock inst = backend(clock, reset, start_block, data_in, write_addr, valid_data, data_out, ready, addr, num_enc_bytes) inst_clock = clock_driver(clock) @instance def tbstim(): """stimulus generates inputs for entropy coder""" # reset the module output_model = [0]*64 yield pulse_reset(reset, clock) # write Y data into input buffer valid_data.next = True yield clock.posedge write_addr.next = 64 for i in range(64): data_in.next = i % 25 yield clock.posedge write_addr.next = write_addr + 1 valid_data.next = False yield clock.posedge for _ in range(35): yield clock.posedge # start the blocks yield toggle_signal(start_block, clock) # write Cb data into input buffer valid_data.next = True yield clock.posedge for i in range(64): data_in.next = i % 16 yield clock.posedge write_addr.next = write_addr + 1 valid_data.next = False yield clock.posedge while not ready: yield clock.posedge yield toggle_signal(start_block, clock) # write Cr data into input buffer valid_data.next = True yield clock.posedge for i in range(64): data_in.next = i % 47 yield clock.posedge write_addr.next = write_addr + 1 valid_data.next = False yield clock.posedge while not ready: yield clock.posedge yield toggle_signal(start_block, clock) # write Y data into input buffer valid_data.next = True yield clock.posedge for i in range(64): data_in.next = i % 28 yield clock.posedge write_addr.next = write_addr + 1 valid_data.next = False yield clock.posedge while not ready: yield clock.posedge yield toggle_signal(start_block, clock) # write Cb data into input buffer valid_data.next = True yield clock.posedge for i in range(64): data_in.next = i % 40 index = int(addr) output_model[index] = int(data_out) yield clock.posedge write_addr.next = write_addr + 1 valid_data.next = False yield clock.posedge yield toggle_signal(start_block, clock) # write Cr data into input buffer valid_data.next = True yield clock.posedge for i in range(64): data_in.next = i % 31 index = int(addr) output_model[index] = int(data_out) yield clock.posedge write_addr.next = write_addr + 1 valid_data.next = False yield clock.posedge while not ready: yield clock.posedge yield toggle_signal(start_block, clock) while not ready: index = int(addr) output_model[index] = int(data_out) yield clock.posedge yield toggle_signal(start_block, clock) while not ready: index = int(addr) output_model[index] = int(data_out) yield clock.posedge yield toggle_signal(start_block, clock) while not ready: index = int(addr) output_model[index] = int(data_out) yield clock.posedge yield toggle_signal(start_block, clock) while not ready: index = int(addr) output_model[index] = int(data_out) yield clock.posedge print ("===================") for i in range(addr): print ("outputs_hdl %d" % output_model[i]) print ("======================") # get outputs from reference values output_ref = [] output_ref = backend_soft() for i in range(len(output_ref)): print ("outputs_soft %d" % int(output_ref[i], 2)) print ("===========================") # compare reference and HDL outputs for i in range(len(output_ref)): assert int(output_ref[i], 2) == output_model[i] raise StopSimulation return tbstim, inst, inst_clock run_testbench(bench_backend)
def test_doublebuffer(): """The functionality of Double Buffer is tested here""" @block def bench_doublebuffer(): """This bench is used to send test cases into module""" # instantiation of clock and reset clock = Signal(bool(0)) reset = ResetSignal(0, active=1, async=True) # buffer selection port instantiation buffer_sel = Signal(bool(0)) # input data width and depth of FIFO(double) width_data = 20 width_depth = 64 # instantiation of FIFOBus, clock and rledoublefifo dfifo_bus = FIFOBus(width=width_data) inst = doublefifo( clock, reset, dfifo_bus, buffer_sel, depth=width_depth) inst_clock = clock_driver(clock) @instance def tbstim(): """write data inputs to double buffer""" print("start simulation") # disable read and write dfifo_bus.write.next = False dfifo_bus.read.next = False # reset before sending data yield pulse_reset(reset, clock) # check if FIFO is empty assert dfifo_bus.empty # select first buffer buffer_sel.next = False yield clock.posedge # write first data into double buffer dfifo_bus.write.next = True # convert signed number to unsigned dfifo_bus.write_data.next = -1 and 0xFF yield clock.posedge dfifo_bus.write.next = False yield clock.posedge assert dfifo_bus.empty # write data into double buffer dfifo_bus.write.next = True dfifo_bus.write_data.next = 0xA1 yield clock.posedge dfifo_bus.write.next = False yield clock.posedge assert dfifo_bus.empty # write data into rle double buffer dfifo_bus.write.next = True dfifo_bus.write_data.next = 0x11 yield clock.posedge dfifo_bus.write.next = False yield clock.posedge # write data into rle double buffer dfifo_bus.write.next = True dfifo_bus.write_data.next = 0x101 yield clock.posedge dfifo_bus.write.next = False yield clock.posedge # write data into rle double buffer for test_cases in range(64): if test_cases < 28: buffer_sel.next = False yield clock.posedge else: buffer_sel.next = True yield clock.posedge dfifo_bus.write.next = True dfifo_bus.write_data.next = test_cases yield clock.posedge dfifo_bus.write.next = False yield clock.posedge # read data from rle double buffer dfifo_bus.read.next = True yield clock.posedge assert dfifo_bus.read_data and -1 == -1 dfifo_bus.read.next = False buffer_sel.next = True yield clock.posedge # read data from rle double buffer dfifo_bus.read.next = True yield clock.posedge assert dfifo_bus.read_data == 0xA1 dfifo_bus.read.next = False buffer_sel.next = True yield clock.posedge # read data from rle double buffer dfifo_bus.read.next = True yield clock.posedge assert dfifo_bus.read_data == 0x11 dfifo_bus.read.next = False buffer_sel.next = True yield clock.posedge # read data from rle double buffer dfifo_bus.read.next = True yield clock.posedge assert dfifo_bus.read_data == 0x101 dfifo_bus.read.next = False # read data from rle double buffer for test_cases in range(64): if test_cases < 28: buffer_sel.next = True yield clock.posedge else: buffer_sel.next = False yield clock.posedge dfifo_bus.read.next = True yield clock.posedge assert dfifo_bus.read_data == test_cases dfifo_bus.read.next = False yield clock.posedge assert dfifo_bus.empty raise StopSimulation return inst, inst_clock, tbstim run_testbench(bench_doublebuffer)
def test_rle(): """This test checks the functionality of the Run Length Encoder""" @block def bench_rle(): clock = Signal(bool(0)) reset = ResetSignal(0, active=1, async=True) # constants for input, runlength, size width width = 6 constants = Constants(width_addr=width, width_data=12, max_write_cnt=63, rlength=4, size=width.bit_length()) pixel = Pixel() # interfaces to the rle module # input to the rle core and start signals sent from here indatastream = InDataStream(constants.width_data) # signals generated by the rle core bufferdatabus = BufferDataBus( constants.width_data, constants.size, constants.rlength) # selects the color component, manages address values rleconfig = RLEConfig(constants.max_write_cnt.bit_length()) # rle double buffer constants width_dbuf = constants.width_data + constants.size + constants.rlength dfifo_const = Constants(width=width_dbuf, depth=constants.max_write_cnt + 1) # instantiation for clock and rletop module inst = rlencoder( dfifo_const, constants, reset, clock, indatastream, bufferdatabus, rleconfig ) inst_clock = clock_driver(clock) @instance def tbstim(): # reset the stimulus before sending data in yield pulse_reset(reset, clock) # write Y1 component into 1st buffer bufferdatabus.buffer_sel.next = False yield clock.posedge yield write_block( clock, red_pixels_1, indatastream, rleconfig, pixel.Y1 ) yield clock.posedge print("============================") # read Y1 component from 1st Buffer yield read_block(True, bufferdatabus, clock) # write Y2 component into 2nd Buffer yield write_block( clock, red_pixels_2, indatastream, rleconfig, pixel.Y2 ) yield clock.posedge print("============================") # read Y2 component from 2nd Buffer yield read_block(False, bufferdatabus, clock) # write Cb Component into 1st Buffer yield write_block( clock, green_pixels_1, indatastream, rleconfig, pixel.Cb ) yield clock.posedge print("=============================") # read Cb component from 1st Buffer yield read_block(True, bufferdatabus, clock) # write Cb Component into 2nd Buffer yield write_block( clock, green_pixels_2, indatastream, rleconfig, pixel.Cb ) yield clock.posedge print("==============================") # read Cb component from 2nd Buffer yield read_block(False, bufferdatabus, clock) # write Cr Component into 1st Buffer yield write_block( clock, blue_pixels_1, indatastream, rleconfig, pixel.Cr ) yield clock.posedge print("==============================") # read Cr component from 1st Buffer yield read_block(True, bufferdatabus, clock) # write Cr Component into 2nd Buffer yield write_block( clock, blue_pixels_2, indatastream, rleconfig, pixel.Cr ) yield clock.posedge print("==============================") # read Cr component from 1st Buffer yield read_block(False, bufferdatabus, clock) print("==============================") # end of stream when sof asserts yield clock.posedge rleconfig.sof.next = True yield clock.posedge raise StopSimulation return tbstim, inst_clock, inst run_testbench(bench_rle)
def test_quantizer(): """The functionality of the module is tested here""" # declare clock and reset clock = Signal(bool(0)) reset = ResetSignal(0, active=True, async=True) # width of the input data width_data = 12 # width of input address width_addr = 6 # bus declaration for the module quanto_datastream = QuantIODataStream(width_data, width_addr) assert isinstance(quanto_datastream, QuantIODataStream) quanti_datastream = QuantIODataStream(width_data, width_addr) assert isinstance(quanti_datastream, QuantIODataStream) quant_ctrl = QuantCtrl() assert isinstance(quant_ctrl, QuantCtrl) # declare constants max_addr = 2**width_addr component = Component() assert isinstance(component, Component) @block def bench_quant(): """instantiation of quantizer module and clock""" inst = quantizer(clock, reset, quanti_datastream, quant_ctrl, quanto_datastream) inst_clock = clock_driver(clock) @instance def tbstim(): """we send test cases here""" # reset the block before processing yield pulse_reset(reset, clock) # select Cb or Cr component color = component.y2_space # process Cb or Cr component yield quant_top_block_process( clock, quant_ctrl, color, quanto_datastream, quanti_datastream, quant_in, quant_rom, max_addr, 1) print ("===============================================") # select Y1 or Y2 component color = component.cr_space # process Cb or Cr component yield quant_top_block_process( clock, quant_ctrl, color, quanto_datastream, quanti_datastream, quant_in, quant_rom, max_addr, 1) raise StopSimulation return tbstim, inst, inst_clock run_testbench(bench_quant)
def test_huffman(): """This test checks the functionality of the Run Length Encoder""" # clock and reset signals clock = Signal(bool(0)) reset = ResetSignal(0, active=1, async=True) # width of the runlength width_runlength = 4 # width of the vli size width_size = 4 # width of the vli amplitude ref width_amplitude = 12 # width of address register width_addr = 6 # width of the output data width_packed_byte = 8 # image width width = 8 # image height height = 8 huffmandatastream = HuffmanDataStream(width_runlength, width_size, width_amplitude, width_addr) assert isinstance(huffmandatastream, HuffmanDataStream) bufferdatabus = HuffBufferDataBus(width_packed_byte) assert isinstance(bufferdatabus, HuffBufferDataBus) huffmancntrl = HuffmanCntrl() assert isinstance(huffmancntrl, HuffmanCntrl) # color component class component = Component() assert isinstance(component, Component) # image size class img_size = ImgSize(width, height) assert isinstance(img_size, ImgSize) # input fifo is empty rle_fifo_empty = Signal(bool(0)) @block def bench_huffman(): """bench to test the functionality of RLE""" inst = huffman(clock, reset, huffmancntrl, bufferdatabus, huffmandatastream, img_size, rle_fifo_empty) inst_clock = clock_driver(clock) @instance def tbstim(): """Huffman input tests given here""" # reset the stimulus before sending data in yield pulse_reset(reset, clock) bufferdatabus.buffer_sel.next = False # send y1 component into the module color = component.y1_space yield write_block(huffmandatastream, huffmancntrl, rle_fifo_empty, color, vli_test_y, runlength_test_y, vli_size_test_y, clock) print("=======================================") # read y1 component from the double FIFO bufferdatabus.buffer_sel.next = True yield read_block(bufferdatabus, clock) print("==============================") # send cb component into the module color = component.cb_space yield write_block(huffmandatastream, huffmancntrl, rle_fifo_empty, color, vli_test_cb, runlength_test_cb, vli_size_test_cb, clock) print("==========================================") # read cb component from the double FIFO bufferdatabus.buffer_sel.next = False yield clock.posedge yield read_block(bufferdatabus, clock) print("==============================") # send cr component into the module color = component.cr_space yield write_block(huffmandatastream, huffmancntrl, rle_fifo_empty, color, vli_test_cr, runlength_test_cr, vli_size_test_cr, clock) print("============================") # read cr component from the double FIFO bufferdatabus.buffer_sel.next = True yield clock.posedge yield read_block(bufferdatabus, clock) print("==============================") yield toggle_signal(huffmancntrl.sof, clock) raise StopSimulation return tbstim, inst_clock, inst run_testbench(bench_huffman)
def test_rle_core(): """functionality of rle core tested here""" # instantiation of clock and reset clock = Signal(bool(0)) reset = ResetSignal(0, active=1, async=True) # instantiation of component select block component = Component() # input data width into the rlecore width_data = 12 # address data width width_addr = 6 # number of bits required to store amplitude width_size = width_data.bit_length() # maximum counter value max_addr_cnt = (2**(width_addr)) - 1 # maximum width of the runlength value width_runlength = 4 # input bus to the rlecore datastream = DataStream(width_data, width_addr) assert isinstance(datastream, DataStream) # symbols generated by the rle core rlesymbols = RLESymbols(width_data, width_size, width_runlength) assert isinstance(rlesymbols, RLESymbols) # selects the color component, manages address values rleconfig = RLEConfig() assert isinstance(rleconfig, RLEConfig) @block def bench_rle_core(): """The RLE Core is tested in this block""" # instantiation of the rle core inst = rle( clock, reset, datastream, rlesymbols, rleconfig ) # clock instantiation inst_clock = clock_driver(clock) @instance def tbstim(): """Test inputs given here""" # reset before sending data yield pulse_reset(reset, clock) # components of type y1 or y2 processed yield block_process( clock, red_pixels_1, datastream, rlesymbols, rleconfig, component.y1_space, max_count=max_addr_cnt ) print ("======================") # components of type y1 or y2 processed yield block_process( clock, red_pixels_2, datastream, rlesymbols, rleconfig, component.y2_space, max_count=max_addr_cnt ) print ("=====================") # components of type cb processes yield block_process( clock, green_pixels_1, datastream, rlesymbols, rleconfig, component.cb_space, max_count=max_addr_cnt ) print ("=====================") # components od type cb processed yield block_process( clock, green_pixels_2, datastream, rlesymbols, rleconfig, component.cb_space, max_count=max_addr_cnt ) print ("=====================") # components of type cr processed yield block_process( clock, blue_pixels_1, datastream, rlesymbols, rleconfig, component.cr_space, max_count=max_addr_cnt ) print ("=====================") # components of type cr processed yield block_process( clock, blue_pixels_2, datastream, rlesymbols, rleconfig, component.cr_space, max_count=max_addr_cnt ) print ("=====================") # start of new frame asserts rleconfig.sof.next = True yield clock.posedge raise StopSimulation return tbstim, inst_clock, inst run_testbench(bench_rle_core)
def test_quantizer_core(): """The functionality of the module is tested here""" # clock and reset signals declared here clock = Signal(bool(0)) reset = ResetSignal(0, active=True, async=True) # width of the input data width_data = 12 # width of input address width_addr = 6 # bus signals declaration for the module quant_output_stream = QuantDataStream(width_data) assert isinstance(quant_output_stream, QuantDataStream) quant_input_stream = QuantDataStream(width_data) assert isinstance(quant_input_stream, QuantDataStream) color_component = Signal(intbv(0)[3:]) max_addr = 2**width_addr # component declaration component = Component() assert isinstance(component, Component) @block def bench_quant_core(): """instantiation of quantizer core module and clock signals""" inst = quantizer_core(clock, reset, quant_output_stream, quant_input_stream, color_component) inst_clock = clock_driver(clock) @instance def tbstim(): """We send the inputs from here""" # reset the module before sending inputs yield pulse_reset(reset, clock) # select Cb or Cr component color = component.y2_space # process the component selected yield quant_block_process(clock, color_component, color, quant_in, quant_rom, quant_input_stream, quant_output_stream, max_addr) yield clock.posedge print("====================================") # select Y1 or Y2 component color = component.cb_space # process the component selected yield quant_block_process(clock, color_component, color, quant_in, quant_rom, quant_input_stream, quant_output_stream, max_addr) yield clock.posedge raise StopSimulation return tbstim, inst, inst_clock run_testbench(bench_quant_core)
def test_entropycoder(): """ We will test the functionality of entropy coder in this block constants: width_data : width of the input data size_data : size required to store the data """ # width of the input data width_data = 12 # size required to store input data size_data = (width_data-1).bit_length() # clock and reset signals clock = Signal(bool(0)) reset = ResetSignal(0, active=True, async=True) # declaration of input signal data_in = Signal(intbv(0)[width_data:].signed()) # declaration of output signals size = Signal(intbv(0)[size_data:]) amplitude = Signal(intbv(0)[width_data:].signed()) @block def bench_entropycoder(): """This bench is used to test the functionality""" # instantiate module and clock inst = entropycoder(clock, reset, data_in, size, amplitude) inst_clock = clock_driver(clock) @instance def tbstim(): """stimulus generates inputs for entropy coder""" # reset the module yield pulse_reset(reset, clock) # send input test cases into the module for i in range(-2**(width_data-1)+1, 2**(width_data-1), 1): data_in.next = i yield clock.posedge yield clock.posedge # extract results from reference design amplitude_ref, size_ref = entropy_encode(int(data_in)) # comparing reference and module results assert size == size_ref assert amplitude == amplitude_ref raise StopSimulation return tbstim, inst, inst_clock run_testbench(bench_entropycoder)
def test_quantizer(): """The functionality of the module is tested here""" # declare clock and reset clock = Signal(bool(0)) reset = ResetSignal(0, active=True, async=True) # width of the input data width_data = 12 # width of input address width_addr = 6 # bus declaration for the module quanto_datastream = QuantIODataStream(width_data, width_addr) assert isinstance(quanto_datastream, QuantIODataStream) quanti_datastream = QuantIODataStream(width_data, width_addr) assert isinstance(quanti_datastream, QuantIODataStream) quant_ctrl = QuantCtrl() assert isinstance(quant_ctrl, QuantCtrl) # declare constants max_addr = 2**width_addr component = Component() assert isinstance(component, Component) @block def bench_quant(): """instantiation of quantizer module and clock""" inst = quantizer(clock, reset, quanti_datastream, quant_ctrl, quanto_datastream) inst_clock = clock_driver(clock) @instance def tbstim(): """we send test cases here""" # reset the block before processing yield pulse_reset(reset, clock) # select Cb or Cr component color = component.y2_space # process Cb or Cr component yield quant_top_block_process(clock, quant_ctrl, color, quanto_datastream, quanti_datastream, quant_in, quant_rom, max_addr, 1) print("===============================================") # select Y1 or Y2 component color = component.cr_space # process Cb or Cr component yield quant_top_block_process(clock, quant_ctrl, color, quanto_datastream, quanti_datastream, quant_in, quant_rom, max_addr, 1) raise StopSimulation return tbstim, inst, inst_clock run_testbench(bench_quant)
def test_quantizer_core(): """The functionality of the module is tested here""" # clock and reset signals declared here clock = Signal(bool(0)) reset = ResetSignal(0, active=True, async=True) # width of the input data width_data = 12 # width of input address width_addr = 6 # bus signals declaration for the module quant_output_stream = QuantDataStream(width_data) assert isinstance(quant_output_stream, QuantDataStream) quant_input_stream = QuantDataStream(width_data) assert isinstance(quant_input_stream, QuantDataStream) color_component = Signal(intbv(0)[3:]) max_addr = 2**width_addr # component declaration component = Component() assert isinstance(component, Component) @block def bench_quant_core(): """instantiation of quantizer core module and clock signals""" inst = quantizer_core( clock, reset, quant_output_stream, quant_input_stream, color_component) inst_clock = clock_driver(clock) @instance def tbstim(): """We send the inputs from here""" # reset the module before sending inputs yield pulse_reset(reset, clock) # select Cb or Cr component color = component.y2_space # process the component selected yield quant_block_process( clock, color_component, color, quant_in, quant_rom, quant_input_stream, quant_output_stream, max_addr) yield clock.posedge print ("====================================") # select Y1 or Y2 component color = component.cb_space # process the component selected yield quant_block_process( clock, color_component, color, quant_in, quant_rom, quant_input_stream, quant_output_stream, max_addr) yield clock.posedge raise StopSimulation return tbstim, inst, inst_clock run_testbench(bench_quant_core)
def test_bytestuffer(): """ We will test the functionality of bytestuffer in this block Constants: width_addr_out : maximum adress width of the output RAM width_out : width of the data in the ouput RAM """ # width of the input data or output data width_data = 8 # maximum address width of output RAM width_addr_out = 24 # clock and reset signals clock = Signal(bool(0)) reset = ResetSignal(0, active=True, async=True) # input, output and control interfaces bs_in_stream = BSInputDataStream(width_data) assert isinstance(bs_in_stream, BSInputDataStream) bs_out_stream = BSOutputDataStream(width_data, width_addr_out) assert isinstance(bs_out_stream, BSOutputDataStream) bs_cntrl = BScntrl() assert isinstance(bs_cntrl, BScntrl) num_enc_bytes = Signal(intbv(0)[width_addr_out:]) @block def bench_bytestuffer(): """This bench is used to test the functionality""" # instantiate module and clock inst = bytestuffer(clock, reset, bs_in_stream, bs_out_stream, bs_cntrl, num_enc_bytes) inst_clock = clock_driver(clock) @instance def tbstim(): """stimulus generates inputs for byte stuffer""" # reset the module yield pulse_reset(reset, clock) yield toggle_signal(bs_cntrl.start, clock) yield clock.posedge # send input data for i in range(64): # send 0xFF bytes if i % 5 == 0: bs_in_stream.data_in.next = 0xFF # send other bytes else: bs_in_stream.data_in.next = i yield clock.posedge if bs_out_stream.data_valid: print("output data is %d" % bs_out_stream.byte) # assert fifo empty when all the inputs are over if i == 63: bs_in_stream.fifo_empty.next = True for _ in range(3): yield clock.posedge if bs_out_stream.data_valid: print("output data is %d" % bs_out_stream.byte) yield toggle_signal(bs_cntrl.sof, clock) # if last byte is 0xFF. Print the zero's stuffed if bs_out_stream.data_valid: print("output data is %d" % bs_out_stream.byte) print("total encoded bytes is %d" % num_enc_bytes) raise StopSimulation return tbstim, inst, inst_clock run_testbench(bench_bytestuffer)
def test_backend(): """ We will test the functionality of entropy coder in this block constants: width_data : width of the input data size_data : size required to store the data width_addr : width of the address """ # width of the input data width_data = 12 write_addr = 7 # clock and reset signals clock = Signal(bool(0)) reset = ResetSignal(0, active=True, async=True) # declaration of input signal data_in = Signal(intbv(0)[width_data:]) write_addr = Signal(modbv(0)[7:]) ready = Signal(bool(0)) data_out = Signal(intbv(0)[width_data:]) valid_data = Signal(bool(0)) start_block = Signal(bool(0)) addr = Signal(intbv(0)[24:]) num_enc_bytes = Signal(intbv(0)[24:]) @block def bench_backend(): """This bench is used to test the functionality""" # instantiate module and clock inst = backend(clock, reset, start_block, data_in, write_addr, valid_data, data_out, ready, addr, num_enc_bytes) inst_clock = clock_driver(clock) @instance def tbstim(): """stimulus generates inputs for entropy coder""" # reset the module output_model = [0] * 64 yield pulse_reset(reset, clock) # write Y data into input buffer valid_data.next = True yield clock.posedge write_addr.next = 64 for i in range(64): data_in.next = i % 25 yield clock.posedge write_addr.next = write_addr + 1 valid_data.next = False yield clock.posedge for _ in range(35): yield clock.posedge # start the blocks yield toggle_signal(start_block, clock) # write Cb data into input buffer valid_data.next = True yield clock.posedge for i in range(64): data_in.next = i % 16 yield clock.posedge write_addr.next = write_addr + 1 valid_data.next = False yield clock.posedge while not ready: yield clock.posedge yield toggle_signal(start_block, clock) # write Cr data into input buffer valid_data.next = True yield clock.posedge for i in range(64): data_in.next = i % 47 yield clock.posedge write_addr.next = write_addr + 1 valid_data.next = False yield clock.posedge while not ready: yield clock.posedge yield toggle_signal(start_block, clock) # write Y data into input buffer valid_data.next = True yield clock.posedge for i in range(64): data_in.next = i % 28 yield clock.posedge write_addr.next = write_addr + 1 valid_data.next = False yield clock.posedge while not ready: yield clock.posedge yield toggle_signal(start_block, clock) # write Cb data into input buffer valid_data.next = True yield clock.posedge for i in range(64): data_in.next = i % 40 index = int(addr) output_model[index] = int(data_out) yield clock.posedge write_addr.next = write_addr + 1 valid_data.next = False yield clock.posedge yield toggle_signal(start_block, clock) # write Cr data into input buffer valid_data.next = True yield clock.posedge for i in range(64): data_in.next = i % 31 index = int(addr) output_model[index] = int(data_out) yield clock.posedge write_addr.next = write_addr + 1 valid_data.next = False yield clock.posedge while not ready: yield clock.posedge yield toggle_signal(start_block, clock) while not ready: index = int(addr) output_model[index] = int(data_out) yield clock.posedge yield toggle_signal(start_block, clock) while not ready: index = int(addr) output_model[index] = int(data_out) yield clock.posedge yield toggle_signal(start_block, clock) while not ready: index = int(addr) output_model[index] = int(data_out) yield clock.posedge yield toggle_signal(start_block, clock) while not ready: index = int(addr) output_model[index] = int(data_out) yield clock.posedge print("===================") for i in range(addr): print("outputs_hdl %d" % output_model[i]) print("======================") # get outputs from reference values output_ref = [] output_ref = backend_soft() for i in range(len(output_ref)): print("outputs_soft %d" % int(output_ref[i], 2)) print("===========================") # compare reference and HDL outputs for i in range(len(output_ref)): assert int(output_ref[i], 2) == output_model[i] raise StopSimulation return tbstim, inst, inst_clock run_testbench(bench_backend)
def test_entropycoder(): """ We will test the functionality of entropy coder in this block constants: width_data : width of the input data size_data : size required to store the data """ # width of the input data width_data = 12 # size required to store input data size_data = (width_data - 1).bit_length() # clock and reset signals clock = Signal(bool(0)) reset = ResetSignal(0, active=True, async=True) # declaration of input signal data_in = Signal(intbv(0)[width_data:].signed()) # declaration of output signals size = Signal(intbv(0)[size_data:]) amplitude = Signal(intbv(0)[width_data:].signed()) @block def bench_entropycoder(): """This bench is used to test the functionality""" # instantiate module and clock inst = entropycoder(clock, reset, data_in, size, amplitude) inst_clock = clock_driver(clock) @instance def tbstim(): """stimulus generates inputs for entropy coder""" # reset the module yield pulse_reset(reset, clock) # send input test cases into the module for i in range(-2 ** (width_data - 1) + 1, 2 ** (width_data - 1), 1): data_in.next = i yield clock.posedge yield clock.posedge # extract results from reference design amplitude_ref, size_ref = entropy_encode(int(data_in)) # comparing reference and module results assert size == size_ref assert amplitude == amplitude_ref raise StopSimulation return tbstim, inst, inst_clock run_testbench(bench_entropycoder)
def test_divider(): """The functionality of the divider is tested here""" # clock and reset signals clock = Signal(bool(0)) reset = ResetSignal(0, active=True, async=True) width_dividend = 5 width_divisor = 8 width_quotient = 5 # dividend, divisor, quotient signals declared dividend = Signal(intbv(0)[width_dividend:].signed()) divisor = Signal(intbv(0)[width_divisor:]) quotient = Signal(intbv(0)[width_quotient:].signed()) # compute data width width_data = len(dividend) - 1 @block def bench_divider(): """The module where we pass tests into divider block""" # instantiation of clock and divider inst = divider(clock, reset, dividend, divisor, quotient) inst_clock = clock_driver(clock) @instance def tbstim(): """Test cases are given here""" # reset signal yield pulse_reset(reset, clock) list_output = [] list_output_ref = [] # all the possible tests from -2048 to 2048 given here for dividend_temp in range(-2**(width_data), 2**(width_data), 1): for divisor_temp in range(0, 256, 1): dividend.next = dividend_temp divisor.next = divisor_temp result = divider_ref(dividend_temp, divisor_temp) list_output_ref.append(result) yield clock.posedge list_output.append(int(quotient)) yield clock.posedge list_output.append(int(quotient)) yield clock.posedge list_output.append(int(quotient)) yield clock.posedge list_output.append(int(quotient)) yield clock.posedge list_output.append(int(quotient)) # pop the zeroes stored in the list because of pipelining list_output.pop(0) list_output.pop(0) list_output.pop(0) list_output.pop(0) # compare reference design divider output with that of HDL divider for item1, item2 in zip(list_output, list_output_ref): print("quotient %d quotient_ref %d" % (item1, item2)) assert item1 == item2 raise StopSimulation return tbstim, inst, inst_clock run_testbench(bench_divider)
def test_divider(): """The functionality of the divider is tested here""" # clock and reset signals clock = Signal(bool(0)) reset = ResetSignal(0, active=True, async=True) width_dividend = 5 width_divisor = 8 width_quotient = 5 # dividend, divisor, quotient signals declared dividend = Signal(intbv(0)[width_dividend:].signed()) divisor = Signal(intbv(0)[width_divisor:]) quotient = Signal(intbv(0)[width_quotient:].signed()) # compute data width width_data = len(dividend)-1 @block def bench_divider(): """The module where we pass tests into divider block""" # instantiation of clock and divider inst = divider(clock, reset, dividend, divisor, quotient) inst_clock = clock_driver(clock) @instance def tbstim(): """Test cases are given here""" # reset signal yield pulse_reset(reset, clock) list_output = [] list_output_ref = [] # all the possible tests from -2048 to 2048 given here for dividend_temp in range(-2**(width_data), 2**(width_data), 1): for divisor_temp in range(0, 256, 1): dividend.next = dividend_temp divisor.next = divisor_temp result = divider_ref(dividend_temp, divisor_temp) list_output_ref.append(result) yield clock.posedge list_output.append(int(quotient)) yield clock.posedge list_output.append(int(quotient)) yield clock.posedge list_output.append(int(quotient)) yield clock.posedge list_output.append(int(quotient)) yield clock.posedge list_output.append(int(quotient)) # pop the zeroes stored in the list because of pipelining list_output.pop(0) list_output.pop(0) list_output.pop(0) list_output.pop(0) # compare reference design divider output with that of HDL divider for item1, item2 in zip(list_output, list_output_ref): print ("quotient %d quotient_ref %d" % (item1, item2)) assert item1 == item2 raise StopSimulation return tbstim, inst, inst_clock run_testbench(bench_divider)