Reputation: 89
I am currently writing Verilog code to construct a game of "Tug of War." The module below represents the central LED of the 15 LED's that represent the playing field. The central light must be on until the game begins, e.g. when the it receives some sort of input (the input is given by L and R, where L is one movement to the left, and R is one movement to the right).
However, I have run into a strange bug. Although I give enabled
a value of 1 at construction, and L and R are 0 (or should be) at construction, when I run the code enabled
immediately turns to 0.
My question is, why does this occur? And how would I go about making a variable maintain a value of 1 until input is seen?
module centerLight(Clock, reset, L, R, NL, NR, lightOn);
input Clock, reset, L, R, NL, NR;
output reg lightOn;
reg gameStart = 0;
reg enabled = 1;
always@(L or R)
if (L | R) begin
gameStart = 1;
enabled = 0;
end
else if (enabled)
gameStart = 0;
wire PS;
reg NS;
always@(PS or L or R or NL or NR)
if((NL && R) || (NR && L)) NS = ~PS;
else NS = PS;
always@(PS or gameStart)
case(PS || !gameStart)
0: lightOn = 0;
1: lightOn = 1;
endcase
D_FF cl (PS, NS, reset, Clock);
endmodule
module D_FF (q, d, reset, clk);
input d, reset, clk;
output reg q;
always@(posedge clk or posedge reset)
if (reset)
q = 0;
else
q = d;
endmodule
Upvotes: 1
Views: 2383
Reputation: 11
It could be due to a compiler switch.
Your default setting of enabled is effectively an initial block, as initial blocks are not synthesisable (well Altera's Quartus can be directed to read them to set powerup conditions, but officially according to Doulos they are not supported for synthesis) then it should not effect the result of the FPGA logic.
This should be simulated ok as RTL though. But I know for Altera devices for example all logic powers up as zero on startup unless the "Powerup don't care" switch is set to on, in this case it will look at the logic and set registers to values that would minimise the logic.
In this case it would set enabled as logic 0 since that produces the smallest logic thus removing the need for (because your code never sets enabled to 1 anywhere except in the initial construct which technically should be ignored, even if it was reading the initial construct then with that switch it could be ).
I did try adding a reset to enabled by adding an always and putting all the assignments to enabled there (keeping it as a latch)
always@(reset) if (reset) enabled <= 1'b1; else if (L | R) enabled <= 1'b0;
By doing this I could see the functionality for enabled was preserved on the logic.
On a different note I would recommend going for a synchronous registered approach rather then latches.
Also its recommended for Verilog to be consistent with case throughout your code as eventually you will get into trouble (the classic error is connecting modules up and the compiler inferring a wire if the statement `default_nettype none is not used (I'd look at code like Clifford Cummin's from Sunburst technology, or Doulos for inspiration).
I hope this helps!
Upvotes: 1
Reputation: 436
In you design enable
is a latch, if either L
or R
are high (or possibly floating) for the shortest amount of time, enable
will switch on.
It might be better to make the whole design sequential and then use the reset to make sure gameStart
is low.
this is how I'd do it:
module centerLight(Clock, reset, L, R, NL, NR, lightOn);
input Clock, reset, L, R, NL, NR;
output reg lightOn;
reg lightOn_d;
reg gameStart, gameStart_d;
reg PN, NS;
always @ (posedge Clock or posedge reset)
if(reset)
begin
gameStart <= 1'b0;
PS <= 1'b0;
lightOn <= 1'b0;
end
else
begin
gameStart <= gameStart_d;
PS <= NS;
lightOn <= lightOn_d;
end
always @ *
begin
if(L || R)
gameStart_d = 1'b1;
else
gameStart_d = gameStart;
if((NL && R) || (NR && L))
NS = ~PS;
else
NS = PS;
if(PS || !gameStart)
lightOn_d = 1'b1;
else
lightOn_d = 1'b0;
end
endmodule
I hope that helps.
Upvotes: 1
Reputation: 7556
The enable value in your code is assigned to 0 when L|R=1. If the initial values of L and R in your testbench or the values of these pins on your FPGS are 1 initially, enable will switch to 0. Dangling L and R pins may be evaluated as 1 too.
Simulators such as Modelsim allow you to set a breakpoint on the line when "enabled = 0;".
Upvotes: 0