Verilog:为reg赋值
Verilog: assigning value to reg
我有一个关于 Verilog 的非常初级的问题,我希望得到一些帮助。
您可以在下面看到一个简单计数器的代码,它具有:
- 输入:单时钟信号,接时钟
- 输入:复位信号,接物理按键
- 输出:计数器输出
- 输出:led等于复位输入
奇怪的是,当复位信号为高电平时,计数器不会复位为零。
在板上,当我按下按钮时,我可以看到 LED 灯亮起和熄灭,因此重置为真,但 if 指令 internal_counter <= 0;
未执行 (?)
我将 Quartus Prime II Lite 与 DE-10 Nano Terasic 开发板一起使用
有什么建议吗?谢谢!
//Single clock input and a 32bit output port
//reset will zero the internal_counter
module simple_counter (
CLOCK_50,
counter_out,
reset,
led
);
input CLOCK_50 ;
input reset ;
output led;
output [31:0] counter_out;
reg [31:0] counter_out;
reg [31:0] internal_counter;
reg led;
always @ (posedge CLOCK_50) // on positive clock edge
begin
if (reset)
internal_counter <= 0;
led <= reset;
internal_counter <= internal_counter + 1;
counter_out <= internal_counter;// increment counter
end
endmodule // end of module counter
我不知道为什么你的代码不起作用。我现在使用 VHDL。
但是,我会这样写:
module simple_counter (CLOCK_50, reset, led, counter_out);
input CLOCK_50 ;
input reset ;
output led;
output [31:0] counter_out;
reg [31:0] internal_counter;
always @ (posedge CLOCK_50)
begin
if (reset)
internal_counter <= 0;
else
internal_counter <= internal_counter + 1;
led <= reset;
counter_out <= internal_counter;
end
endmodule
您的代码无法运行,因为您对 internal_counter
进行了两次赋值。这是允许的,但规则是 最后一次分配 "wins".
因此,让我们在重置处于活动状态时单步执行代码:
if (reset)
internal_counter <= 0;
这使得 internal_counter
被重置(设置为零)。
但后来我们得到另一个作业:
internal_counter <= internal_counter + 1;
因为这是 later/behind 上一个作业 "wins"。这里有 no 条件所以这个 always 替换了之前的 if ...
。这样 if...
代码就变得多余了。它永远不会执行,综合工具将为此删除任何逻辑。
正如其他人所指出的:您需要一个 else
部分。重置重置部分中的所有变量是一种很好的做法:
always @ (posedge CLOCK_50) // on positive clock edge
begin
if (reset)
begin
internal_counter <= 0;
led <= 1'b1;
counter_out <= 0;
end // reset section
else
begin // clocked section
internal_counter <= internal_counter + 1;
led <= 1'b0;
counter_out <= internal_counter;
end
end // clocked section
现在我们得到一些一般性的评论:
我建议您改用 ANSI 端口定义。当你把所有东西放在一起时,它会更容易。如果您需要更改,例如counter_out
的宽度你可以在一个地方做到这一点:
module simple_counter (
input CLOCK_50 ,
input reset ,
output reg led,
output reg [31:0] counter_out
);
你的led
有点奇怪。复位时为高,否则为低。我假设你这样做是为了调试。
counter_out
总是比 internal_counter 晚一个值。这是你想要的吗?它还会花费您 32 个额外的寄存器。我希望在没有内部计数器的情况下直接使用 counter_out:
always @ (posedge CLOCK_50) // on positive clock edge
begin
if (reset)
begin
led <= 1'b1;
counter_out <= 0;
end // reset section
else
begin // clocked section
led <= 1'b0;
counter_out <= counter_out + 1;
end
end // clocked section
我会建议使用 Verilog-2001 变体进行更多改进,而您的代码无法正常工作,因为在重置期间您正在分配 internal_counter <= 0
和 internal_counter <= internal_counter + 1'b1
,所以通常当您像这样修改时工具将在重置条件下进行第二次分配,因此它不会导致分配给 0.. 我在您的代码中添加了 reset_synchronizer 因此 led u 的 on/off 中的 glithces 可能不会遇到此实现(基于在你使用的某些开关上它可能也不起作用)。
module simple_counter (
input clock_50
,input reset
,output reg led
,output reg [31:0] counter_out
);
reg [9:0] reset_sync = 10'h3_FF;
reg system_reset = 1'b1 ;
// to remove glitches in PUSH Button reset
always@(posedge clock_50) begin
reset_sync <= #1 {reset_sync[8:0],reset};
system_reset <= #1 &(reset_sync[9:2]);
end
always@(posedge clock_50)begin
if (system_reset) begin
led <= #1 1'b0;
counter_out <= #1 32'b0;
end else begin
led <= #1 1'b1;
counter_out <= #1 counter_out + 1'b1 ;// increment counter
end
end
endmodule
我有一个关于 Verilog 的非常初级的问题,我希望得到一些帮助。
您可以在下面看到一个简单计数器的代码,它具有:
- 输入:单时钟信号,接时钟
- 输入:复位信号,接物理按键
- 输出:计数器输出
- 输出:led等于复位输入
奇怪的是,当复位信号为高电平时,计数器不会复位为零。
在板上,当我按下按钮时,我可以看到 LED 灯亮起和熄灭,因此重置为真,但 if 指令 internal_counter <= 0;
未执行 (?)
我将 Quartus Prime II Lite 与 DE-10 Nano Terasic 开发板一起使用
有什么建议吗?谢谢!
//Single clock input and a 32bit output port
//reset will zero the internal_counter
module simple_counter (
CLOCK_50,
counter_out,
reset,
led
);
input CLOCK_50 ;
input reset ;
output led;
output [31:0] counter_out;
reg [31:0] counter_out;
reg [31:0] internal_counter;
reg led;
always @ (posedge CLOCK_50) // on positive clock edge
begin
if (reset)
internal_counter <= 0;
led <= reset;
internal_counter <= internal_counter + 1;
counter_out <= internal_counter;// increment counter
end
endmodule // end of module counter
我不知道为什么你的代码不起作用。我现在使用 VHDL。 但是,我会这样写:
module simple_counter (CLOCK_50, reset, led, counter_out);
input CLOCK_50 ;
input reset ;
output led;
output [31:0] counter_out;
reg [31:0] internal_counter;
always @ (posedge CLOCK_50)
begin
if (reset)
internal_counter <= 0;
else
internal_counter <= internal_counter + 1;
led <= reset;
counter_out <= internal_counter;
end
endmodule
您的代码无法运行,因为您对 internal_counter
进行了两次赋值。这是允许的,但规则是 最后一次分配 "wins".
因此,让我们在重置处于活动状态时单步执行代码:
if (reset)
internal_counter <= 0;
这使得 internal_counter
被重置(设置为零)。
但后来我们得到另一个作业:
internal_counter <= internal_counter + 1;
因为这是 later/behind 上一个作业 "wins"。这里有 no 条件所以这个 always 替换了之前的 if ...
。这样 if...
代码就变得多余了。它永远不会执行,综合工具将为此删除任何逻辑。
正如其他人所指出的:您需要一个 else
部分。重置重置部分中的所有变量是一种很好的做法:
always @ (posedge CLOCK_50) // on positive clock edge
begin
if (reset)
begin
internal_counter <= 0;
led <= 1'b1;
counter_out <= 0;
end // reset section
else
begin // clocked section
internal_counter <= internal_counter + 1;
led <= 1'b0;
counter_out <= internal_counter;
end
end // clocked section
现在我们得到一些一般性的评论:
我建议您改用 ANSI 端口定义。当你把所有东西放在一起时,它会更容易。如果您需要更改,例如counter_out
的宽度你可以在一个地方做到这一点:
module simple_counter (
input CLOCK_50 ,
input reset ,
output reg led,
output reg [31:0] counter_out
);
你的led
有点奇怪。复位时为高,否则为低。我假设你这样做是为了调试。
counter_out
总是比 internal_counter 晚一个值。这是你想要的吗?它还会花费您 32 个额外的寄存器。我希望在没有内部计数器的情况下直接使用 counter_out:
always @ (posedge CLOCK_50) // on positive clock edge
begin
if (reset)
begin
led <= 1'b1;
counter_out <= 0;
end // reset section
else
begin // clocked section
led <= 1'b0;
counter_out <= counter_out + 1;
end
end // clocked section
我会建议使用 Verilog-2001 变体进行更多改进,而您的代码无法正常工作,因为在重置期间您正在分配 internal_counter <= 0
和 internal_counter <= internal_counter + 1'b1
,所以通常当您像这样修改时工具将在重置条件下进行第二次分配,因此它不会导致分配给 0.. 我在您的代码中添加了 reset_synchronizer 因此 led u 的 on/off 中的 glithces 可能不会遇到此实现(基于在你使用的某些开关上它可能也不起作用)。
module simple_counter (
input clock_50
,input reset
,output reg led
,output reg [31:0] counter_out
);
reg [9:0] reset_sync = 10'h3_FF;
reg system_reset = 1'b1 ;
// to remove glitches in PUSH Button reset
always@(posedge clock_50) begin
reset_sync <= #1 {reset_sync[8:0],reset};
system_reset <= #1 &(reset_sync[9:2]);
end
always@(posedge clock_50)begin
if (system_reset) begin
led <= #1 1'b0;
counter_out <= #1 32'b0;
end else begin
led <= #1 1'b1;
counter_out <= #1 counter_out + 1'b1 ;// increment counter
end
end
endmodule