Beispiel #1
0
def test_dct_1d():
    """1D-DCT MyHDL Test

    In this test is verified the correct behavior of the 1d-dct module
    """

    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)
Beispiel #2
0
def dct_2d(inputs, outputs, clock, reset, num_fractional_bits=14,
           stage_1_prec=10, out_prec=10, N=8):
    """2D-DCT Module

    This module performs the 2D-DCT Transformation.
    It takes serially the inputs of a NxN block
    and outputs parallely the transformed block in
    64 signals. The row-column decomposition method used to
    implement the 2d-dct. The parameter num_fractional_bits is used
    to define the fractional bits for the fixed point representation
    of the coefficients. The stage_1_prec parameter defines the fractional
    bits for the fixed point representation of the 1st stage 1d-dct outputs.
    The out_prec defines the fractional bits for the ouputs of the 2d-dct and
    the N parameter defines the size of the NxN block.

    Inputs:
        data_in, data_valid, clock, reset

    Outputs:
        NxN signals in the list out_sigs, data_valid

    Parameters:
        num_fractional_bits, stage_1_prec, out_prec, N
    """
    first_1d_output = output_interface(stage_1_prec, N)
    input_1d_stage_1 = input_1d_1st_stage()

    first_1d = dct_1d(input_1d_stage_1, first_1d_output, clock,
                      reset, num_fractional_bits, stage_1_prec, N)

    data_in_signed = Signal(intbv(0, min=-input_1d_stage_1.in_range,
                                  max=input_1d_stage_1.in_range))
    data_valid_reg = Signal(bool(0))
    data_valid_reg2 = Signal(bool(0))

    counter = Signal(intbv(0, min=0, max=N))
    outputs_data_valid = Signal(bool(0))

    # list of interfaces for the 2nd stage 1d-dct modules
    inputs_2nd_stage = []
    outputs_2nd_stage = []
    for i in range(N):
        inputs_2nd_stage += [input_1d_1st_stage(first_1d_output.out_precision)]
        outputs_2nd_stage += [output_interface(out_prec, N)]


    stage_2_insts = []
    for i in range(N):
        stage_2_insts += [dct_1d(inputs_2nd_stage[i], outputs_2nd_stage[i], clock,
                                reset, num_fractional_bits, stage_1_prec, N)]

        stage_2_insts += [assign(inputs_2nd_stage[i].data_in, first_1d_output.out_sigs[i])]
        stage_2_insts += [assign(inputs_2nd_stage[i].data_valid, first_1d_output.data_valid)]

        for j in range(N):
            stage_2_insts += [assign(outputs.out_sigs[j * N + i], outputs_2nd_stage[i].out_sigs[j])]

    stage_2_insts += [assign(outputs_data_valid, outputs_2nd_stage[0].data_valid)]

    @always_seq(clock.posedge, reset=reset)
    def input_subtract():
        """Align to zero each input"""
        if inputs.data_valid:
            data_in_signed.next = inputs.data_in
            input_1d_stage_1.data_in.next = data_in_signed - 128
            data_valid_reg.next = inputs.data_valid
            input_1d_stage_1.data_valid.next = data_valid_reg

    @always_comb
    def second_stage_output():
        outputs.data_valid.next = data_valid_reg2

    @always_seq(clock.posedge, reset=reset)
    def counter_update():
        """Counter update"""
        if outputs_data_valid:
            if counter == N - 1:
                counter.next = 0
            else:
                counter.next = counter + 1

    @always_comb
    def data_valid_2d():
        """Data valid signal assignment when the outputs are valid"""
        if outputs_data_valid and counter == 0:
            data_valid_reg2.next = True
        else:
            data_valid_reg2.next = False

    return (stage_2_insts, input_subtract, second_stage_output,
            counter_update, data_valid_2d, first_1d)
