# Synthesis of a multiplier design

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.

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

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

• @Xcodo, I have posted the remaining parts of the code. Please have a look at it. – titan May 23 '14 at 10:15
• You can use for loops inside a process in Verilog (or VHDL), the syntax is the same as in C. However it's only synthesisable if the loop condition is constant at compile time, that is that the loop variable is being incremented up on down to a fixed value, either a numeric constant or a module parameter. In hardware this is equivalent to multiple copies of the circuit in parallel (like generates). Just be careful to ensure that none of the iterations rely on the result of another iteration in the same clock cycle or you will get a chain of the circuits rather than a parallel set. – Xcodo May 23 '14 at 12:32

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:

• Using posedge and negedge always@ blocks for signals other than clock and reset lines often isn't synthesisable (see this answer). I think that using shift registers (explicitly or with a signal_old register) is a much more reliable approach than testing for posedge of count[0].
• 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.

genvar j, i,  k, m;
// ... other code
generate
for (j=1; j<=16; j=j+1)
begin: loop1
always @ (posedge clk)
begin
if (!reset) begin
// ... qq assignments
end
end
end
endgenerate

/* should be */

genvar i,  k, m;
integer j; // j as integer not genvar
// ... other code
//generate // comment out or remove
always @ (posedge clk)
begin
for (j=1; j<=16; j=j+1) // <- for-loop inside always block
begin: loop1
if (!reset) begin
// ... qq assignments
end
end
end
//endgenerate // comment out or remove

• I've found the source of that. In the case statement based on ones[j] you assign values to qq[j+1]. In the simulator or on paper try to step through that logic to find out what you're actually assigning each time. Make sure for any condition each qq[][] bit is only assigned once per clock cycle. I'm afraid I have to go do some work so won't be able to look again until tonight. Let me know how you get on! – Xcodo May 23 '14 at 13:35
• Sorry - I missed that j was still in a generate statement (I'm not doing badly since I haven't used Verilog in about five years, only VHDL!) Move the j to a for loop INSIDE the always block and it will at least synthesise. – Xcodo May 23 '14 at 17:54
• For clarification - the generate statement is just a convenient shorthand for writing the always@ process 16 times. In each of those blocks there is a possibility (the synthesiser isn't too smart) that the process could write to a given qq register, so it is given as a driver. All of these generated processes then have a claim on driving the output, which isn't synthesisable. – Xcodo May 23 '14 at 17:57
• @Xcodo, good debug. I added a code example of second bullet to be more specific. – Greg May 23 '14 at 18:06
• @titan, It will be all done in one clock cycle. There are no delay elements in the always block. The for-loop will execute in zero time. – Greg May 23 '14 at 22:14