Commit 2d4c00bf authored by Andrey Filippov's avatar Andrey Filippov
Browse files

working on DSP-based 8x8 DCT implementing Chen algorithm

parent c4619853
Loading
Loading
Loading
Loading
+33 −0
Original line number Original line Diff line number Diff line
@@ -991,6 +991,39 @@ module jp_channel#(
        .dv                 (),  // not used: output data output valid. Will go high on the 94-th cycle after the start (now - on 95-th?)
        .dv                 (),  // not used: output data output valid. Will go high on the 94-th cycle after the start (now - on 95-th?)
        .d_out              (dct_out)              // output[12:0] 
        .d_out              (dct_out)              // output[12:0] 
    );
    );
    
    /* New DCT, now in passive mode */
    // TODO: enforce minimal pause (when not butted together)
    wire        dct_last_in_debug;
    wire        dct_pre_first_out_debug;
    wire        dct_dv_debug;
    wire [12:0] dct_dout_debug;
    
    dct2d8x8_chen #(
        .INPUT_WIDTH      (10),
        .OUTPUT_WIDTH     (13),
        .STAGE1_SAFE_BITS (3),
        .STAGE2_SAFE_BITS (3),
        .TRANSPOSE_WIDTH  (16),
        .TRIM_STAGE_1     (0),
        .TRIM_STAGE_2     (2),
        .DSP_WIDTH        (24),
        .DSP_OUT_WIDTH    (24),
        .DSP_B_WIDTH      (18),
        .DSP_A_WIDTH      (25),
        .DSP_P_WIDTH      (48),
        .DSP_M_WIDTH      (43)
    ) dct2d8x8_chen_i (
        .clk           (xclk),                    // input
        .rst           (!frame_en),               // input
        .start         (dct_start),               // input
        .xin           (yc_nodc),                 // input[9:0] signed 
        .last_in       (dct_last_in_debug),       // output reg 
        .pre_first_out (dct_pre_first_out_debug), // output
        .dv            (dct_dv_debug),            // output
        .d_out         (dct_dout_debug)           // output[12:0] signed 
    );
    
`endif    
`endif    
    
    
    wire          quant_start;
    wire          quant_start;
+112 −54
Original line number Original line Diff line number Diff line
@@ -45,6 +45,7 @@ module dct1d_chen#(
    parameter A_WIDTH =     25,
    parameter A_WIDTH =     25,
    parameter P_WIDTH =     48,
    parameter P_WIDTH =     48,
    parameter M_WIDTH =     43, // actual multiplier width (== (A_WIDTH +B_WIDTH)
    parameter M_WIDTH =     43, // actual multiplier width (== (A_WIDTH +B_WIDTH)
    parameter COSINE_SHIFT= 17,
    parameter COS_1_16 =    128553, // (1<<17) * cos(1*pi/16)
    parameter COS_1_16 =    128553, // (1<<17) * cos(1*pi/16)
    parameter COS_2_16 =    121095, // (2<<17) * cos(1*pi/16)
    parameter COS_2_16 =    121095, // (2<<17) * cos(1*pi/16)
    parameter COS_3_16 =    108982, // (3<<17) * cos(1*pi/16)
    parameter COS_3_16 =    108982, // (3<<17) * cos(1*pi/16)
@@ -59,8 +60,9 @@ module dct1d_chen#(
    input  [2 * WIDTH -1:0]        d10_32_76_54, // Concatenated input data {x[1],x[0]}/{x[3],x[2]}/ {x[7],x[6]}/{x[5],x[4]}
    input  [2 * WIDTH -1:0]        d10_32_76_54, // Concatenated input data {x[1],x[0]}/{x[3],x[2]}/ {x[7],x[6]}/{x[5],x[4]}
    input                          start,      // {x[1],x[0]} available next after start,  {x[3],x[2]} - second next, then {x[7],x[6]} and {x[5],x[4]} 
    input                          start,      // {x[1],x[0]} available next after start,  {x[3],x[2]} - second next, then {x[7],x[6]} and {x[5],x[4]} 
    output [WIDTH -1:0]            dout,
    output [WIDTH -1:0]            dout,
    output                         pre2_start_out // 2 clock cycle before F4 output, full dout sequence
    output reg                     pre2_start_out, // 2 clock cycle before F4 output, full dout sequence
                                             // start_out-X-F4-X-F2-X-F6-F5-F0-F3-X-F1-X-F7
                                             // start_out-X-F4-X-F2-X-F6-F5-F0-F3-X-F1-X-F7
    output reg                     en_out    // valid at the same time slot as pre2_start_out (goes active with pre2_start_out)                                      
);
);
    reg    signed [B_WIDTH-1:0] dsp_ma_bin;
    reg    signed [B_WIDTH-1:0] dsp_ma_bin;
    wire                        dsp_ma_ceb1_1;     // load b1 register
    wire                        dsp_ma_ceb1_1;     // load b1 register
