一、存在的问题
初稿参考《Verilog HDL程序设计教程》王金明编著。但是这个教材存在问题,源码如下:module pipeline
(
cout, sum, ina, inb, cin, clk
);
output [7:0] sum;
output cout;
input [7:0] ina, inb;
input cin, clk;
reg [7:0] tempa, tempb, sum;
reg tempci, firstco, secondco, thirdco, cout;
reg [1:0] firsts, thirda, thirdb;
reg [3:0] seconda, secondb, seconds;
reg [5:0] firsta, firstb, thirds;
always @(posedge clk)
begin
tempa <= ina;
tempb <= inb;
tempci <= cin;
end
always @(posedge clk)
begin
{firstco , firsts} <= tempa [1:0] + tempb [1:0] +tempci;
firsta <= tempa [7:2];
firstb <= tempb [7:2];
end
always @(posedge clk)
begin
{secondco , seconds} <= {firsta [1:0] + firstb [1:0] + firstco , firsts};
seconda <= firsta [5:2];
secondb <= firstb [5:2];
end
always @(posedge clk)
begin
{thirdco , thirds} <= {seconda [1:0] + secondb [1:0] + secondco , seconds};
thirda <= seconda [3:2];
thirdb <= secondb [3:2];
end
always @(posedge clk)
begin
{cout , sum} <= {thirda[1:0] + thirdb [1:0] +thirdco , thirds};
end
endmodule
综合过后的RTL视图下,上述红色框中,cout作为进位位,实际上cout的D触发器的输入端并没有信号输入,原因是:
①{secondco , seconds} <= {firsta [1:0] + firstb [1:0] + firstco , firsts};
② {thirdco , thirds} <= {seconda [1:0] + secondb [1:0] + secondco , seconds};
③ {cout , sum} <= {thirda[1:0] + thirdb [1:0] +thirdco , thirds};
这几行代码中,在综合过程中,①右边自动被限制为四位,在综合过程中,secondco不会得到正确的进位值,②③同理。参考:8位4级流水线加法器verilog程序 - 豆丁网 (docin.com)
如:①修改为:{secondco , seconds} <= {{1'b0,firsta [1:0]} + {1'b0,firstb [1:0]} + firstco , firsts};另外几个同理。
二、改进源码如下
方法1,加了缓存数据的寄存器,每一级都进行缓存。
module pipeline
(
output reg cout,
output reg[7:0] sum,
input wire[7:0] ina,
input wire[7:0] inb,
input wire cin,
input wire clk
);
reg ci0_reg, ci1_reg,ci2_reg,ci3_reg;
reg[1:0] temp1_reg;
reg[3:0] temp2_reg;
reg[5:0] temp3_reg;
reg[5:0] firstTemp_a,firstTemp_b;
reg[3:0] secondTemp_a,secondTemp_b;
reg[1:0] thirdTemp_a,thirdTemp_b;
reg[7:0] inputa,inputb;
always@(posedge clk)
begin
inputa <= ina;
inputb <= inb;
ci0_reg <= cin;
end
always@(posedge clk)
begin
{ci1_reg,temp1_reg} <= inputa[1:0] + inputb[1:0] + ci0_reg;
firstTemp_a <= inputa[7:2];
firstTemp_b <= inputb[7:2];
end
always@(posedge clk)
begin
{ci2_reg,temp2_reg} <= {{1'b0,firstTemp_a[1:0]} + {1'b0,firstTemp_b[1:0]} + ci1_reg,temp1_reg};
secondTemp_a <= firstTemp_a[5:2];
secondTemp_b <= firstTemp_b[5:2];
end
always@(posedge clk)
begin
{ci3_reg,temp3_reg} <= {{1'b0,secondTemp_a[1:0]} + {1'b0,secondTemp_b[1:0]} + ci2_reg,temp2_reg};
thirdTemp_a <= secondTemp_a[3:2];
thirdTemp_b <= secondTemp_b[3:2];
end
always@(posedge clk)
begin
{cout,sum} <= {{1'b0,thirdTemp_a} + {1'b0,thirdTemp_b} + ci3_reg,temp3_reg};
end
endmodule
RTL视图:
观察cout端口,现在端口所在的D触发器信号输入端已经有信号输入了。
简单的testbench测试 156 + 149 能不能得到正确的结果。
测试源码如下:
`timescale 1ns/1ns
module tb_pipeline;
wire cout;
wire[7:0] sum;
reg[7:0] ina;
reg[7:0] inb;
reg cin;
reg clk;
initial
begin
ina <= 8'd156;
inb <= 8'd149;
cin <= 1'b0;
clk <= 1'b0;
end
always #10 clk = ~clk;
initial
begin
$timeformat(-9,0,"ns",6);
$monitor("@time %t :ina =%d, inb =%d, cout =%d,sum = %d",$time,ina,inb,cout,sum);
end
pipeline tb_pipeline_instan
(
.cout(cout),
.sum(sum),
.ina(ina),
.inb(inb),
.cin(cin),
.clk(clk)
);
endmodule
仿真结果:
和实际设计要求相符合。
方法二,没有对每一级的没有参与计算的值都进行缓存,只保留了每次计算的结果,其实思路上和前面是一样的,放上这个代码希望能够帮助理解4级流水线的8位全加器。
module pipeline
(
output reg cout,
output reg[7:0] sum,
input wire[7:0] ina,
input wire[7:0] inb,
input wire cin,
input wire clk
);
reg ci0_reg, ci1_reg,ci2_reg,ci3_reg;
reg[1:0] temp1_reg;
reg[3:0] temp2_reg;
reg[5:0] temp3_reg;
reg[5:0] firstTemp_a,firstTemp_b;
reg[3:0] secondTemp_a,secondTemp_b;
reg[1:0] thirdTemp_a,thirdTemp_b;
reg[7:0] inputa,inputb;
always@(posedge clk)
begin
inputa <= ina;
inputb <= inb;
ci0_reg <= cin;
end
always@(posedge clk)
begin
{ci1_reg,temp1_reg} <= inputa[1:0] + inputb[1:0] + ci0_reg;
end
always@(posedge clk)
begin
{ci2_reg,temp2_reg} <= {{1'b0,inputa[3:2]} + {1'b0,inputb[3:2]} + ci1_reg,temp1_reg};
end
always@(posedge clk)
begin
{ci3_reg,temp3_reg} <= {{1'b0,inputa[5:4]} + {1'b0,inputb[5:4]} + ci2_reg,temp2_reg};
end
always@(posedge clk)
begin
{cout,sum} <= {{1'b0,inputa[7:6]} + {1'b0,inputb[7:6]} + ci3_reg,temp3_reg};
end
endmodule
testbench和前面的是一样的。