Beispiel #3
0
def dct_2d(inputs, outputs, clock, reset, num_fractional_bits=14,
           stage_1_prec=10, out_prec=10, N=8):
    """2D-DCT Module

    This module performs the 2D-DCT Transformation.
    It takes serially the inputs of a NxN block
    and outputs parallely the transformed block in
    64 signals.

    Inputs:
        data_in, data_valid
    Outputs:
        NxN signals in the list out_sigs, data_valid
    """
    first_1d_output = output_interface(stage_1_prec, N)
    input_1d_stage_1 = input_1d_1st_stage()

    first_1d = dct_1d(input_1d_stage_1, first_1d_output, clock,
                      reset, num_fractional_bits, stage_1_prec, N)

    data_in_signed = Signal(intbv(0, min=-input_1d_stage_1.in_range,
                                  max=input_1d_stage_1.in_range))
    data_valid_reg = Signal(bool(0))
    data_valid_reg2 = Signal(bool(0))

    counter = Signal(intbv(0, min=0, max=N))
    outputs_data_valid = Signal(bool(0))

    # list of interfaces for the 2nd stage 1d-dct modules
    inputs_2nd_stage = []
    outputs_2nd_stage = []
    for i in range(N):
        inputs_2nd_stage += [input_1d_2nd_stage(first_1d_output.out_precision)]
        outputs_2nd_stage += [output_interface(out_prec, N)]

    """the blocks below are used for the list of signal elaboration"""

    @block
    def assign(data_in, data_valid, data_in_temp, data_valid_temp):
        """used to assign the signals data_in and data_valid of the first 1d-dct module
        to the second stage 1d-dct modules"""
        @always_comb
        def assign():
            data_in.next = data_in_temp
            data_valid.next = data_valid_temp

        return assign

    @block
    def assign_2(outputs, outputs_2nd_stage, io):
        """used to assigns the output signals of the 2nd stage 1d-dct modules
        to the outputs signals of the top level 2d-dct"""
        @block
        def assign(y, x):
            @always_comb
            def assign():
                y.next = x
            return assign

        g = [None for _ in range(N)]
        for i in range(N):
                g[i] = assign(outputs.out_sigs[i*N + io], outputs_2nd_stage.out_sigs[i])
        return g

    @block
    def assign_3(y, x):
        """used to make a simple assignment of the data_valid signals of the 2nd stage
        1d-dct modules to a temp signal which used in the 2d-dct module"""
        @always_comb
        def assign():
            y.next = x

        return assign


    stage_2_insts = []
    for i in range(N):
        stage_2_insts += [dct_1d(inputs_2nd_stage[i], outputs_2nd_stage[i], clock,
                                reset, num_fractional_bits, stage_1_prec, N)]

        stage_2_insts += [assign(inputs_2nd_stage[i].data_in, inputs_2nd_stage[i].data_valid,
                                 first_1d_output.out_sigs[i], first_1d_output.data_valid)]

        stage_2_insts += [assign_2(outputs, outputs_2nd_stage[i], i)]

    stage_2_insts += [assign_3(outputs_data_valid, outputs_2nd_stage[0].data_valid)]

    @always_seq(clock.posedge, reset=reset)
    def input_subtract():
        """Align to zero each input"""
        if inputs.data_valid:
            data_in_signed.next = inputs.data_in
            input_1d_stage_1.data_in.next = data_in_signed - 128
            data_valid_reg.next = inputs.data_valid
            input_1d_stage_1.data_valid.next = data_valid_reg

    @always_comb
    def second_stage_output():
        outputs.data_valid.next = data_valid_reg2

    @always_seq(clock.posedge, reset=reset)
    def counter_update():
        """Counter update"""
        if outputs_data_valid:
            if counter == N - 1:
                counter.next = 0
            else:
                counter.next = counter + 1

    @always_comb
    def data_valid_2d():
        """Data valid signal assignment when the outputs are valid"""
        if outputs_data_valid and counter == 0:
            data_valid_reg2.next = True
        else:
            data_valid_reg2.next = False

    return (stage_2_insts, input_subtract, second_stage_output,
            counter_update, data_valid_2d, first_1d)
Beispiel #4
0
def test_dct_1d_conversion():
    """Convertible 1D-DCT Test

    This is the convertible testbench which ensures that the overall
    design is convertible and verified for its correct behavior"""

    samples, fract_bits, out_prec, N = 10, 14, 10, 8

    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()

    inputs_rom, expected_outputs_rom = in_out_data.get_rom_tables()

    @myhdl.block
    def bench_dct_1d():
        print_sig = [Signal(intbv(0, min=-2**out_prec, max=2**out_prec))
                     for _ in range(N)]
        print_sig_1 = [Signal(intbv(0, min=-2**out_prec, max=2**out_prec))
                       for _ in range(N)]

        tdut = dct_1d(inputs, outputs, clock, reset, fract_bits, out_prec, N)
        tbclk = clock_driver(clock)
        tbrst = reset_on_start(reset, clock)

        @instance
        def tbstim():
            yield reset.negedge
            inputs.data_valid.next =True

            for i in range(samples * N):
                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
                yield delay(1)
                if outputs.data_valid:
                    for i in range(N):
                        print_sig[i].next = expected_outputs_rom[outputs_count * 8 + i]
                    yield delay(1)
                    print("Expected Outputs")
                    for i in range(N):
                        print("%d" % print_sig[i])
                    print("Actual Outputs")
                    for i in range(N):
                        print("%d" % print_sig_1[i])
                    print("------------------------")
                    outputs_count += 1

            raise StopSimulation

        return tdut, tbclk, tbstim, monitor, tbrst, print_assign

    assert bench_dct_1d().verify_convert() == 0
Beispiel #5
0
def test_dct_1d_conversion():

    samples, fract_bits, out_prec, N = 10, 14, 10, 8

    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()

    inputs_rom, expected_outputs_rom = in_out_data.get_rom_tables()

    @myhdl.block
    def bench_dct_1d():
        print_sig = [Signal(intbv(0, min=-2**out_prec, max=2**out_prec))
                     for _ in range(N)]
        print_sig_1 = [Signal(intbv(0, min=-2**out_prec, max=2**out_prec))
                       for _ in range(N)]

        tdut = dct_1d(inputs, outputs, clock, reset, fract_bits, out_prec, N)
        tbclk = clock_driver(clock)
        tbrst = reset_on_start(reset, clock)

        @instance
        def tbstim():
            yield reset.negedge
            inputs.data_valid.next =True

            for i in range(samples * N):
                inputs.data_in.next = inputs_rom[i]
                yield clock.posedge

        print_assign = outputs.assignment_2(print_sig_1)

        @instance
        def monitor():
            outputs_count = 0
            while outputs_count != samples:
                yield clock.posedge
                yield delay(1)
                if outputs.data_valid:
                    for i in range(N):
                        print_sig[i].next = expected_outputs_rom[outputs_count * 8 + i]
                    yield delay(1)
                    print("Expected Outputs")
                    for i in range(N):
                        print("%d" % print_sig[i])
                    print("Actual Outputs")
                    for i in range(N):
                        print("%d" % print_sig_1[i])
                    print("------------------------")
                    outputs_count += 1

            raise StopSimulation

        return tdut, tbclk, tbstim, monitor, tbrst, print_assign

    # verify and convert with GHDL
    verify.simulator = 'ghdl'
    assert bench_dct_1d().verify_convert() == 0
    # verify and convert with iverilog
    verify.simulator = 'iverilog'
    assert bench_dct_1d().verify_convert() == 0