@@ -74,7 +76,7 @@ module dct1d_chen#(
    wire                        dsp_ma_sela_1;
    wire                        dsp_ma_sela_1;
    wire                        dsp_ma_en_a_1;      // 0: +/- D, 1: A or A +/- D 
    wire                        dsp_ma_en_a_1;      // 0: +/- D, 1: A or A +/- D 
    wire                        dsp_ma_en_d_1;      // 0: A, 1: D  or A +/- D 
    wire                        dsp_ma_en_d_1;      // 0: A, 1: D  or A +/- D 
    wire                        dsp_ma_sub_d_1;     // 1 when  - D, 0 - all other
    wire                        dsp_ma_sub_a_1;     //
    wire                        dsp_ma_neg_m_1;    // 1 - negate multiplier result
    wire                        dsp_ma_neg_m_1;    // 1 - negate multiplier result
    wire                        dsp_ma_accum_1;    // 0 - use multiplier result, 1 add to accumulator
    wire                        dsp_ma_accum_1;    // 0 - use multiplier result, 1 add to accumulator
    wire   signed [P_WIDTH-1:0] dsp_ma_p_1;
    wire   signed [P_WIDTH-1:0] dsp_ma_p_1;
@@ -125,8 +127,8 @@ module dct1d_chen#(
    
    
    wire                        simd_cea01;
    wire                        simd_cea01;
    wire                        simd_cea23;
    wire                        simd_cea23;
    wire                        simd_ceaf45; // first stage A registers CE
    wire                        simd_cea45; // first stage A registers CE
    wire                        simd_ceas45; // second stage A registers CE
//    wire                        simd_ceas45; // second stage A registers CE
    wire                        simd_ceb01;
    wire                        simd_ceb01;
    wire                        simd_ceb23;
    wire                        simd_ceb23;
    wire                        simd_ceb45;  // B registers CE
    wire                        simd_ceb45;  // B registers CE
@@ -138,10 +140,11 @@ module dct1d_chen#(
    wire                        simd_cep45;
    wire                        simd_cep45;


    reg                   [7:0] phase;
    reg                   [7:0] phase;
    reg                   [3:0] phase_cnt;
    reg                   [2:0] phase_cnt;
    reg        [OUT_WIDTH -1:0] dout_r;
    reg        [OUT_WIDTH -1:0] dout_r;
    wire       [OUT_WIDTH -1:0] dout1_w;
    wire       [OUT_WIDTH -1:0] dout1_w;
    wire       [OUT_WIDTH -1:0] dout2_w;
    wire       [OUT_WIDTH -1:0] dout2_w;
    reg                   [2:0] per_type; // idle/last:0, first cycle - 1, 2-nd - 2, other - 3,... ~en->6 ->7 -> 0  (to generate pre2_start_out)


//        .ain      ({simd_a1,simd_a0}), // input[47:0] 
//        .ain      ({simd_a1,simd_a0}), // input[47:0] 
//        .bin      ({simd_b1,simd_b0}), // input[47:0]
//        .bin      ({simd_b1,simd_b0}), // input[47:0]
@@ -156,7 +159,8 @@ module dct1d_chen#(
    assign simd_ceb01 =  phase[2] | phase[5];
    assign simd_ceb01 =  phase[2] | phase[5];


    assign simd_sub01 = phase[3] | phase[6];
    assign simd_sub01 = phase[3] | phase[6];
    assign simd_cep01 = phase[2] | phase[3] | phase[5] | phase[6];
//    assign simd_cep01 = phase[2] | phase[3] | phase[5] | phase[6];
    assign simd_cep01 = phase[3] | phase[4] | phase[6] | phase[7];
    
    
    // dsp_addsub_simd2_i input connections
    // dsp_addsub_simd2_i input connections
    assign  simd_a2 = phase[1]? d10_32_76_54[0 * WIDTH +: WIDTH] : simd_p0; // only phase[1] & phase[7], other phases - don't care
    assign  simd_a2 = phase[1]? d10_32_76_54[0 * WIDTH +: WIDTH] : simd_p0; // only phase[1] & phase[7], other phases - don't care
@@ -169,25 +173,35 @@ module dct1d_chen#(
    assign simd_ceb23 =  phase[3] | phase[7];
    assign simd_ceb23 =  phase[3] | phase[7];


    assign simd_sub23 = phase[4] | phase[7];
    assign simd_sub23 = phase[4] | phase[7];
    assign simd_cep23 = phase[0] | phase[3] | phase[4] | phase[7];
