用Icarus Verilog模拟程序计数器设计时的无限循环

用Icarus Verilog模拟程序计数器设计时的无限循环,verilog,infinite-loop,program-counter,icarus,Verilog,Infinite Loop,Program Counter,Icarus,我正在用以下原型实现一个简单的程序计数器加法器: module program_counter(input enable_count, input enable_overwrite, input[31:0] overwrite_value, output[31:0] out); 当使用Icarus Verilog进行模拟时,我在

我正在用以下原型实现一个简单的程序计数器加法器:

module program_counter(input        enable_count,
                       input        enable_overwrite,
                       input[31:0]  overwrite_value,
                       output[31:0] out);
当使用Icarus Verilog进行模拟时,我在第一个刻度处得到一个无限循环,在该循环上禁用覆盖并启用计数,因此内部寄存器由PC加法器(PC+4)的输出馈送

我将问题简化为一段基本代码,其中D触发器用作1位寄存器:

module register(input in, input set, output out);

    wire not_in;
    wire q0;
    wire not_q0;
    wire not_q;

    nand (q0, in, set);

    not  (not_in, in);
    nand (not_q0, not_in, set);

    nand (out, q0, not_q);
    nand (not_q, not_q0, out);

endmodule

module test;

    reg  clock;
    reg  in;
    wire out;
    wire not_out;

    xor (x_out, out, 1);                // add
    or  (muxed_out, x_out, in);         // mux

    register r(muxed_out, clock, out);

    initial
    begin
        $dumpfile("test.vcd");
        $dumpvars(0, test);

        $display("\tclock,\tin,\tout");
        $monitor("\t%b,\t%x,\t%b",
                 clock, in, out);

        #0 assign in = 1;               // erase register
        #0 assign clock = 1;

        #1 assign in = 0;
        #1 assign clock = 0;

        #2 assign clock = 1;
        #3 assign clock = 0;
        #4 assign clock = 1;
    end

endmodule
VCD输出在模拟卡滞后不显示任何状态变化

我的猜测是,在一个特定的滴答声中,加法器不断地输入一个不同的值(不断地添加),因此,由于它不稳定,模拟器正在等待该值被固定,并被卡住


这种设计正确吗(即可以合成并假设工作)?

有一个组合回路:“寄存器”的输出通过测试中的异或门反馈到其输入。实际上,您已经创建了一个

如果在寄存器中添加以下代码,则可以看到这种情况:

  always @(in) $display("@%d: in = %d", $time, in);
当您运行解释器时,您将看到以下内容:

@                   1: in = 1
@                   1: in = 0
@                   1: in = 1
@                   1: in = 0
看起来您正试图在“寄存器”中启用闩锁。这是你的本意吗?边触发触发器是同步设计中的常规做法。要做到这一点,您需要两个背对背的锁存器,但在Verilog中实现这一点的标准(更简单)方法如下:

reg my_flop;

always @(posedge clk)
   my_flop <= input;

您尝试使用gates手动创建这些关键字有什么原因吗?

尝试删除代码中的所有
assign
关键字。注意!我已经尝试删除它们,但它无法解决问题。谢谢!事实上,我完全忽略了这样一个事实:这里没有边缘触发的数据触发器,而是一个简单的数据锁存器,它可以无限地写入自身。至于为什么我想用门手动创建这个,我觉得最好是通过更接近裸晶体管来学习,并且基本上写下模拟器将从RTL描述中生成什么。我不知道这是否有意义,我明白了。请注意,RTL模拟器通常将触发器作为一个单元进行建模,而不是将其进一步分解(即使您为ASIC合成了Verilog,它也会将触发器映射到单个单元)
always @(clk, input)
begin
    if (clk)
        my_flop = input;
end