大家来看下小弟编的verilog HDL 加减计数器怎么不能在 Quartus 8.1 仿真?
我的程序是这样的:module AAAA (add, sub, rst, Fn);
input add, sub, rst;
output Fn;
reg Fn;
initial
begin
Fn <= 0;
end
always @ (posedge rst or posedge add or posedge sub)
begin
if (rst)
Fn <= 0;
else if (add)
Fn <= Fn+8'd1;
else
Fn <= Fn - 1;
end
endmodule
http://cache.amobbs.com/bbs_upload782111/files_43/ourdev_661290MG0CU1.jpg
仿真结果图片 (原文件名:FPGA.jpg)
输出Fn计数器值在加1后变乱了!!!为什么啊?如果仅做加计数或仅减计数的话仿真就正常的。 大家都没遇到过这个问题吗? 回复【1楼】yuantielei
-----------------------------------------------------------------------
else if (sub) 可用同步时钟驱动的方式试试 else if (sub)
是不行的,我试过了。。。
什么是“同步时钟驱动的方式"??? 同步时钟驱动就是加上个时钟信号clk
我只会写成两个文件的方式,用testbench来生成激励,代码如下(具体没有仿真过,那个initial中的仿真时间可以自己调一下)
分两个模块写,自己试试看
模块一:
module AAAA (clk,add, sub, rst, Fn);
input clk,add, sub, rst;
output Fn;
reg Fn;
always @ (posedge clk)
begin
if (rst)
Fn <= 0;
else if (add)
Fn <= Fn + 8'd1;
else if (sub)
Fn <= Fn - 8'd1;
else
Fn <= Fn;
end
endmodule
模块二(即测试激励模块)
`timescale 1ns/100ps
module tb_AAA;
reg Fn;
wire clk,add,sub,rst;
AAAA inst_AAA(
.clk(clk),
.add(add),
.sub(sub),
.rst(rst),
.Fn(Fn)
);
initial begin
clk = 0;
add = 0;
sub = 0;
rst = 0;
#100 rst = 1;
#150 rst = 0;
#200 add = 1;
#1000 add = 0;
#100 sub = 1;
end
always #50 clk = ~clk;
endmodule 你这个计数器没有时钟信号。综合的结果不可能生成DFF,最后只能是组合逻辑。对于组合逻辑来说,不能保存中间状态。所以Fn <= Fn+8'd1;这样的语句对于组合逻辑将形成自激振荡。所以你波形乱了。
你应该用时钟去检测add或者sub的上升沿,监测到他们的上升沿后计数器改变。
module mycounter(
input clk,
input rst,
input add,
input sub,
output reg Fn
);
reg radd1, radd2, rsub1, rsub2;
always @(posedge clk or posedge rst)
begin
if(rst)
begin
Fn <= 8'd0;
radd1 <= 1'b0;
radd2 <= 1'b0;
rsub1 <= 1'b0;
rsub2 <= 1'b0;
end
else
begin
//detect posedge of add
radd1 <= add;
radd2 <= radd1;
//detect posedge of sub
rsub1 <= sub;
rsub2 <= rsub1;
if({radd1, radd2} == 2'b10)
Fn <= Fn + 8'd1;
else if({rsub1, rsub2} == 2'b10)
Fn <= Fn - 8'd1;
else
Fn <= Fn;
end
end
endmodule 用一个同步时钟作为进程的激励,而不是用add或sub,否则就是异步电路了。在进程中检测add和sub信号的上跳沿,再根据不同情况作处理。
供参考。 谢谢大家的帮助,就是这个同步时钟的问题了!
现在好了。谢谢。。。。。。。。。 always里的信号就之要rst!
页:
[1]