为什么定时器输出未知?
Why is the timer output unknown?
我刚开始在 Verilog 中构建递增计数定时器,但输出一直未知。
我在代码中使用 50MHz 振荡器和这些变量:
分钟:秒:1/100 秒
a b : c d : ef
例如,我希望定时器为:
00:00:99 > 00:01:00
...
00:59:99 > 1:00:00
module timer (clk,
a,
b,
c,
d,
e,
f,
count);
input clk;
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)
begin
if (f == 4'b1010) f = 4'b0000;
else if (count == 19'd500000) f = f+4'b0001;
end
always@(posedge clk)
begin
if (e == 4'b1010) e = 4'b0000;
else if (f == 4'b1010) e = e +4'b0001;
end
always@(posedge clk)
begin
if (d == 4'b1010) d = 4'b0000;
else if (e == 4'b1010) d = d +4'b0001;
end
always@(posedge clk)
begin
if (c == 4'b1010) c = 4'b0000;
else if (d == 4'b1010) c = c +4'b0001;
end
always@(posedge clk)
begin
if (b == 4'b1010) b = 4'b0000;
else if (c == 4'b0101) b = b +4'b0001;
end
always@(posedge clk)
begin
if (a == 4'b1010) a = 4'b0000;
else if (c == 4'b1010) a = a +4'b0001;
end
endmodule
<测试台>
`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
// <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
<我错过的事情>
- Flip Flop的初始值只有在有reset输入时才需要设置
- 在测试台中,计数器应该是
// count signal
always begin
count = 0;
forever #(clk_period/5)count = count + 19'b0000000000000000001;
end
- 初始块只执行一次,不作为硬件综合。
我刚开始在 Verilog 中构建递增计数定时器,但输出一直未知。
我在代码中使用 50MHz 振荡器和这些变量:
分钟:秒:1/100 秒
a b : c d : ef
例如,我希望定时器为:
00:00:99 > 00:01:00
...
00:59:99 > 1:00:00
module timer (clk,
a,
b,
c,
d,
e,
f,
count);
input clk;
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)
begin
if (f == 4'b1010) f = 4'b0000;
else if (count == 19'd500000) f = f+4'b0001;
end
always@(posedge clk)
begin
if (e == 4'b1010) e = 4'b0000;
else if (f == 4'b1010) e = e +4'b0001;
end
always@(posedge clk)
begin
if (d == 4'b1010) d = 4'b0000;
else if (e == 4'b1010) d = d +4'b0001;
end
always@(posedge clk)
begin
if (c == 4'b1010) c = 4'b0000;
else if (d == 4'b1010) c = c +4'b0001;
end
always@(posedge clk)
begin
if (b == 4'b1010) b = 4'b0000;
else if (c == 4'b0101) b = b +4'b0001;
end
always@(posedge clk)
begin
if (a == 4'b1010) a = 4'b0000;
else if (c == 4'b1010) a = a +4'b0001;
end
endmodule
<测试台>
`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
// <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
<我错过的事情>
- Flip Flop的初始值只有在有reset输入时才需要设置
- 在测试台中,计数器应该是
// count signal
always begin
count = 0;
forever #(clk_period/5)count = count + 19'b0000000000000000001;
end
- 初始块只执行一次,不作为硬件综合。