//    assign simd_cep23 = phase[0] | phase[3] | phase[4] | phase[7];
    assign simd_cep23 = phase[0] | phase[1] | phase[4] | phase[5];
    
    
    assign  simd_a4 = simd_p3; // only at phase[6], other phases - don't care
    assign  simd_a4 = simd_p3; // only at phase[6], other phases - don't care
    assign  simd_a5 = simd_p0; // only at phase[6], other phases - don't care
    assign  simd_a5 = simd_p0; // only at phase[6], other phases - don't care


    // dsp_addsub_reg2_simd_i input connections
    // dsp_addsub_reg2_simd_i input connections
    assign  simd_b4 = dsp_ma_p_1[M_WIDTH-1 -: WIDTH]; // only at phase[6], other phases - don't care. TODO: add symmetric rounding here?
//    assign  simd_b4 = dsp_ma_p_1[M_WIDTH-1 -: WIDTH]; // only at phase[6], other phases - don't care. TODO: add symmetric rounding here?
    assign  simd_b5 = dsp_ma_p_1[M_WIDTH-1 -: WIDTH]; // only at phase[2], other phases - don't care. TODO: add symmetric rounding here?
//    assign  simd_b5 = dsp_ma_p_1[M_WIDTH-1 -: WIDTH]; // only at phase[2], other phases - don't care. TODO: add symmetric rounding here?


    assign simd_ceaf45 = phase[6];
    assign  simd_b4 = dsp_ma_p_1[COSINE_SHIFT +: WIDTH]; // only at phase[6], other phases - don't care. TODO: add symmetric rounding here?
    assign simd_ceas45 = phase[2];
    assign  simd_b5 = dsp_ma_p_1[COSINE_SHIFT +: WIDTH]; // only at phase[2], other phases - don't care. TODO: add symmetric rounding here?




//COSINE_SHIFT

    assign simd_cea45 = phase[6];
//    assign simd_ceas45 = phase[2];
    assign simd_ceb45 =  phase[2] | phase[4];
    assign simd_ceb45 =  phase[2] | phase[4];


    assign simd_sub45 = phase[2] | phase[4];
    assign simd_sub45 = phase[2] | phase[4];
    assign simd_cep45 = phase[2] | phase[3] | phase[4] | phase[5];
//    assign simd_cep45 = phase[2] | phase[3] | phase[4] | phase[5];
    assign simd_cep45 = phase[3] | phase[4] | phase[5] | phase[6];
    
    
    // dsp_ma1_i control connections
    // dsp_ma1_i control connections
    assign dsp_ma_ceb1_1 =  phase[3] | phase[7];
    assign dsp_ma_ceb1_1 =  phase[4] | phase[7];
    assign dsp_ma_ceb2_1 =  phase[0];
    assign dsp_ma_ceb2_1 =  phase[1];
    assign dsp_ma_selb_1 =  phase[3] | phase[6];
    assign dsp_ma_selb_1 =  phase[3] | phase[6];
    assign dsp_ma_cea1_1 =  phase[2] | phase[6];
    assign dsp_ma_cea1_1 =  phase[2] | phase[6];
    assign dsp_ma_cea2_1 =  phase[1] | phase[3];
    assign dsp_ma_cea2_1 =  phase[1] | phase[3];
@@ -195,7 +209,7 @@ module dct1d_chen#(
    assign dsp_ma_sela_1 =  phase[1] | phase[7];
    assign dsp_ma_sela_1 =  phase[1] | phase[7];
    assign dsp_ma_en_a_1 =  !(phase[2] | phase[4]);
    assign dsp_ma_en_a_1 =  !(phase[2] | phase[4]);
    assign dsp_ma_en_d_1 =  phase[0] | phase[2] | phase[4] | phase[6];
    assign dsp_ma_en_d_1 =  phase[0] | phase[2] | phase[4] | phase[6];
    assign dsp_ma_sub_d_1 = phase[0];
    assign dsp_ma_sub_a_1 = phase[0];
    assign dsp_ma_neg_m_1 = phase[6];
    assign dsp_ma_neg_m_1 = phase[6];
    assign dsp_ma_accum_1 = phase[5] | phase[7];
    assign dsp_ma_accum_1 = phase[5] | phase[7];
    // dsp_ma1_i data input connections
    // dsp_ma1_i data input connections
