/*******************8位2级流水加法器*************************/
module add8(cout, sum, ina, inb, cin, enable);
output cout;
output [7:0] sum;
input [7:0] ina, inb;
input cin, enable;
reg cout;
reg [7:0] sum;
reg [3:0] tempa, tempb, firsts;
reg firstc;
always @(posedge enable)
begin
{firstc,firsts} <= ina[3:0] + inb[3:0] + cin;
tempa <= ina[7:4]; //高4位输入寄存,
tempb <= inb[7:4]; //使其与sum低4位在下级流水线同步输入。
//否则sum的高4位与低四位分两个时钟周期输出
end
always @(posedge enable)
begin
{cout,sum[7:4]} <= tempa + tempb + firstc;
sum[3:0] <= firsts;
//不能合并为{cout, sum} = {tempa + tempb + firstc, firsts}; 位宽不匹配
end
endmodule
parameter DELY=80;
initial
begin
enable=0;
ina=8'b0;inb=8'b0;cin=1'b0;
#DELY ina=1;inb=1;
#DELY ina=20;inb=20;cin=1;
#DELY ina=75;inb=75;cin=1;
#DELY ina=128;inb=128;cin=0;
#DELY ina=200;inb=200;cin=0;
#DELY $stop;
$display("Running testbench");
end
always
begin
#(DELY/2) enable=~enable;
end
/*******************8位4级流水线加法器*************************/
module adder_8(clk,ina,inb,cin,cout,sum);
input [7:0] ina,inb;
input cin,clk;
output reg cout;
output reg [7:0] sum;
reg tempcin;
reg [7:0] tempina,tempinb;
reg firstco,secondco,thirdco; //前三级加法器进位输出
reg [1:0] firstsum,thirdina,thirdinb;
reg [3:0] secondsum,secondina,secondinb;
reg [5:0] thirdsum,firstina,firstinb;
//输入数据缓存
always @(posedge clk)
begin
tempcin <= cin;
tempina <= ina;
tempinb <= inb;
end
//第一级
always @(posedge clk)
begin
{firstco,firstsum} <= tempina[1:0]+tempinb[1:0]+tempcin; //第一级
firstina <= tempina[7:2]; //高6位输入寄存
firstinb <= tempinb[7:2];
end
//第二级
always @(posedge clk)
begin
{secondco,secondsum[3:2]} <= firstina[1:0]+firstinb[1:0]+firstco;
secondsum[1:0] <= firstsum; //不能合并为{secondco,secondsum} = {firstina[1:0]+firstinb[1:0]+firstco,firstsum}; 位宽不匹配
secondina <= firstina[5:2];
secondinb <= firstinb[5:2];
end
//第三级
always @(posedge clk)
begin
{thirdco,thirdsum[5:4]} <= secondina[1:0]+secondinb[1:0]+secondco;
thirdsum[3:0] <= secondsum;
thirdina <= secondina[3:2];
thirdinb <= secondinb[3:2];
end
//第四级
always @(posedge clk)
begin
{cout,sum[7:6]} <= thirdina[1:0]+thirdinb[1:0]+thirdco;
sum[5:0] <= thirdsum;
end
endmodule
parameter DELY=80;
initial
begin
clk=0;
ina=8'b0;inb=8'b0;cin=1'b0;
#DELY ina=1;inb=1;
#DELY ina=20;inb=20;cin=1;
#DELY ina=75;inb=75;cin=1;
#DELY ina=128;inb=128;cin=0;
#DELY ina=200;inb=200;cin=0;
#DELY $stop;
$display("Running testbench");
end
always
begin
#(DELY/2) clk=~clk;
end
//本文档于2019/10/22日更新,将Verilog源程序中阻塞赋值改为非阻塞赋值,并更新了modelsim仿真波形图
//若文档有任何错误或不足,欢迎在博客下方留言指正;