verilog中的事件计数器

verilog中的事件计数器,verilog,Verilog,我是一个verilog初学者,我正在尝试在verilog上写一个事件计数器。。。。这是我的代码,但它仅在周期设置为16'b0000000000000001时有效,如果尝试将周期设置为16'b0000000000001000,则resultout_事件始终为“0”。 有人能帮我修一下吗 module mymodule( input wire clk, input wire enable, input wire

我是一个verilog初学者,我正在尝试在verilog上写一个事件计数器。。。。这是我的代码,但它仅在周期设置为16'b0000000000000001时有效,如果尝试将周期设置为16'b0000000000001000,则resultout_事件始终为“0”。 有人能帮我修一下吗

module mymodule(
    input  wire          clk,
    input  wire             enable,
    input  wire             reset, 
    input    wire [15:0]        period,
    input    wire              in_event, 
    output reg                  out_event            
);

reg en = 1'b0; 
reg re = 1'b0;
reg [15:0] count = 16'b0000000000000000;
always @(posedge clk) en <= enable;
always @(posedge clk) re <= reset;


always @(in_event)begin


if(in_event == 1'b1)begin
if(re)begin
    count <= 0 ; 
    out_event <= 1'b0;
end else begin
    if(en) begin
        if(count == period-1)begin
            out_event <= 1'b1;
            count <= 0;
        end else begin
            count <=count + 1;
            out_event <= 1'b0;
        end
    end else begin
        out_event <= 1'b0;
    end
end

end else begin
    out_event <= 1'b0;

end

end 

endmodule

提前感谢

计数器统计in_事件线的posedge数。那么,你能在事件中使用@posedge吗

我模拟了你的代码,为它提供了一个测试平台

我不太了解硬件合成,但就个人而言,我建议根据时钟的边缘/电平编写逻辑

这段代码运行得非常好。看看这个


您可以在testbench中配置各种period值,希望这会有所帮助。

我为您的问题提供了一个测试台和设计,它可以正常工作

    `timescale 1s / 1s

module TB();
    reg clk;
    reg enable;
    reg reset;
    reg [15:0] period;
    wire out_event;
    wire [15:0] counter;

    initial begin
        clk = 1'b0;
        forever begin
            #1 clk = ~clk;
        end
    end

    stack_exch_code test (.clk(clk),
                          .enable(enable),
                          .reset(reset),
                          .period(period),
                          .out_event(out_event),
                          .tb_counter(counter)
                          );

    integer i;

    initial
        begin
            @(negedge clk) reset = 1'b1; enable = 1'b0; period = 16'h0000;
            @(negedge clk) reset = 1'b0; enable = 1'b1; period = 16'h00FF;
            for (i = 0 ; i < 500 ; i = i + 1)   begin
                @(negedge clk) period = period - 1; 
                @(posedge clk) $display ("Period = %h , Counter = %h, Out_Event = %b ", period, counter, out_event);
            end
            @(negedge clk) $finish;

        end

endmodule //TB

module stack_exch_code (input clk,
                        input enable,
                        input reset,
                        input [15:0] period,
                        //input inevent,
                        output reg out_event,
                        output [15:0] tb_counter
                        );

    // initialization doesnt matter in hardware, its not C or C++
    reg en;
    reg re;
    reg [15:0] count;

    always @ (posedge clk)  begin

        re <= reset;
        en <= enable;

    end

    always @ (posedge clk) begin

        if (re) begin

            count <= 16'h0000;
            out_event <= 1'b0;

        end 

        else if (en) begin

            if ((count == period - 1) && !(period == 16'h0000)) begin

                out_event <= 1'b1;
                count <= 16'h0000;

            end

            else if (!(period == 16'h0000)) begin

                count <= count + 1;
                out_event <= 1'b0;

            end

            else if (period == 16'h0000)

                out_event <= 1'b0;

        end
    end

    assign tb_counter = count;

endmodule //stack_exch_code

提示:任何flop分配都应该在您的always@posedge clk块内。任何梳状逻辑都应该位于always@*block my preference或assign语句中。您当前的逻辑使用复杂锁存,这是不推荐的。您好,谢谢您的帮助,如果使用@posedge in_事件计数器工作,但将周期设置为16'b0000000000000001,则out out_事件始终设置为1'b1。我试着模拟代码,但当我合成它时,它就不起作用了work@Foo正如Greg提到的,您正在使用复杂的锁存设置来检测事件中的更改。大多数合成工具都难以进行这样的描述,即使它们成功了,也可能有许多计时场景会导致电路以不希望的方式运行。你真的应该改变你的设计,使用同步采样而不是异步锁存。耶,虽然我对合成知之甚少,但我完全同意Unn的观点,同步采样使之成为一个触发器而不是锁存器。