I'm having some trouble wrapping my head around this simulation waveform output. It reproduces in both Verilator and Icarus Verilog, so I'm assuming I'm just not understanding something about Verilog. I've boiled it down to a simple module:
`default_nettype none
module strobe (
input wire clk,
input wire reset,
input wire strobe_in,
output reg [3:0] counter_1,
output reg [3:0] counter_2
);
// Count clock ticks for simulation
reg [7:0] clk_count;
reg strobe_in_q;
always @(posedge clk) begin
if (reset) begin
clk_count <= 0;
end else begin
clk_count <= clk_count + 1;
end
end
always @(posedge clk) begin
if (reset) begin
strobe_in_q <= 0;
end else begin
strobe_in_q <= strobe_in;
end
end
always @(posedge clk) begin
if (reset) begin
counter_1 <= 0;
end else if (strobe_in) begin
counter_1 <= counter_1 + 1;
end
end
always @(posedge clk) begin
if (reset) begin
counter_2 <= 0;
end else if (strobe_in_q) begin
counter_2 <= counter_2 + 1;
end
end
endmodule
And here's a screenshot of the test bench simulation:
My question is why does strobe_in_q
pulse at clock 06
instead of 07
? counter_2
seems to behave as if it pulsed at 07
. And that's what I would expect by delaying strobe_in
by 1 clock cycle. Is this just a quirk of simulation? Or am I misunderstanding something fundamental about Verilog here? Thanks for any help!
Here's an EDA Playground link also showing this.
Edit: Putting it in one always
block generates the same results:
module strobe (
input wire clk,
input wire reset,
input wire strobe_in,
output reg [3:0] counter_1,
output reg [3:0] counter_2
);
// Count clock ticks for simulation
reg [7:0] clk_count;
reg strobe_in_q;
always @(posedge clk) begin
if (reset) begin
clk_count <= 0;
strobe_in_q <= 0;
counter_1 <= 0;
counter_2 <= 0;
end else begin
clk_count <= clk_count + 1;
strobe_in_q <= strobe_in;
if (strobe_in) begin
counter_1 <= counter_1 + 1;
end
if (strobe_in_q) begin
counter_2 <= counter_2 + 1;
end
end
end
endmodule
EDA Playground for one always
block.
Edit: Here's the test bench:
`timescale 1ns/100ps
`default_nettype none
module strobe_tb();
// Make a regular pulsing clock
reg clk = 0;
always #1 clk = !clk;
reg reset = 0;
reg strobe_in = 0;
strobe UUT (
.clk(clk),
.reset(reset),
.strobe_in(strobe_in),
.counter_1(),
.counter_2()
);
initial begin
$dumpfile("strobe.vcd");
$dumpvars(0);
# 1 reset = 1;
# 2 reset = 0;
# 10 strobe_in = 1;
# 2 strobe_in = 0;
# 10 $finish;
end
endmodule
always @(posedge clk)
blocks? You should only need one? \$\endgroup\$always
block. \$\endgroup\$always
blocks is much simpler to read and understand. It is a matter of preference, not functionality. \$\endgroup\$