@@ -203,53 +217,83 @@ module dct1d_chen#(
                            ({WIDTH{phase[1]}} & simd_p2) |
                            ({WIDTH{phase[1]}} & simd_p2) |
                            ({WIDTH{phase[2]}} & simd_p0) |
                            ({WIDTH{phase[2]}} & simd_p0) |
                            ({WIDTH{phase[3]}} & simd_p2) ; // Other - don't care */
                            ({WIDTH{phase[3]}} & simd_p2) ; // Other - don't care */
    assign dsp_ma_ain24_1 = phase[6] ? simd_p1 : (phase[2] ? simd_p0 : simd_p2); 
    // Swapping A and d for pre-added (it is D-A, not A-D)                            
    assign dsp_ma_din24_1 = phase[6] ? simd_p2 :  simd_p1; 
//    assign dsp_ma_ain24_1 = phase[6] ? simd_p1 : (phase[2] ? simd_p0 : simd_p2); 
//    assign dsp_ma_din24_1 = phase[6] ? simd_p2 :  simd_p1; 
    assign dsp_ma_ain24_1 = phase[6] ? simd_p2 : (phase[2] ? simd_p0 : simd_p2); 
//    assign dsp_ma_din24_1 = phase[6] ? simd_p1 :  simd_p1; 
    assign dsp_ma_din24_1 = simd_p1; 


    // dsp_ma2_i control connections
    // dsp_ma2_i control connections
    assign dsp_ma_ceb1_2 = phase[1] | phase[6];
    assign dsp_ma_ceb1_2 = phase[3] | phase[6];
    assign dsp_ma_ceb2_2 = phase[2] | phase[5];
    assign dsp_ma_ceb2_2 = phase[2] | phase[5];
    assign dsp_ma_selb_2 = phase[1] | phase[3] | phase[5] | phase[7];
    assign dsp_ma_selb_2 = phase[0] | phase[2] | phase[4] | phase[6];
    assign dsp_ma_cea1_2 = phase[5];
    assign dsp_ma_cea1_2 = phase[5];
    assign dsp_ma_cea2_2 = phase[4];
    assign dsp_ma_cea2_2 = phase[4];
    assign dsp_ma_ced_2 =  phase[1] | phase[6];
    assign dsp_ma_ced_2 =  phase[1] | phase[6];
    assign dsp_ma_sela_2 =  phase[1] | phase[6];
    assign dsp_ma_sela_2 =  phase[1] | phase[6];
    assign dsp_ma_seld_2 =  phase[0] | phase[3] | phase[4] | phase[7];
    assign dsp_ma_seld_2 =  phase[0] | phase[2] | phase[5] | phase[7];
    assign dsp_ma_neg_m_2 = phase[6];
    assign dsp_ma_neg_m_2 = phase[6];
    assign dsp_ma_accum_2 = phase[0] | phase[2] | phase[4] | phase[6];
    assign dsp_ma_accum_2 = phase[0] | phase[2] | phase[4] | phase[6];
    // dsp_ma2_i data input connections
    // dsp_ma2_i data input connections
    assign dsp_ma_ain24_2 = simd_p5; 
    assign dsp_ma_ain24_2 = simd_p5; 
    assign dsp_ma_din24_2 = simd_p4; 
    assign dsp_ma_din24_2 = simd_p4; 


    assign dsp_ma_din24_1 = phase[6] ? simd_p2 :  simd_p1; 


