2 位有符号乘法器

时间:2021-03-14 02:34:02

标签: binary verilog system-verilog signed

<块引用>

使用 4 位加法器的一个实例设计一个 2 位有符号乘法器。请记住,您需要将两个 2 位输入符号扩展为完整的 4 位。

这是我的作业,我想出了以下代码,但我的一些输出是错误的。谁能告诉我我做错了什么?

module mult(C,A,B);
    output signed[3:0]C;
    input signed[1:0]A,B;
    reg signed[3:0]sA,sB;

    assign sA = {A[1],A[1],A};
    assign sB = {B[1],B[1],B};
    
    wire carry;
    wire signed[3:0] A1;
    wire signed[3:0] A2;
    wire signed[3:0] sum0;
    
    and(A1[0],sA[0],sB[0]);
    and(A1[1],sA[1],sB[0]);
    and(A1[2],sA[2],sB[0]);
    and(A1[3],sA[3],sB[0]);
    
    
    assign A2[0] = 0;
    and(A2[1],sA[0],sB[1]);
    and(A2[2],sA[1],sB[1]);
    and(A2[3],sA[2],sB[1]);
    
 
    adder4bit a1(.A(A1),.B(A2),.Co(carry),.sum(sum0));
    assign C[0] = sum0[0];
    assign C[1] = sum0[1];
    assign C[2] = sum0[2];
    assign C[3] = sum0[3];
endmodule

module adder4bit(A,B,sum,Co);
    input signed[3:0]A,B;
    output signed [4:0]sum;
    reg signed[4:0]a,b;
    output Co;
    
    wire Ci;
    assign Ci = 1'b0;
    assign a = {A[3],A};
    assign b = {B[3],B};
    
    FA a0(.A(a[0]),.B(b[0]),.Ci(Ci),.sum(sum[0]),.Co(w1));
    FA a1(.A(a[1]),.B(b[1]),.Ci(w1),.sum(sum[1]),.Co(w2));
    FA a2(.A(a[2]),.B(b[2]),.Ci(w2),.sum(sum[2]),.Co(w3));
    FA a3(.A(a[3]),.B(b[3]),.Ci(w3),.sum(sum[3]),.Co(w4));
    FA a4(.A(a[4]),.B(b[4]),.Ci(w4),.sum(sum[4]),.Co(Co));
endmodule

module FA(A,B,Ci,Co,sum);
    
    input A,B,Ci;
    output sum,Co;
    
    assign sum = (A^B)^Ci;
    assign Co = (B&Ci) | (A&Ci) | (A&B);
    
endmodule

1 个答案:

答案 0 :(得分:1)

有一些信号声明为 reg 连接到端口输出,reg 必须在程序块中分配。

我还将加法器中的进位位设为显式 wire 向量,而不是多个隐式连线。隐式电线很危险,打字错误会导致断线。

我还声明乘法器中的 sum0 具有与其连接的 sum 端口的输出输入相同的宽度,即使位 4 不会被使用。

就逻辑而言,您只犯了一个错误,如果 A * B = A * B[0] - 2*A * B[1] 是 2 位有符号整数,则使用 A * B[0] + 2*B[1] 而不是 B。因为 B[1] 是符号位,因此 B = B[0] - 2*B[1]。我通过在端口连接中直接使用一元 - 解决了这个问题,我会让你在结构上写这个。

module mult(C,A,B);
  output signed[3:0]C;
  input signed[1:0]A,B;
  wire signed[3:0]sA,sB;

  assign sA = {A[1],A[1],A};
  assign sB = {B[1],B[1],B};

  wire carry;
  wire signed[3:0] A1;
  wire signed[3:0] A2;
  wire signed[4:0] sum0;

  and(A1[0],sA[0],sB[0]);
  and(A1[1],sA[1],sB[0]);
  and(A1[2],sA[2],sB[0]);
  and(A1[3],sA[3],sB[0]);


  assign A2[0] = 0;
  and(A2[1],sA[0],sB[1]);
  and(A2[2],sA[1],sB[1]);
  and(A2[3],sA[2],sB[1]);

  // FIXME: Notice that I am passing -A2, the simulator will
  // negate the signal automatically. Maybe for your assignment
  // you are requried to expand this using logic primitives...
  adder4bit a1(.A(A1),.B(-A2),.Co(carry),.sum(sum0));
  assign C[0] = sum0[0];
  assign C[1] = sum0[1];
  assign C[2] = sum0[2];
  assign C[3] = sum0[3];
endmodule

module adder4bit(A,B,sum,Co);
  input signed[3:0]A,B;
  output signed [4:0]sum;
  wire signed[4:0]a,b;
  output Co;
  wire [4:1] w;  
  wire Ci;
  assign Ci = 1'b0;
  assign a = {A[3],A};
  assign b = {B[3],B};
  
  
  FA a0(.A(a[0]),.B(b[0]),.Ci(Ci),.sum(sum[0]),.Co(w[1]));
  FA a1(.A(a[1]),.B(b[1]),.Ci(w[1]),.sum(sum[1]),.Co(w[2]));
  FA a2(.A(a[2]),.B(b[2]),.Ci(w[2]),.sum(sum[2]),.Co(w[3]));
  FA a3(.A(a[3]),.B(b[3]),.Ci(w[3]),.sum(sum[3]),.Co(w[4]));
  FA a4(.A(a[4]),.B(b[4]),.Ci(w[4]),.sum(sum[4]),.Co(Co));
endmodule


module FA(A,B,Ci,Co,sum);
    
  input A,B,Ci;
  output sum,Co;

  assign sum = (A^B)^Ci;
  assign Co = (B&Ci) | (A&Ci) | (A&B);
    
endmodule
相关问题