¿Cómo crear un sumador de 64 bits Carry Look ahead?

0

Estoy tratando de implementar el código verilog mediante la generación de una declaración. Hay un problema con la toma de cuatro bits para calcular los valores P y G. Agregué el código a continuación como referencia. Cin se toma como cero.

'timescale 1ns/10ps

module cla_64bit(sum,c_out,a,b,c_in);

input [64:0]a,b;
input c_in;
output [64:0]sum;
output c_out;
wire [65:0]sum_out;
wire [64:0]c_in;
wire [64:0]c_out;

assign c_in[0]=1'b0;


genvar i;
generate
  for (i = 0;i<64;i=i+16)
        begin : FA
            add_16bit FINALBITBLOCK(
              .sum    (sum_out[i]),
              .c_out  (c_in[i-1]),
              .a  (a[i]),
              .b  (b[i]),
            .c_in   (c_in[i])
            );
          //assign g[i]=a[i] & b[i];
          //assign p[i]=a[i] ^ b[i];
          //assign c_in[i+1]= g[i]|(p[i] & c_in[i]);
          end 

assign c_out=c_in[63];
assign sum=sum_out[63:0];

endgenerate 
endmodule

module add_16bit(sum,c_out,a,b,c_in);
input [15:0]a,b;
input c_in;
output [15:0]sum;
output c_out;
wire [15:0]p,g;
wire [15:0]sum_out;
wire [16:0]c_in;
wire [16:0]c_out;

assign c_in[0]=1'b0;

genvar i;
generate
  for (i = 0;i<16;i=i+4)
        begin : FA
            add_4bit FOURBITBLOCK(
              .sum    (sum_out[i]),
              .c_out  (c_in[i+1]),
              .a  (a[i]),
              .b  (b[i]),
            .c_in   (c_in[i])
            );
          assign g[i]=a[i] & b[i];
          assign p[i]=a[i] ^ b[i];
          assign c_in[i+1]= g[i]|(p[i] & c_in[i]);
          end 

assign c_out=c_in[15];
//assign sum=sum[15:0];

endgenerate
endmodule

module add_4bit(sum,c_out,a,b,c_in);
input [3:0]a,b;
input c_in;
output [3:0]sum;
output c_out;
wire  [3:0]p,g;
wire [3:0]sum_out;
wire [4:0]c_in;
wire [4:0]c_out;  
assign c_in[0]=1'b0;


genvar i;
generate
  for (i = 0;i<4;i=i+1)
        begin : FA
            add_full FA(
              .sum    (sum_out[i:0]),
              .c_out  (c_in[i+1]),
              .a  (a[i]),
              .b  (b[i]),
            .c_in   (c_in[i])
            );
          assign g[i]=a[i] & b[i];
          assign p[i]=a[i] ^ b[i];
          assign c_in[i]= g[i]|(p[i] & c_in[i]);
          end 

assign c_out=c_in[3];
assign sum=sum_out[3:0];

endgenerate
endmodule

module add_full (sum, c_out, a, b, c_in);
output sum, c_out;   
input  a, b, c_in;   
wire   w1, w2, w3;   

add_half M1 (w1, w2, a, b);   
add_half M2 (sum, w3, w1, c_in);   
or M3 (c_out, w2, w3);
endmodule

module add_half (sum, c_out, a, b);
output sum, c_out;   
input  a, b;     
xor M1 (sum, a, b);     
and M2 (c_out, a, b);
endmodule 
    
pregunta Arun_3810

1 respuesta

1

c_in es una entrada de 1 bit, pero también se define como una interconexión de 64 bits (demasiado amplia). Permite cambiar el nombre de la interconexión a carry y hacer que tenga 5 bits de ancho; un bit para cada uno de los add_16bit 's c_in más el resultado final.

Necesitas usar la sección de rango. [i] solo indexa un bit. Para obtener 16 bits, utilice [16*i+15 : 16*i] o utilice el corte de bits ( +: ) [i +: 16] . La división de bits se explica en StackOverflow: Indexación de vectores y matrices con +: y ¿Qué es +: y - :? . La gran diferencia es que la división de bits se puede utilizar en bloques de procedimientos y generar bucles. La forma expandida solo se puede utilizar cuando i es un genvar o parameter .

wire [4:0] carry;
genvar i;
for (i = 0;i<64;i=i+16) begin : FA
  add_16bit FINALBITBLOCK(
    .sum    (sum[i +: 16]),
    .c_out  (carry[(i>>4)+1]),
    .a      (a[i +: 16]),
    .b      (b[i +: 16]),
    .c_in   (carry[i>>4])
  );
end
assign carry[0] = c_in;
assign c_out = carry[4];
    
respondido por el Greg

Lea otras preguntas en las etiquetas