I have written a verilog code for a multiplier which gives correct results after simulation. But, the code generated after synthesis of the above mentioned code does not give correct results. In fact, it gives no results. The log file created after synthesis says that there could be possible timing errors with my design, although I have tried to synchronize everything at the positive edge of the clock. Besides, it also generates a warning which says:
Variable or signal is driven in more than one process or block. This may cause simulation mismatches between the original and synthesized designs. [CDFG2G-622]
: 'qq[1]' in module 'ab_mac' in file '/ugassignments/ma3ps139/cadence/abacus8_syn/abacus8_chk.v' on line 59, column 22.
I don't know how to rectify this. Please help. Here is the code:
module ab_mac (result, a, b, clk, reset, zero);
output [16:1] result;
input [8:1] a, b;
input [11:0] zero;
reg [8:1] A, B;
input clk, reset;
wire [16:1] p0, p1, p2, p3, p4, p5, p6, p7;
reg [9:0] qq [16:1];
reg [9:0] rr [16:1];
wire [9:0] q [16:1];
wire [3:0] ones [16:1];
genvar j, i, k, m;
reg [4:0] count;
part_prod_gen1 ppg (p0, p1, p2, p3, p4, p5, p6, p7, a, b);
//load the partial products
generate
for (j=1; j<=16; j=j+1)
begin: loop1
always @ (posedge clk)
begin
if (!reset)
begin
if (count == 5'b00000)
begin
qq[j][9] <= p7[j];
qq[j][8] <= p6[j];
qq[j][7] <= p5[j];
qq[j][6] <= p4[j];
qq[j][5] <= p3[j];
qq[j][4] <= p2[j];
qq[j][3] <= p1[j];
qq[j][2] <= p0[j];
qq[j][1] <= 1'b0;
qq[j][0] <= 1'b0;
end
else if (count[0] == 1)
begin
qq[j] <= q[j];
end
else
begin
case (ones[j])
4'b0010 :
begin {qq[j][9], qq[j][8]} <= 2'b0;
if (j<16) qq[j+1][9-ones[j+1]] <= 1'b1; end
4'b0011 :
begin {qq[j][9], qq[j][8]} <= 2'b0;
if (j<16) qq[j+1][9-ones[j+1]] <= 1'b1; end
4'b0100 :
begin {qq[j][9], qq[j][8], qq[j][7],qq[j][6]} <= 4'b0;
if (j<15) qq[j+2][8-ones[j+2]] <= 1'b1; end
4'b0101 :
begin {qq[j][9], qq[j][8], qq[j][7],qq[j][6]} <= 4'b0;
if (j<15) qq[j+2][8-ones[j+2]] <= 1'b1; end
4'b0110 :
begin {qq[j][9], qq[j][8], qq[j][7],qq[j][6]} <= 4'b0;
if (j<15) qq[j+2][8-ones[j+2]] <= 1'b1; end
4'b0111 :
begin {qq[j][9], qq[j][8], qq[j][7],qq[j][6]} <= 4'b0;
if (j<15) qq[j+2][8-ones[j+2]] <= 1'b1; end
4'b1000 :
begin {qq[j][9],qq[j][8],qq[j][7],qq[j][6],qq[j][5],qq[j][4],qq[j][3],qq[j][2]} <= 8'b0;
if (j<14) qq[j+3][7-ones[j+3]] <= 1'b1; end
endcase
end
end
end
end
endgenerate
//compress the partial products
generate
for (i=1; i<=16; i=i+1)
begin: loop2
count_one con (ones[i], qq[i]);
shift sft (q[i], qq[i]);
end
endgenerate
assign result[1] = qq[1][9] & (!reset) ,
result[2] = qq[2][9] & (!reset) ,
result[3] = qq[3][9] & (!reset) ,
result[4] = qq[4][9] & (!reset) ,
result[5] = qq[5][9] & (!reset) ,
result[6] = qq[6][9] & (!reset) ,
result[7] = qq[7][9] & (!reset) ,
result[8] = qq[8][9] & (!reset) ,
result[9] = qq[9][9] & (!reset) ,
result[10] = qq[10][9] & (!reset) ,
result[11] = qq[11][9] & (!reset) ,
result[12] = qq[12][9] & (!reset) ,
result[13] = qq[13][9] & (!reset) ,
result[14] = qq[14][9] & (!reset) ,
result[15] = qq[15][9] & (!reset) ,
result[16] = qq[16][9] & (!reset) ;
always @ (posedge clk)
if (reset)
count <= 5'b00000;
else
begin
count <= count + 1'b1;
if(count == 5'b10001)
count <= 5'b00000;
end
endmodule
Also, here are the codes for the other instances in case you would like to verify:
module shift (out, in);
output[9:0] out;
input [9:0] in;
wire [3:0] ones;
genvar i;
count_one coon (ones, in);
generate
for (i=9; i>=0; i=i-1)
begin: loop
assign out[i] = (i > (9-ones)? 1 : 0);
end
endgenerate
endmodule
module count_one (ones, column);
output [3:0] ones;
input [9:0] column;
assign ones = column[9]+column[8]+column[7]+column[6]+column[5]+column[4]+column[3]+column[2]+column[1]+column[0];
endmodule
module part_prod_gen (p0, p1, p2, p3, p4, p5, p6, p7, in1, in2);
output [15:1] p0, p1, p2, p3, p4, p5, p6, p7;
input [7:0] in1, in2;
wire [7:0] pp [7:0];
genvar i, j;
generate
for (i=0; i<=7; i=i+1)
begin: loop1
for (j=0; j<=7; j=j+1)
begin: loop2
assign pp[i][j] = in1[j] & in2[i];
end
end
endgenerate
assign p0 = {7'b0, pp[0][7], 7'b0};
assign p1 = {6'b0, pp[1][7], pp[1][6], pp[0][6], 6'b0};
assign p2 = {5'b0, pp[2][7:5],pp[1][5],pp[0][5],5'b0};
assign p3 = {4'b0, pp[3][7:4],pp[2][4],pp[1][4],pp[0][4],4'b0};
assign p4 = {3'b0, pp[4][7:3],pp[3][3],pp[2][3],pp[1][3],pp[0][3],3'b0};
assign p5 = {2'b0, pp[5][7:2],pp[4][2],pp[3][2],pp[2][2],pp[1][2],pp[0][2],2'b0};
assign p6 = {1'b0, pp[6][7:1],pp[5][1],pp[4][1],pp[3][1],pp[2][1],pp[1][1],pp[0] [1],1'b0};
assign p7 = {pp[7][7:0],pp[6][0],pp[5][0],pp[4][0],pp[3][0],pp[2][0],pp[1][0],pp[0][0]};
endmodule
Best Answer
I presume that you are synthesising for an FPGA or CPLD. The simulator will successfully simulate many language constructs which are technically valid Verilog, but are very hard to translate to real programmable logic hardware.
I can't synthesise your block myself as I don't have the part_prod_gen1, count_one and shift modules available, but the problems I can see from reading the code are:
Register array qq elements are assigned in multiple separate processed (always blocks). This is not synthesisable as the process blocks run in parallel and the register flip-flop cannot be set from two different sources. You can rectify this by combining much of the code into a single sequential process (which is ugly and harder to debug) or using intermediate wires which are combined together in a single process. See this answer for a similar problem.