I need to solve an issue in FPGA Prototyping By Verilog Examples Pong
If its Autor mistake or I'm doing sth wrong when i simulate on vivado i dont find any change in
q_reg <= q_next; // ? q_next never initialised ???
// next-state logic // How he wants to set time tick ?
assign q_next = q_reg + 1;
// output tick
State diagram of a debouncing circuit. is defined as picture
consider section
// counter to generate 10 ms tick
module db_fsm
(
input wire clk, reset,
input wire sw,
output reg db
);
// symbolic state declaration
localparam [2:0]
zero = 3'b000,
wait1_1 = 3'b001,
wait1_2 = 3'b010,
wait1_3 = 3'b011,
one = 3'b100,
wait0_1 = 3'b101,
wait0_2 = 3'b110,
wait0_3 = 3'b111;
// number of counter bits (2^N * 20ns = 10ms tick)
localparam N =19;
// signal declaration
reg [N-1:0] q_reg;
wire [N-1:0] q_next;
wire m_tick;
reg [2:0] state_reg, state_next;
// body
//=============================================
// counter to generate 10 ms tick
//=============================================
always @(posedge clk)
q_reg <= q_next;
// next-state logic
assign q_next = q_reg + 1;
// output tick
assign m_tick = (q_reg==0) ? 1'b1 : 1'b0;
//=============================================
// debouncing FSM
//=============================================
// state register
always @(posedge clk, posedge reset)
if (reset)
state_reg <= zero;
else
state_reg <= state_next;
// next-state logic and output logic
always @*
begin
state_next = state_reg; // default state: the same
db = 1'b0; // default output: 0
case (state_reg)
zero:
if (sw)
state_next = wait1_1;
wait1_1:
if (~sw)
state_next = zero;
else
if (m_tick)
state_next = wait1_2;
wait1_2:
if (~sw)
state_next = zero;
else
if (m_tick)
state_next = wait1_3;
wait1_3:
if (~sw)
state_next = zero;
else
if (m_tick)
state_next = one;
one:
begin
db = 1'b1;
if (~sw)
state_next = wait0_1;
end
wait0_1:
begin
db = 1'b1;
if (sw)
state_next = one;
else
if (m_tick)
state_next = wait0_2;
end
wait0_2:
begin
db = 1'b1;
if (sw)
state_next = one;
else
if (m_tick)
state_next = wait0_3;
end
wait0_3:
begin
db = 1'b1;
if (sw)
state_next = one;
else
if (m_tick)
state_next = zero;
end
default: state_next = zero;
endcase
end
endmodule
q_next
does not need to be initialized, it is a combinational logic derived from q_reg
. q_reg
is not explicitly initialized, therefore it will take the default value.
The default value of a flop on FPGA is 0
but for simulators the default is X
. The reason for this discrepancy is because Verilog is also used for simulating integrated circuits (IC); who flops can have an initial value that seem random due to the technology node, manufacturing process and variations, temperature, etc.
Since your target is FGPA, the simple solution is to add the line initial q_reg = {N{1'b0}};
or change reg [N-1:0] q_reg;
to reg [N-1:0] q_reg = {N{1'b0}};
Either way of initializing q_reg
will have you Verilog simulation and FPGA matching.
BTW: for a ASIC as the target, the FPGA solution will not work (initializer is ignored by ASIC synthesizers). An ASIC solution would be to add a reset condition (synchronous or asynchronous) to the always block that assigns the flop. The ASIC solution does work for FPGA, however FPGA's typically have a limited number (if any) of flops with asynchronous reset/set