verilog中的事件计数器

时间:2015-09-30 17:24:19

标签: verilog

我是一个verilog初学者,我试着在verilog上写一个“事件计数器”....这是我的代码,但它只能用“period”设置为16'b0000000000000001,如果尝试设置周期到16'b0000000000001000,结果(out_event)始终为'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

提前致谢

2 个答案:

答案 0 :(得分:0)

计数器计算in_event线的posedge数。那么,你可以使用 @(posedge in_event)吗?

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

我对硬件合成知之甚少,但就个人而言,我建议根据时钟的边沿/等级编写逻辑。

此代码完全正常。看看这个link

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

答案 1 :(得分:0)

我想出了一个测试台,并针对您的问题进行了设计。

    `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