I am making a simple module that has a 8-bit counter that counts to a specific number that is written to an 8-bit register. It consists of said counter with asynchronous reset, a register with write-enable input which allows the value to be written and also a combining block that compares values from two other modules and gives a pulse. The pulse is also wired back to reset input of a counter.
The code of register (paral_reg8):
module paral_reg8(
input [7:0] data_in,
input clk,
input WE,
output [7:0] data_out
);
reg [7:0] reg_data = 0;
always @(posedge clk) begin
if (WE) begin
reg_data <= data_in;
end
end
assign data_out = reg_data;
endmodule
Counter (synchro_clock8):
module synchro_clock8(
input clk,
input rst,
output reg [7:0] data_out
);
always @(posedge clk or posedge rst) begin
if (rst) begin
data_out <= 0;
end
else if (clk == 1) begin
data_out <= data_out + 1;
end
end
endmodule
Comparison module (block):
module block(
input [7:0] data_in,
input WE,
input rst,
input clk,
output pulse_out
);
wire [7:0] clock_out, reg_out;
wire clock_rst;
synchro_clock8 clock(
.clk(clk),
.rst(clock_rst),
.data_out(clock_out)
);
paral_reg8 register(
.data_in(data_in),
.clk(clk),
.WE(WE),
.data_out(reg_out)
);
assign clock_rst = pulse_out | rst;
assign pulse_out = clock_out == reg_out;
endmodule
I have also made a testbench to test the behaviour of the modules (tb_block):
module tb_block();
reg WE, clk_rst;
reg clk;
reg [7:0] data_in;
wire pulse_out;
block blk(
.WE(WE),
.rst(clk_rst),
.data_in(data_in),
.clk(clk),
.pulse_out(pulse_out)
);
always #2 clk = ~clk;
initial begin
clk <= 0;
data_in <= 8'd16;
WE <= 1;
clk_rst <= 1;
#14.1 WE <= 0;
#15.1 clk_rst <= 0;
#1000
$finish;
end
endmodule
The problem is when I run behavioral simulation, modules work correctly:
However, after running synthesis and running post-synthesis functional simulation, the behavior changes and everything stalls (notice that pulse_out
is always 1 as opposed to almost always being 0 before):
Also, the register inputs is converted to D, E (as I understand to input and reset) and Q (output) and Q never changes despite the constant value of 10 on D and going clock.
Edit:
After implementing and testing solutions provided by toolic (i.e. using synchronized pulse_out
and making asynchronous reset on the register and fixing code pattern), I came to conclusion that the problematic module is paral_reg8
, which, even though is converted to trigger after synthesis, doesn't save the data_in
value (D
on second waveform) which results in Q
to equal zero. It can be checked if you were to connect data_in
directly to comparison:
In block
:
...
// with paral_register8 removed
always @(posedge clk_comp) begin
pulse_out <= clock_out == data_in;
end
...
Is the Verilog code incorrect, or I don't understand the meaning of post-synthesis simulation?
Additional info: I am using Vivado 2019.1, and the target device is Digilent Arty S7-50 (xc7s50csga324-1)