Verilog 为什么定时器输出未知?

Verilog 为什么定时器输出未知?,verilog,Verilog,我刚开始在Verilog中建立计数计时器,输出结果一直是未知的 我使用50MHz osciliator和以下变量作为代码: 最小:秒:1/100秒 a b:c d:e f 例如,我希望计时器为: 00:00:99 > 00:01:00 ... 00:59:99 > 1:00:00 `timescale 1ns / 1ps module tb_timer(); parameter clk_period = 10; parameter N = 19; reg clk; reg

我刚开始在Verilog中建立计数计时器,输出结果一直是未知的

我使用50MHz osciliator和以下变量作为代码:

最小:秒:1/100秒

a b:c d:e f

例如,我希望计时器为:

00:00:99 > 00:01:00
...
00:59:99 > 1:00:00
<试验台>

`timescale 1ns / 1ps

module tb_timer();

parameter clk_period = 10;
parameter N = 19;

reg clk; 
reg [N-1:0]count;

wire [3:0]a;
wire [3:0]b;
wire [3:0]c;
wire [3:0]d;
wire [3:0]e;
wire [3:0]f;

//instatiate the module 
timer U0(
    .count(count),
    .clk(clk),
    .a(a),
    .b(b),
    .c(c),
    .d(d),
    .e(e),
    .f(f));



// clk signal
always begin
 clk =0;
 forever #(clk_period/2)clk = ~clk;
end

// count signal 
always begin
f = 1'b0
count = 1'b0;
forever #clk_period count = ~count;
end

//reset signal
initial begin
reset = 1;
#12 reset = 0;
#(clk_period) reset = 0;
end

endmodule

假设您在测试台中将
f
声明为
wire
,并将其连接到
timer
f
输出,我的模拟器会在这一行上给我一个编译错误:

f = 1'b0;
使用程序分配驱动导线是非法的

你的直觉是正确的;您需要初始化
f
。它在
timer
内声明为
reg
,这意味着它初始化为X

这通常是通过向您的设计中添加重置输入信号来完成的,您可以从测试台上驱动该信号。断言前几个时钟周期的重置,然后释放它。您可能应该重置设计中的所有寄存器

always@(posedge clk or posedge reset) 
begin
    if (reset) f = 4'b0000;
    else if (f == 4'b1010)       f = 4'b0000;
    else if (count == 19'd500000)   f = f+4'b0001;
end 

这些是有效的Verilog代码。 谢谢你的帮助

module timer    (clk,
         reset,
             a,
             b,
             c,
             d,
             e,
             f,
             count);

input clk;
input reset;
input [18:0]count;

output reg[3:0]a;
output reg[3:0]b;
output reg[3:0]c;
output reg[3:0]d;
output reg[3:0]e;
output reg[3:0]f;


always@(posedge clk or negedge reset) 
begin
    if (~reset)             f <= 4'b0000;
    else if (f == 4'b1010)          f <= 4'b0000;
    else if (count == 19'd500000)   f <= f + 4'b0001;
end 

always@(posedge clk or negedge reset) 
begin   
    if (~reset)             e <= 4'b0000; 
    else if (e == 4'b1010)          e <= 4'b0000;
    else if (f == 4'b1010)          e <= e +4'b0001;
end 

always@(posedge clk or negedge reset) 
begin
    if (~reset)             d <= 4'b0000;
    else if (d == 4'b1010)          d <= 4'b0000;
    else if (e == 4'b1010)          d <= d +4'b0001;
end 

always@(posedge clk or negedge reset) 
begin
    if (~reset)             c <= 4'b0000;
    else if (c == 4'b1010)          c <= 4'b0000;
    else if (d == 4'b1010)          c <= c +4'b0001;
end 

always@(posedge clk or negedge reset) 
begin
    if (~reset)             b <= 4'b0000;
    if (b == 4'b1010)               b <= 4'b0000;
    else if (c == 4'b0101)          b <= b +4'b0001;
end 

always@(posedge clk or negedge reset) 
begin
    if (~reset)             a <= 4'b0000;
    if (a == 4'b1010)           a <= 4'b0000;
    else if (b == 4'b1010)          a <= a +4'b0001;
end 

endmodule
  • 初始块只执行一次,不作为硬件执行
  • module timer    (clk,
             reset,
                 a,
                 b,
                 c,
                 d,
                 e,
                 f,
                 count);
    
    input clk;
    input reset;
    input [18:0]count;
    
    output reg[3:0]a;
    output reg[3:0]b;
    output reg[3:0]c;
    output reg[3:0]d;
    output reg[3:0]e;
    output reg[3:0]f;
    
    
    always@(posedge clk or negedge reset) 
    begin
        if (~reset)             f <= 4'b0000;
        else if (f == 4'b1010)          f <= 4'b0000;
        else if (count == 19'd500000)   f <= f + 4'b0001;
    end 
    
    always@(posedge clk or negedge reset) 
    begin   
        if (~reset)             e <= 4'b0000; 
        else if (e == 4'b1010)          e <= 4'b0000;
        else if (f == 4'b1010)          e <= e +4'b0001;
    end 
    
    always@(posedge clk or negedge reset) 
    begin
        if (~reset)             d <= 4'b0000;
        else if (d == 4'b1010)          d <= 4'b0000;
        else if (e == 4'b1010)          d <= d +4'b0001;
    end 
    
    always@(posedge clk or negedge reset) 
    begin
        if (~reset)             c <= 4'b0000;
        else if (c == 4'b1010)          c <= 4'b0000;
        else if (d == 4'b1010)          c <= c +4'b0001;
    end 
    
    always@(posedge clk or negedge reset) 
    begin
        if (~reset)             b <= 4'b0000;
        if (b == 4'b1010)               b <= 4'b0000;
        else if (c == 4'b0101)          b <= b +4'b0001;
    end 
    
    always@(posedge clk or negedge reset) 
    begin
        if (~reset)             a <= 4'b0000;
        if (a == 4'b1010)           a <= 4'b0000;
        else if (b == 4'b1010)          a <= a +4'b0001;
    end 
    
    endmodule
    
    // <test bench>
    
    
    `timescale 1ns / 1ps
    
    module tb_timer();
    
    parameter clk_period = 10;
    parameter N = 19;
    
    reg clk; 
    reg [N-1:0]count;
    reg reset;
    
    wire [3:0]a;
    wire [3:0]b;
    wire [3:0]c;
    wire [3:0]d;
    wire [3:0]e;
    wire [3:0]f;
    
    //instatiate the module 
    timer U0(
        .reset(reset),
        .count(count),
        .clk(clk),
        .a(a),
        .b(b),
        .c(c),
        .d(d),
        .e(e),
        .f(f));
    
    
    //reset signal 
    initial begin 
    reset = 1;
    #13 reset = 0;
    #(clk_period)reset =1;
    end
    
    // clk signal
    always begin
     clk =0;
     forever #(clk_period/2)clk = ~clk;
    end
    
    // count signal 
    always begin
    count = 0;
    forever #(clk_period/5)count = count + 19'b0000000000000000001;
    end
    
    //reset signal
    initial begin
    reset = 1;
    #12 reset = 0;
    #(clk_period) reset = 0;
    end
    
    endmodule
    
    // count signal 
    always begin
    count = 0;
    forever #(clk_period/5)count = count + 19'b0000000000000000001;
    end