这段verilog代码是不是有问题啊,仿真波形错误啊?
从书上抄的一个例子:
module pipeline(cout,sum,ina,inb,cin,clk);
output [7:0] sum;
output cout;
input [7:0] ina;
input [7:0] 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;
reg [3:0] secondb;
reg [3:0] 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
自己写了一个激励文件:
`timescale 10ns / 1ns
module pipeline_tb;
//Internal signals declarations:
wire cout;
wire [7:0]sum;
reg [7:0]ina;
reg [7:0]inb;
reg cin;
reg clk;
parameter dely=10;
// Unit Under Test port map
pipeline UUT (
.cout(cout),
.sum(sum),
.ina(ina),
.inb(inb),
.cin(cin),
.clk(clk));
always #(dely/2)clk=~clk;
initial
begin
clk=0;
cin=0;
ina=8'b0;
inb=8'b0;
#(dely*1000) $finish;
end
always #(10*dely) cin=$random;
always #(10*dely) ina=$random;
always #(10*dely) inb=$random;
initial
$monitor($realtime,,"ps %h %h %h %h %h %h ",cout,sum,ina,inb,cin,clk);
endmodule
但是仿真出来的波形明显不对啊

就是中间那组数据有一位算错了。估计是连续进位的问题。
[ 本帖最后由 langhuamin 于 2007-11-23 08:31 编辑 ]
问题是,为何第一个进位正确,而后面的两个进位就错误了?这属于什么问题?
据猜测,程序可能有问题。
{thirdco,thirds}={seconda[1:0]+secondb[1:0]+secondco,seconds};PCB
其中,{seconda[1:0]+secondb[1:0]+secondco,seconds}是6位,{thirdco,thirds}是7位,
导致最高进位出现问题。
此属推断,待验证。
可以尝试先将second[2:0]=seconda[1:0]+secondb[1:0]+secondco;
再{thirdco,thirds}={second[2:0],seconds};
不过我这边现在没装这个工具软件。
[ 本帖最后由 langhuamin 于 2007-11-23 18:40 编辑 ]
回去试了一下,确实如此。
而且程序段可以作以下简化:
reg [8:0]ins;
always @(posedge clk)
begin
tempa<=ina;
tempb<=inb;
tempci<=cin;
end
always @(posedge clk)
begin
ins=tempa+tempb+tempc;
{cout,sum}={ins};
end
虽然没错
这样的代码综合出来比流水线效率低
综合出来用的器件也多哈
呵呵
这个问题我也注意到了
但问题在于为何第一也是这样的效果为何就有进位变化
而只有后面的两个有错误?
不知道是否与verilog语言本事有关系?
我自己试了试
如何在加之前先把2位的值赋值给一个3位的值
这样就能保证赋值间的位数一样
这样进位的值就不会丢失了
也可以说是verilog本身的原因吧,
因为这里{thirdco,thirds}={seconda[1:0]+secondb[1:0]+secondco,seconds}
并不是将右边计算完后得出的数据直接放入{thirdco,thirds}中的,
这里{}={};在次序上是先将里面的算完得出运算结果(这时已经确定位数),然后再把结果作=处理。分两步进行。
本质上与second[2:0]=seconda[1:0]+secondb[1:0]+secondco;不一样。
一开始我也想到“在加之前先把2位的值赋值给一个3位的值”,这个方法和我说的那个原理类似。PCB
呵呵,这个我倒没考虑过
你可以参看一些教程里面的综合结果实例对比
代码不同效率不一样 虽然结果相同
嗯好的,有机会会多去看看的.呵呵
