imageverilogsystem-verilogxilinxhdl

Need help in converting verilog module without input & output ports into synthesizable. Because module without input/output ports is not synthesizable


I created a verilog module for my project, and getting the expected output (but it doesn't has a testbench, it takes required input data by reading a .txt file using $readmemh)

But a module without input or output ports cant be synthesized.

Need to synthesize it using cadence to get area, power reports (Not dumping it on FPGA). If required another top module which instantiates this module can also be used.

Need help to make this code synthesizable (Planar and DC outputs are required to be displayed -

Input : clk

Outputs : Y_Planar_output, Cb_Planar_output, Cr_Planar_output, Y_DC_output_corner, Y_DC_output_left, Y_DC_output_top.

Any extra input/output ports if required can be used to make it synthesizable)

Code

module hevc_v6;

//Registers to store file contents and reference buffer for Y, Cb and Cr
reg [7:0] Y_data[0:291];
reg [7:0] Y_ref_buffer[0:34];

reg [7:0] Cb_data[0:82];
reg [7:0] Cb_ref_buffer[0:18];

reg [7:0] Cr_data[0:82];
reg [7:0] Cr_ref_buffer[0:18];

//Reading pixel values from text file
initial $readmemh("Luma_Y_data_16x16.txt", Y_data);
initial $readmemh("Chroma_Cb_data_8x8.txt", Cb_data);
initial $readmemh("Chroma_Cr_data_8x8.txt", Cr_data);

//Registers for Matrix
reg [7:0] Y_luma_matrix [0:15][0:15];
reg [7:0] Cb_chroma_matrix [0:7][0:7];
reg [7:0] Cr_chroma_matrix [0:7][0:7];

//Registers for Planar and DC prediction outputs for Y, Cb and Cr
reg [11:0] Y_Planar_output [0:15][0:15];
reg [11:0] Y_DC_output_corner;
reg [11:0] Y_DC_output_left [1:15];
reg [11:0] Y_DC_output_top [1:15];

reg [11:0] Cb_Planar_output [0:7][0:7];

reg [11:0] Cr_Planar_output [0:7][0:7];

//Extra registers for Planar prediction
//Luma Y
reg [11:0] Y_pred_h [0:15][0:15];
reg [11:0] Y_pred_v [0:15][0:15];

//Chroma Cb
reg [11:0] Cb_pred_h [0:7][0:7];
reg [11:0] Cb_pred_v [0:7][0:7];

//Chroma Cr
reg [11:0] Cr_pred_h [0:7][0:7];
reg [11:0] Cr_pred_v [0:7][0:7];

//Extra registers for DC prediction
reg [12:0] Y_dc_avg;

//Clock initialization
reg clk;
initial clk = 0;
always #5 clk = ~clk;

//Storing pixel values into matrix  
integer x, y, z;

//Luma Y
initial
    for (x=0; x<256; x=x+1)
        Y_luma_matrix [x/16][x%16] = Y_data[x]; 

//Chroma Cb
initial
    for (y=0; y<64; y=y+1)
        Cb_chroma_matrix [y/8][y%8] = Cb_data[y]; 

//Chroma Cr
initial
    for (z=0; z<64; z=z+1)
        Cr_chroma_matrix [z/8][z%8] = Cr_data[z]; 
        
//Ref buffer initialization
integer a, b, c;

//Luma Y
initial 
    for (a=0; a<35; a=a+1)
        //Y_ref_buffer [a] = 'h80;
        Y_ref_buffer [a] = Y_data[256+a];

//Chroma Cb
initial 
    for (b=0; b<19; b=b+1)
        //Cb_ref_buffer [b] = 'h80;
        Cb_ref_buffer [b] = Cb_data[64+b];

//Chroma Cr
initial 
    for (c=0; c<19; c=c+1)
        //Cr_ref_buffer [c] = 'h80;
        Cr_ref_buffer [c] = Cr_data[64+c];

//PLANAR PREDICTION
integer e,f,g,h,i,j;

//Luma Y
always @(posedge clk)
begin
    for (f=0; f<16; f=f+1)  
    begin
        for (e=0; e<16; e=e+1) 
        begin
            Y_pred_h [f][e] = (16-1-e) * Y_ref_buffer[19+f] + (e+1) * Y_ref_buffer[1];
            Y_pred_v [f][e] = (16-1-f) * Y_ref_buffer[3+e] + (f+1) * Y_ref_buffer[2];
            Y_Planar_output [f][e] = (Y_pred_h [f][e] + Y_pred_v [f][e] + 16 ) >> (4+1);                
        end
    end
end

//Chroma Cb
always @(posedge clk)
begin
    for (h=0; h<8; h=h+1)   
    begin
        for (g=0; g<8; g=g+1) 
        begin
            Cb_pred_h [h][g] = (8-1-g) * Cb_ref_buffer[11+h] + (g+1) * Cb_ref_buffer[1];
            Cb_pred_v [h][g] = (8-1-h) * Cb_ref_buffer[3+g] + (h+1) * Cb_ref_buffer[2];
            Cb_Planar_output [h][g] = (Cb_pred_h [h][g] + Cb_pred_v [h][g] + 8 ) >> (3+1);              
        end
    end
end

//Chroma Cr
always @(posedge clk)
begin
    for (j=0; j<8; j=j+1)   
    begin
        for (i=0; i<8; i=i+1) 
        begin
            Cr_pred_h [j][i] = (8-1-i) * Cr_ref_buffer[11+j] + (i+1) * Cr_ref_buffer[1];
            Cr_pred_v [j][i] = (8-1-j) * Cr_ref_buffer[3+i] + (j+1) * Cr_ref_buffer[2];
            Cr_Planar_output [j][i] = (Cr_pred_h [j][i] + Cr_pred_v [j][i] + 8 ) >> (3+1);              
        end
    end
end

//DC PREDICTION
integer m,n;

//For only Luma Y
always @(posedge clk)
begin
    Y_dc_avg = (Y_ref_buffer[3] + Y_ref_buffer[4] + Y_ref_buffer[5] + Y_ref_buffer[6] + Y_ref_buffer[7] + Y_ref_buffer[8] + Y_ref_buffer[9] + Y_ref_buffer[10] + Y_ref_buffer[11] + Y_ref_buffer[12] + Y_ref_buffer[13] + Y_ref_buffer[14] + Y_ref_buffer[15] + Y_ref_buffer[16] + Y_ref_buffer[17] + Y_ref_buffer[18] + Y_ref_buffer[19] + Y_ref_buffer[20] + Y_ref_buffer[21] + Y_ref_buffer[22] + Y_ref_buffer[23] + Y_ref_buffer[24] + Y_ref_buffer[25] + Y_ref_buffer[26] + Y_ref_buffer[27] + Y_ref_buffer[28] + Y_ref_buffer[29] + Y_ref_buffer[30] + Y_ref_buffer[31] + Y_ref_buffer[32] + Y_ref_buffer[33] + Y_ref_buffer[34]) >> (4+1);
    
    Y_DC_output_corner = (Y_ref_buffer [19] + 2 * Y_dc_avg + Y_ref_buffer[3] + 2) >> 2;
    
    for (m=1; m<16; m=m+1)
        Y_DC_output_left [m] = (Y_ref_buffer[3+m] + 3 * Y_dc_avg + 2) >> 2;
    for (n=1; n<16; n=n+1)
        Y_DC_output_top [n] = (Y_ref_buffer[19+n] + 3 * Y_dc_avg + 2) >> 2;
end     

endmodule

Help is appreciated!

These are the 3 text files, you can copy these data into notepad (notepad++ would be better i feel)

Luma_Y_data_16x16.txt

99 9C 99 96 9C 9A 99 9A 9B 97 99 98 98 98 96 98 9A 9B 9D 9D 9A 9C 99 9A 99 97 9B 98 98 98 9B 9B 9D 9B 9C 9B 9B 9E 97 9A 9A 99 99 9A 9A 98 99 9A 9F 9E 9A 99 9A 9C 9B 9B 9C 9C 9A 9A 99 9A 99 98 9B 9B 9A 99 9B 9E 9D 9E 9C 9B 9C 9A 9B 9A 9B 98 9F 9D 9B 9C 9C 9F 9D 9E 9B 9A 9A 9B 9E 9C 9A 99 A1 A0 9D A0 9D 9D 9F 9D 9B 9F 9A 9B 9D 9E 9B 9A 9F A0 A1 9C 9E 9E 9A 9F 9D 9F 9E 9F 9D 9C A0 9C 9F A1 A0 9C 9F 9F 9E 9D 9F A1 9F 9E 9D 9C 9F 9D A3 A1 A2 A1 9E A0 A1 9D 9F 9C A0 9E 9C 9E 9F 9F A0 9F A2 9F A3 9E 9F 9F A0 9F A0 A0 A2 A1 A0 9E A2 A2 A5 A4 A1 9F 9F A0 A1 9F 9F A1 A3 A0 9F A1 A5 A5 A2 A0 A3 A2 9F A0 A4 A2 A1 9E 9F A3 9B 9E A6 A2 A3 A1 A2 A2 A3 A1 A1 A5 A3 A2 A3 A1 9A A1 A5 A2 A2 A3 A1 A5 A3 A2 A2 A3 A2 A3 A3 A0 A0 9F A5 A7 A7 A2 A1 A5 A3 A3 A3 9F A4 A1 A2 A1 A0 9F

98 98 A4 99 96 97 9A 98 9C 9A 97 9A 99 99 9A 98 99 9A 99 9A 99 9D 9D 9B 9E 9F 9E 9F A1 A1 9F A3 A2 A5 A2

Chroma_Cb_data_8x8.txt

84 84 85 85 85 86 86 86 84 84 85 85 85 86 86 86 84 84 84 85 85 85 85 85 83 83 84 84 84 84 83 84 84 84 83 84 84 83 83 83 82 82 83 83 84 83 83 83 81 81 82 83 83 82 82 82 81 81 82 83 82 82 82 82

86 88 80 86 86 86 87 88 86 85 86 83 83 83 83 83 83 82 80

Chroma_Cr_data_8x8.txt

68 68 69 69 69 68 68 68 68 68 69 69 69 68 68 68 68 68 68 69 69 68 68 68 68 67 68 6A 69 68 68 68 6A 6A 6A 69 69 68 68 68 6A 6A 6A 6A 6A 6A 69 6A 6A 6A 6A 6A 6B 6A 6A 6A 6A 6A 6A 6A 6A 6A 6A 6A

68 66 6C 69 69 68 68 68 67 66 67 68 68 69 69 69 6A 6A 6A


Solution

  • Here is a list of synthesis concerns for the OP and how to address them:

        initial
          for (z=0; z<64; z=z+1)
            Cr_chroma_matrix [z/8][z%8] = Cr_data[z]
    
        // Chroma Cr
        always @(posedge clk)
        begin
          for (j=0; j<8; j=j+1) begin
            for (i=0; i<8; i=i+1) begin
              // infers a lot of multiplies             
            end
          end
    

    Keep in mind that synthesis targets a physical device with finite resources; write the RTL to model within the limits of those resources.

    If these concerns are addressed, then the design should synthesize.

    Write a testbench if you want to understand how the changed design works. The timing will be different for initial blocks with for loops replaced by synchronous processes.