// Shift adder outputs to the MSB of the multiplier inputs
// Shift adder outputs to the MSB of the multiplier inputs
    assign dsp_ma_ain_1 = {dsp_ma_ain24_1, {A_WIDTH-WIDTH{1'b0}}};   
//    assign dsp_ma_ain_1 = {dsp_ma_ain24_1, {A_WIDTH-WIDTH{1'b0}}};   
    assign dsp_ma_din_1 = {dsp_ma_din24_1, {A_WIDTH-WIDTH{1'b0}}};   
//    assign dsp_ma_din_1 = {dsp_ma_din24_1, {A_WIDTH-WIDTH{1'b0}}};   
    assign dsp_ma_ain_2 = {dsp_ma_ain24_2, {A_WIDTH-WIDTH{1'b0}}};   
//    assign dsp_ma_ain_2 = {dsp_ma_ain24_2, {A_WIDTH-WIDTH{1'b0}}};   
    assign dsp_ma_din_2 = {dsp_ma_din24_2, {A_WIDTH-WIDTH{1'b0}}};
//    assign dsp_ma_din_2 = {dsp_ma_din24_2, {A_WIDTH-WIDTH{1'b0}}};
// Extend sign  for A and D of the multiplier inputs (24bits->25 bits)
    assign dsp_ma_ain_1 = {{A_WIDTH-WIDTH{dsp_ma_ain24_1[WIDTH-1]}},dsp_ma_ain24_1};   
    assign dsp_ma_din_1 = {{A_WIDTH-WIDTH{dsp_ma_din24_1[WIDTH-1]}},dsp_ma_din24_1};   
    assign dsp_ma_ain_2 = {{A_WIDTH-WIDTH{dsp_ma_ain24_2[WIDTH-1]}},dsp_ma_ain24_2};   
    assign dsp_ma_din_2 = {{A_WIDTH-WIDTH{dsp_ma_din24_2[WIDTH-1]}},dsp_ma_din24_2};

// Shift DSP outputs to match output results
// Shift DSP outputs to match output results
    assign  dout1_w = dsp_ma_p_1[M_WIDTH -: WIDTH]; // adding one it for adder (two MPY outputs are added)
// Leave unshifted?
    assign  dout2_w = dsp_ma_p_2[M_WIDTH -: WIDTH]; // adding one it for adder (two MPY outputs are added)
    
//    assign  dout1_w = dsp_ma_p_1[M_WIDTH -: WIDTH]; // adding one bit for adder (two MPY outputs are added)
//    assign  dout2_w = dsp_ma_p_2[M_WIDTH -: WIDTH]; // adding one bit for adder (two MPY outputs are added)
    assign  dout1_w = dsp_ma_p_1[COSINE_SHIFT +: WIDTH]; // adding one bit for adder (two MPY outputs are added)
    assign  dout2_w = dsp_ma_p_2[COSINE_SHIFT +: WIDTH]; // adding one bit for adder (two MPY outputs are added)
    
    
    assign dout = dout_r;
    assign dout = dout_r;


    always @ (posedge clk) begin
    always @ (posedge clk) begin
        phase <= {phase[6:0], en & (start |phase[7])};
        if      (rst)      per_type <= 0;
        if      (!rst || start)          phase_cnt <= 0;
        else if (start)    per_type <= 3'h1;
        else if (en || (phase_cnt != 7)) phase_cnt <= phase_cnt + 1;
        else if (phase[7]) begin
            if (!per_type[2] && !en)  per_type <= 3'h6;
            else if ((per_type != 0) && (per_type != 3)) per_type <= per_type + 1;  
        end
        phase <= {phase[6:0], start | (phase[7] & (|per_type) )};
        
        if (rst || start || phase[7]) phase_cnt <= 0;
        else if (|phase[6:0])         phase_cnt <= phase_cnt + 1;
        
        // Cosine table, defined to fit into 17 bits for 18-bit signed DSP B-operand
        // Cosine table, defined to fit into 17 bits for 18-bit signed DSP B-operand
        case (phase_cnt)
        case (phase_cnt)
            3'h0: dsp_ma_bin <= COS_1_16;
            3'h0: dsp_ma_bin <= COS_6_16;
            3'h1: dsp_ma_bin <= COS_7_16;
            3'h1: dsp_ma_bin <= COS_7_16;
            3'h2: dsp_ma_bin <= COS_2_16;
            3'h2: dsp_ma_bin <= COS_1_16;
            3'h3: dsp_ma_bin <= COS_2_16;
            3'h3: dsp_ma_bin <= COS_2_16;
            3'h4: dsp_ma_bin <= COS_3_16;
            3'h4: dsp_ma_bin <= COS_5_16;
            3'h5: dsp_ma_bin <= COS_5_16;
            3'h5: dsp_ma_bin <= COS_3_16;
            3'h6: dsp_ma_bin <= COS_4_16;
            3'h6: dsp_ma_bin <= COS_4_16;
            3'h7: dsp_ma_bin <= COS_6_16;
            3'h7: dsp_ma_bin <= COS_6_16;
        endcase
        endcase
        dout_r <= phase_cnt[0] ? dout1_w : dout2_w;
        dout_r <= phase_cnt[0] ? dout1_w : dout2_w;

        if (rst) pre2_start_out <= 0;
        else     pre2_start_out <= (per_type == 2) && phase[3];
        
        if (rst || !(en || (|phase))) en_out <= 0;
        else if (phase[3]) begin
            if      (per_type == 2)   en_out <= 1;
            else if (per_type[2])     en_out <= 0;
        end         
    end
    end


    dsp_addsub_simd #(
    dsp_addsub_simd #(
@@ -281,7 +325,7 @@ module dct1d_chen#(
        .cep      (simd_cep23),        // input
        .cep      (simd_cep23),        // input
        .pout     ({simd_p3,simd_p2})  // output[47:0] 
        .pout     ({simd_p3,simd_p2})  // output[47:0] 
    );
    );

/*
    dsp_addsub_reg2_simd #(
    dsp_addsub_reg2_simd #(
        .NUM_DATA(2),
        .NUM_DATA(2),
        .WIDTH(24)
        .WIDTH(24)
@@ -297,7 +341,21 @@ module dct1d_chen#(
        .cep      (simd_cep45),        // input
        .cep      (simd_cep45),        // input
        .pout     ({simd_p5,simd_p4})  // output[47:0] 
        .pout     ({simd_p5,simd_p4})  // output[47:0] 
    );
    );

*/
    dsp_addsub_simd #(
        .NUM_DATA (2),
        .WIDTH    (WIDTH)
    ) dsp_addsub_simd3_i (
        .clk      (clk),               // input
        .rst      (rst),               // input
        .ain      ({simd_a5,simd_a4}), // input[47:0] 
        .bin      ({simd_b5,simd_b4}), // input[47:0] 
        .cea      (simd_cea45),        // input
        .ceb      (simd_ceb45),        // input
        .subtract (simd_sub45),        // input
        .cep      (simd_cep45),        // input
        .pout     ({simd_p5,simd_p4})  // output[47:0] 
    );
   
   
    dsp_ma_preadd #(
    dsp_ma_preadd #(
        .B_WIDTH(18),
        .B_WIDTH(18),
@@ -319,7 +377,7 @@ module dct1d_chen#(
        .sela  (dsp_ma_sela_1),  // input
        .sela  (dsp_ma_sela_1),  // input
        .en_a  (dsp_ma_en_a_1),    // input
        .en_a  (dsp_ma_en_a_1),    // input
        .en_d  (dsp_ma_en_d_1), // input
        .en_d  (dsp_ma_en_d_1), // input
        .sub_d (dsp_ma_sub_d_1), // input
        .sub_a (dsp_ma_sub_a_1), // input
        .neg_m (dsp_ma_neg_m_1), // input
        .neg_m (dsp_ma_neg_m_1), // input
        .accum (dsp_ma_accum_1), // input
        .accum (dsp_ma_accum_1), // input
        .pout  (dsp_ma_p_1)      // output[47:0] signed 
        .pout  (dsp_ma_p_1)      // output[47:0] signed 
@@ -348,7 +406,7 @@ module dct1d_chen#(
        .accum (dsp_ma_accum_2), // input
        .accum (dsp_ma_accum_2), // input
        .pout  (dsp_ma_p_2)      // output[47:0] signed 
        .pout  (dsp_ma_p_2)      // output[47:0] signed 
    );
    );

/*
    dly01_16 dly01_16_i (
    dly01_16 dly01_16_i (
        .clk   (clk),           // input
        .clk   (clk),           // input
        .rst   (rst),           // input
        .rst   (rst),           // input
@@ -356,7 +414,7 @@ module dct1d_chen#(
        .din   (phase[7]),      // input
        .din   (phase[7]),      // input
        .dout  (pre2_start_out) // output
        .dout  (pre2_start_out) // output
    );
    );

*/


endmodule
endmodule
+25 −5
Original line number Original line Diff line number Diff line
@@ -48,23 +48,35 @@ module dct1d_chen_reorder_in#(
    input                  start, // with first pixel 
    input                  start, // with first pixel 
    output [2*WIDTH -1:0]  dout_10_32_76_54, // Concatenated/reordered output data {x[1],x[0]}/{x[3],x[2]}/ {x[7],x[6]}/{x[5],x[4]}
    output [2*WIDTH -1:0]  dout_10_32_76_54, // Concatenated/reordered output data {x[1],x[0]}/{x[3],x[2]}/ {x[7],x[6]}/{x[5],x[4]}
    output reg             start_out,
    output reg             start_out,
    output reg             en_out // to be sampled when start_out is expected
    output                 en_out // to be sampled when start_out is expected
);
);
    reg                    last_r;
    reg                    last_r;
    reg              [2:0] cntr_in;
    reg              [2:0] cntr_in;
    reg              [1:0] raddr;
    reg              [1:0] raddr;
    wire                   restart = !rst && en && (start || last_r);
    wire                   restart = !rst && en && (start || last_r);
    wire             [1:0] we = ((|cntr_in) || en)? {~cntr_in[0]^cntr_in[2],cntr_in[0]^cntr_in[2]}:2'b0;
//    wire             [1:0] we = ((|cntr_in) || en)? {~cntr_in[0]^cntr_in[2],cntr_in[0]^cntr_in[2]}:2'b0;
    wire             [1:0] we = ((|cntr_in) || en)? {cntr_in[0]^cntr_in[2], ~cntr_in[0]^cntr_in[2]}:2'b0;
    wire             [1:0] waddr = {cntr_in[2],cntr_in[2]^cntr_in[1]};
    wire             [1:0] waddr = {cntr_in[2],cntr_in[2]^cntr_in[1]};
    reg        [WIDTH-1:0] bufl_ram[0:3];
    reg        [WIDTH-1:0] bufl_ram[0:3];
    reg        [WIDTH-1:0] bufh_ram[0:3];
    reg        [WIDTH-1:0] bufh_ram[0:3];
    reg     [2*WIDTH -1:0] dout_10_32_76_54_r;
    reg     [2*WIDTH -1:0] dout_10_32_76_54_r;
    reg                    first_period;
    reg                    en_out_r;
    reg                    last_out;
    reg                    re_r;
    assign dout_10_32_76_54 = dout_10_32_76_54_r;
    assign dout_10_32_76_54 = dout_10_32_76_54_r;
    assign en_out =           en_out_r;
    
    
    always @(posedge clk) begin
    always @(posedge clk) begin
        if (rst) last_r <= 0;
        if (rst) last_r <= 0;
        else     last_r <= &cntr_in;
        else     last_r <= &cntr_in;


        last_out <= raddr == 2;
        
        if      (rst)          re_r <= 0;
        else if (cntr_in == 5) re_r <= 1;
        else if (last_out)     re_r <= 0;
        
        if      (rst)                   cntr_in <= 0;
        if      (rst)                   cntr_in <= 0;
        else if (restart || (|cntr_in)) cntr_in <= cntr_in + 1;
        else if (restart || (|cntr_in)) cntr_in <= cntr_in + 1;
        
        
@@ -75,10 +87,18 @@ module dct1d_chen_reorder_in#(
        else if (cntr_in == 5) raddr <= 0;
        else if (cntr_in == 5) raddr <= 0;
        else if (!(&raddr))    raddr <= raddr + 1;
        else if (!(&raddr))    raddr <= raddr + 1;
        
        
        dout_10_32_76_54_r <= {bufh_ram[raddr],bufl_ram[raddr]};
        if      (rst)          first_period <= 0;
        start_out <= (cntr_in == 5);
        else if (start && en)  first_period <= 1;
        else if (last_r)       first_period <= 0;
        
        if (re_r) dout_10_32_76_54_r <= {bufh_ram[raddr],bufl_ram[raddr]};
        
        start_out <= first_period && (cntr_in == 5);
        
        if      (rst)                 en_out_r <= 0;
        else if (cntr_in == 5)        en_out_r <= 1;
        else if ((raddr == 2) && !en) en_out_r <= 0;


        en_out <= en || (|cntr_in) || last_r;
    end
    end
endmodule
endmodule
+34 −44
Original line number Original line Diff line number Diff line
@@ -43,33 +43,45 @@ module dct1d_chen_reorder_out#(
 )(
 )(
    input                  clk,
    input                  clk,
    input                  rst,
    input                  rst,
    input                  en,        // sampled at timeslot of pre2_start
    input  [WIDTH -1:0]    din,       // pre2_start-X-F4-X-F2-X-F6-F5-F0-F3-X-F1-X-F7
    input  [WIDTH -1:0]    din,       // pre2_start-X-F4-X-F2-X-F6-F5-F0-F3-X-F1-X-F7
    input                  pre2_start,     // Two cycles ahead of F4 
    input                  pre2_start,     // Two cycles ahead of F4 
    output   [WIDTH -1:0]  dout,      // data in natural order: F0-F1-F2-F3-F4-F5-F6-F7
    output   [WIDTH -1:0]  dout,      // data in natural order: F0-F1-F2-F3-F4-F5-F6-F7
    output                 start_out, // 1 ahead of F0
    output                 start_out, // 1 ahead of the first F0
    output reg             en_out // to be sampled when start_out is expected
    output reg             dv,        // output data valid
    output                 en_out     // to be sampled when start_out is expected
);
);
    reg [WIDTH -1:0] reord_buf_ram[0:15];
    reg [WIDTH -1:0] reord_buf_ram[0:15];
    reg [WIDTH -1:0] dout_r;
    reg [WIDTH -1:0] dout_r;
    reg  [3:0] cntr_in;
    reg  [3:0] cntr_in;
    wire       start_8;
    reg        pre_we_r;
    wire       start_11;
    reg        start_12;
    wire       stop_in;
    reg        we_r;
    reg        we_r;
    reg  [3:0] ina_rom;
    reg  [3:0] ina_rom;
    wire [3:0] waddr = {ina_rom[3] ^ cntr_in[3], ina_rom[2:0]};   
    wire [3:0] waddr = {ina_rom[3] ^ cntr_in[3], ina_rom[2:0]};   
    reg  [3:0] raddr;
    reg  [3:0] raddr;
    reg  [2:0] per_type; // idle/last:0, first cycle - 1, 2-nd - 2, other - 3,... ~en->6 ->7 -> 0  (to generate pre2_start_out)
    reg        start_out_r;
    reg        en_out_r;
    assign dout = dout_r;
    assign dout = dout_r;
    assign start_out = start_12;
    assign start_out = start_out_r; 
    assign en_out = en_out_r;
    
    always @(posedge clk) begin
    always @(posedge clk) begin
        if      (rst)        we_r <= 0;
        if      (rst)           per_type <= 0;
        else if (pre2_start) we_r <= 1;
        else if (pre2_start)    per_type <= 3'h1;
        else if (stop_in)    we_r <= 0;
        else if (&cntr_in[2:0]) begin
            if      (!per_type[2] && !en)                per_type <= 3'h6;
            else if ((per_type != 0) && (per_type != 3)) per_type <= per_type + 1;  
        end
    
        if      (rst)                                              pre_we_r <= 0;
        else if (pre2_start)                                       pre_we_r <= 1;
        else if ((per_type == 0) || ((cntr_in==3) && per_type[2])) pre_we_r <= 0;
        we_r <= pre_we_r;
        
        
        if      (rst)        cntr_in <= 0;
        if      (rst)        cntr_in <= 0;
        else if (pre2_start) cntr_in <= {~cntr_in[3],3'b0};
        else if (pre2_start) cntr_in <= {~cntr_in[3],3'b0};
        else if (we_r)       cntr_in <= cntr_in + 1;
        else if (pre_we_r)       cntr_in <= cntr_in + 1;
        case (cntr_in[2:0])
        case (cntr_in[2:0])
            3'h0: ina_rom <= {1'b0,3'h4};
            3'h0: ina_rom <= {1'b0,3'h4};
            3'h1: ina_rom <= {1'b1,3'h1};
            3'h1: ina_rom <= {1'b1,3'h1};
@@ -78,46 +90,24 @@ module dct1d_chen_reorder_out#(
            3'h4: ina_rom <= {1'b0,3'h6};
            3'h4: ina_rom <= {1'b0,3'h6};
            3'h5: ina_rom <= {1'b0,3'h5};
            3'h5: ina_rom <= {1'b0,3'h5};
            3'h6: ina_rom <= {1'b0,3'h0};
            3'h6: ina_rom <= {1'b0,3'h0};
            3'h7: ina_rom <= {1'b0,3'h3};
            3'h7: ina_rom <= {1'b1,3'h3};
        endcase
        endcase
        
        
        if (we_r) reord_buf_ram[waddr] <= din;
        if (we_r) reord_buf_ram[waddr] <= din;


        if      (start_11)                  raddr <= {~cntr_in[3], 3'b0};
        if      ((per_type == 2) && (cntr_in == 1))   raddr <= {~cntr_in[3], 3'b0};
        else if ((raddr[2:0] != 0) || we_r) raddr <= raddr + 1;
        else if ((raddr[2:0] != 0) || (per_type !=0)) raddr <= raddr + 1;
        
        
        dout_r <=  reord_buf_ram[raddr];
        dout_r <=  reord_buf_ram[raddr];
        start_out_r <=  (per_type == 2) && (cntr_in == 1);
        
        
        start_12 <= start_11;
        if (rst ||(per_type == 0) ) en_out_r <= 0;
        
        else if (cntr_in == 1)      en_out_r <= (per_type == 2) || !per_type[2]; 
        en_out <= start_12 || (raddr[2:0] != 0); 


        if      (rst)                            dv <= 0;
        else if (start_out_r)                    dv <= 1;
        else if ((raddr[2:0] == 0) && !en_out_r) dv <= 0;
    end
    end


    dly01_16 start_8__i (
        .clk   (clk), // input
        .rst   (rst), // input
        .dly   (4'h7), // input[3:0] 
        .din   (pre2_start), // input
        .dout  (start_8) // output
    );

    dly01_16 start_11__i (
        .clk   (clk), // input
        .rst   (rst), // input
        .dly   (4'h1), // input[3:0] 
        .din   (start_8), // input
        .dout  (start_11) // output
    );

    dly01_16 dly01_16_2_i (
        .clk   (clk), // input
        .rst   (rst), // input
        .dly   (4'h4), // input[3:0] 
        .din   (start_8 && !pre2_start), // input
        .dout  (stop_in)            // output
    );


endmodule
endmodule

dsp/dct2d8x8_chen.v

0 → 100644
+224 −0

File added.

Preview size limit exceeded, changes collapsed.

Loading