流水线加法器verilog

流水线加法器verilog

对于位数比较小的数值相加,计算机可以在一个时钟周期内完成相加的过程,比如32位的加法器,我们比较容易满足其定时需求。但是如果我们需要将两个64位的数值相加,计算机就可能不能在一个时钟周期内完成。此时我们可以考虑流水线来解决这个问题。
我们可以使用两个32位的加法器,其中一个加法器执行低32位的加法,在一个时钟周期之后第二个加法器执行高32位的加法,与此同时,下一个64位加法器的低32位加法也在执行。这样,第一组计算结果会出现在两个时钟周期后,但之后的每个时钟周期都会得到一个新值。
代码实现:
语言:verilog
环境:modelsim10.4
加法器:

module adder_pipelined(A,B,clk,reset,FinalSum);
input clk,reset;
input [63:0] A,B;
output [64:0] FinalSum;
/**************************************/
wire carry_d1;
reg [32:0] Lsum_d1;
wire [32:0] Lsum_d1_nxt;
reg [31:0] Lsum_d2;
reg [31:0] Aup_d1,Bup_d2;
reg [32:0] Usum_d2;
wire [32:0] Usum_d2_nxt;
wire [64:0] FinalSum;
/**************************************/
assign Lsum_d1_nxt = A[31:0] + B[31:0];
assign carry_d1 = Lsum_d1[32];
assign Usum_d2_nxt = carry_d1 + Aup_d1 + Bup_d2;
assign FinalSum = {Usum_d2,Lsum_d2};
/**************************************/
always@(posedge clk or negedge reset)begin
 if(!reset)begin
  Lsum_d1 <= 0;
  Lsum_d2 <= 0;
  Aup_d1 <= 0;
  Bup_d2 <= 0;
  Usum_d2 <= 0;
 end
 else begin
  Lsum_d1 <= Lsum_d1_nxt;
  Lsum_d2 <= Lsum_d1_nxt[31:0];
  Aup_d1 <= A[63:32];
  Bup_d2 <= B[63:32];
  Usum_d2 <= Usum_d2_nxt;
 end
end
endmodule

测试代码:

`timescale 1ns/1ns
module testbech;
reg[63:0] A_tb,B_tb;
reg clk_tb,reset_tb;
wire [64:0] FinalSum_tb;
parameter HALF_CLK_PERIOD = 5;
/**************************************/
initial begin
 clk_tb = 0;
 forever #HALF_CLK_PERIOD clk_tb = ~clk_tb;
end
initial begin
 reset_tb = 0;
 #20 reset_tb = 1;
end
initial begin
 A_tb = 64'h2344321432112341;
 B_tb = 64'h1234432143211234;
end
adder_pipelined adder_pipelined_test
  (.A(A_tb),
  .B(B_tb),
  .clk(clk_tb),
  .reset(reset_tb),
  .FinalSum(FinalSum_tb));
endmodule

仿真结果:

在这里插入图片描述


版权声明:本文为qq_39814612原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。