今天很大一部分时间在解决MAC FIR v5.1上面,我知道这篇博文除了我也许没人能看懂,但借CSDN宝地,我记录下今天的一天……
环境:Xilinx ISE10.1 和 ModelSim SE PLUS 6.2b,FPGA型号似乎不重要,因为一年前和现在我使用的FPGA型号不一样。
其实这是一年前的事了,我在用ModelSim仿真包含MAC FIR v5.1的程序时,MAC FIR v5.1的输出就一直是不确定值,也就是一条红线,我实在是不明白,为什么会是一条红线……
这个坎必须得过,因为我必须得用MAC FIR v5.1 IP核,我就单独仿真MAC FIR v5.1,输出竟然正常了,为什么单独仿真IP核输出正常,而放到其它模块里面就不正常呢?
我想是不是我单独仿真时输入的数据较小,而在模块里面仿真时输入的数据太大呢?好吧,我改,我把在模块里面的FIR的输入改小,改成和单独仿真时的一样,但结果还是不行……
是不是输出端我接线接的不合适了,毕竟在模块里面仿真FIR涉及到很多连接,好吧,我把连接全断开,也不行呀……
到底是什么问题?
为什么单获仿真MAC FIR v5.1时正确而在模块里面仿真时输出就不对了呢?
粘一段代码吧:
module test_fir;
// Inputs
reg CLK;
reg RESET;
reg ND;
reg [14:0] DIN;
// Outputs
wire RDY;
wire RFD;
wire [37:0] DOUT;
// Instantiate the Unit Under Test (UUT)
mac_fir uut (
.CLK(CLK),
.RESET(RESET),
.ND(ND),
.DIN(DIN),
.RDY(RDY),
.RFD(RFD),
.DOUT(DOUT)
);
initial begin
// Initialize Inputs
CLK = 0;
RESET = 0;
ND = 0;
DIN = 0;
// Wait 100 ns for global reset to finish
#100;
// Add stimulus here
end
endmodule
这是建仿真文件时自动生成的一段代码,注意加粗的部分,一般都是延时100ns的,我在单独仿真时未加修改,而在模块仿真时在后面又加了一行代码“#32;”其实是我是为了对时钟的,因为我的时钟是这样输入的“always#4 CLK=~CLK; ”,哎,不管是为了啥吧,反正算是我多此一举啦,反正就是又延时了32ns,怎么地吧!
怎么地?
结果就是让我的仿真结果不对呗……
因为我观察我的仿真波形如下:
正常时:
不正常时如下:
注意两幅图中的RFD信号,正常情况下它是从低变高就不变了,而不正常情况下是由低变高,然后被复位,然后又变高,但却自己变成了不确定状态,这是怎么回事呢?
于是我想到了是不是延时的问题,后来去掉那个32ns的延时果然就可以了,我看了半天手册,也没看出什么行道来,哎,认了吧……
刚才又重试了一下,也不知哪儿的问题,我在那个#100后又加了#90的延时仍然正常,但再大就不正常了,为什么呢?
你知道么?
反正我不知道……
我今天就是瞎写,因为感觉这么一天得到的这点结论不记录下来对不起自己……
网友您如果搜到了本篇文章,就不要看了……
见谅……
附:verilog test fixture代码
module test_mac_fir;
// Inputs
reg CLK;
reg RESET;
reg ND;
reg [14:0] DIN;
reg [14:0] counter,counter_d1,counter_d2,counter_d3,counter_d4,counter_d5,counter_d6;
// Outputs
wire RDY;
wire RFD;
wire [37:0] DOUT;
// Instantiate the Unit Under Test (UUT)
mac_fir uut (
.CLK(CLK),
.RESET(RESET),
.ND(ND),
.DIN(DIN),
.RDY(RDY),
.RFD(RFD),
.DOUT(DOUT)
);
initial begin
// Initialize Inputs
CLK = 0;
RESET = 0;
ND = 0;
DIN = 0;
counter_d1=0;
counter_d2=0;
counter_d3=0;
counter_d4=0;
counter_d5=0;
counter_d6=0;
// Wait 100 ns for global reset to finish
#100;
#90;
RESET = 1;
#800;
RESET = 0;
// Add stimulus here
end
always@(posedge CLK)
if(RESET)
begin
ND<=1;
end
else
begin
ND<=~ND;
end
always@ (posedge CLK)
begin
counter_d1<=counter;
counter_d2<=counter_d1;
counter_d3<=counter_d2;
counter_d4<=counter_d3;
counter_d5<=counter_d4;
counter_d6<=counter_d5;
DIN<=0;
if(RESET)
begin
counter<=14'b11_1111_1111_0000;
counter_d1<=0;
counter_d2<=0;
counter_d3<=0;
counter_d4<=0;
counter_d5<=0;
counter_d6<=0;
end
else
begin
counter<=counter+15'd1;
end
end
always#4 CLK=~CLK;
endmodule