yuantielei 发表于 2011-7-26 18:48:19

大家来看下小弟编的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后变乱了!!!为什么啊?如果仅做加计数或仅减计数的话仿真就正常的。

yuantielei 发表于 2011-7-27 08:23:51

大家都没遇到过这个问题吗?

Jach 发表于 2011-7-27 15:18:31

回复【1楼】yuantielei
-----------------------------------------------------------------------

else if (sub)

panda1130 发表于 2011-7-27 15:28:23

可用同步时钟驱动的方式试试

yuantielei 发表于 2011-7-27 18:21:05

else if (sub)
是不行的,我试过了。。。

什么是“同步时钟驱动的方式"???

shawnelee88 发表于 2011-7-28 02:07:26

同步时钟驱动就是加上个时钟信号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

306468117 发表于 2011-7-28 15:51:36

你这个计数器没有时钟信号。综合的结果不可能生成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

panda1130 发表于 2011-7-28 15:53:39

用一个同步时钟作为进程的激励,而不是用add或sub,否则就是异步电路了。在进程中检测add和sub信号的上跳沿,再根据不同情况作处理。
供参考。

yuantielei 发表于 2011-7-28 21:49:02

谢谢大家的帮助,就是这个同步时钟的问题了!
现在好了。谢谢。。。。。。。。。

colinedeng 发表于 2011-7-29 11:47:21

always里的信号就之要rst!
页: [1]
查看完整版本: 大家来看下小弟编的verilog HDL 加减计数器怎么不能在 Quartus 8.1 仿真?