He escrito un código verilog para un multiplicador que da resultados correctos después de la simulación. Pero, el código generado tras la síntesis de dicho código no da resultados correctos. De hecho, no da resultados. El archivo de registro creado después de la síntesis dice que podría haber posibles errores de sincronización con mi diseño, aunque he intentado sincronizar todo en el borde positivo del reloj. Además, también genera una advertencia que dice:
La variable o señal se maneja en más de un proceso o bloque. Esto puede causar desajustes de simulación entre los diseños originales y sintetizados. [CDFG2G-622]: 'qq[1]' en el módulo 'ab_mac' en el archivo '/ugassignments/ma3ps139/cadence/abacus8_syn/abacus8_chk.v' en la línea 59, columna 22.
No sé cómo rectificar esto. Por favor ayuda. Aquí está el código:
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
Además, aquí están los códigos para las otras instancias en caso de que desee verificar:
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
Supongo que está sintetizando para un FPGA o CPLD. El simulador simulará con éxito muchas construcciones de lenguaje que son Verilog técnicamente válidas, pero que son muy difíciles de traducir a hardware de lógica programable real.
No puedo sintetizar su bloque yo mismo porque no tengo los módulos part_prod_gen1, count_one y shift disponibles, pero los problemas que puedo ver al leer el código son:
Matriz de registros q los elementos q se asignan en multiples procesados separados (siempre bloques). Esto no se puede sintetizar ya que los bloques de proceso se ejecutan en paralelo y el flip-flop de registro no se puede configurar desde dos fuentes diferentes. Puede corregir esto combinando gran parte del código en un solo proceso secuencial (que es feo y más difícil de depurar) o usando cables intermedios que se combinan en un solo proceso. Ver esta respuesta para un problema similar.
genvar j, i, k, m;
// ... other code
//load the partial products
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
//load the partial products
//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
titán
Xcodó