转自:http://www.cnblogs.com/haigege/archive/2011/09/28/2194687.html
《数字系统设计与Verilog HDL》上面有这么一段代码,用于实现8位4级流水线加法器。
module adder8pip(cout,sum,cin,ina,inb,clk
);
input cin,clk;
input [7:0] ina,inb;
output cout;
output [7:0] sum;
reg cout,tempcin;
reg [7:0] sum,tempa,tempb;
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;tempa=ina;tempb=inb;//输入数据缓存
end
always @ (posedge clk)
begin
{firstco,firstsum}=tempa[1:0]+tempb[1:0]+tempcin;//第一级低2位相加
firstina=tempa[7:2];firstinb=tempb[7:2];//未参加计算的数据缓存
end
always @ (posedge clk)
begin
{secondco,secondsum}={firstina[1:0]+firstinb[1:0]+firstco,firstsum};//第二级2位相加,并与前一级结果合并
secondina=firstina[5:2];secondinb=firstinb[5:2];//未参加计算的数据缓存
end
always @ (posedge clk)
begin
{thirdco,thirdsum}={secondina[1:0]+secondinb[1:0]+secondco,secondsum};//第三级2位相加,并与前一级结果合并
thirdina=secondina[3:2];thirdinb=secondinb[3:2];//未参加计算的数据缓存
end
always @ (posedge clk)
begin
{cout,sum}={thirdina[1:0]+thirdinb[1:0]+thirdco,thirdsum};//第四级最高2位相加,并与前一级结果合并
end
endmodule
在网上找原因,原来是因为在后面三级的加法运算中,比如第二级:
module adder8pip(cout,sum,cin,ina,inb,clk
);
input cin,clk;
input [7:0] ina,inb;
output cout;
output [7:0] sum;
reg cout,tempcin;
reg [7:0] sum,tempa,tempb;
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;tempa=ina;tempb=inb;//输入数据缓存
end
always @ (posedge clk)
begin
{firstco,firstsum}=tempa[1:0]+tempb[1:0]+tempcin;//第一级低2位相加,由于没有{}限位,因此不需要扩展位
firstina=tempa[7:2];firstinb=tempb[7:2];//未参加计算的数据缓存
end
always @ (posedge clk)
begin
{secondco,secondsum}={{1'b0,firstina[1:0]}+{1'b0,firstinb[1:0]}+firstco,firstsum};//第二级2位相加,并与前一级结果合并
secondina=firstina[5:2];secondinb=firstinb[5:2];//未参加计算的数据缓存
end
always @ (posedge clk)
begin
{thirdco,thirdsum}={{1'b0,secondina[1:0]}+{1'b0,secondinb[1:0]}+secondco,secondsum};//第三级2位相加,并与前一级结果合并
thirdina=secondina[3:2];thirdinb=secondinb[3:2];//未参加计算的数据缓存
end
always @ (posedge clk)
begin
{cout,sum}={{1'b0,thirdina[1:0]}+{1'b0,thirdinb[1:0]}+thirdco,thirdsum};//第四级最高2位相加,并与前一级结果合并
end
endmodule
该代码用ISE综合没有报错,但是发现RTL电路仍然不符合要求,想不通,怀疑难道综合器有问题。于是装上Synplify,再综合,还真没问题了,而且界面很好看。