1

I'm very new to verilog and I am stuck on a project I am writing to get better at it. I have a button and an LED on my board, and I want the button to increment a counter which makes the led flash faster. This seems to work in theory but I cannot get it to work in practice. The switch won't make the led flash faster, it seems to do some strange things.

My current code, please inform me of any issues with what I'm doing even if it does not cause my issue here as I am trying to learn the langauge and constructs.

  `timescale 1ns / 1ps

module LedFlash(CLK100MHZ, led0, sw0, btn0);
input CLK100MHZ;
output reg led0;
input sw0;
input btn0;

 reg [25:0] clockTick = 0;
 reg [1:0]currentlyLighting = 0;
 reg [3:0] speedFactor = 0;
 reg [1:0]oldButton = 0;
 reg [1:0]buttonValue = 0;



  always @(posedge CLK100MHZ)
  begin
    led0 <= 0;
    buttonValue <= 0;

    if(oldButton != btn0 && btn0 == 1)
        buttonValue <= 1;

    oldButton <= btn0;

    if(clockTick == 0)
    currentlyLighting <= !currentlyLighting;

    if(currentlyLighting)
    led0 <= 1;

    if(buttonValue) begin
            speedFactor <= speedFactor + 1;
    end

    clockTick <= clockTick + speedFactor;
  end  


endmodule

Here is a gif of a couple presses of the button. Only the times when speedfactor increments is when I actually press the button.

waveform

I would provide more presses, but it just gets more strange from there, clearly I am doing something wrong. After that initial press of the button, it strays away from what I expect. Sometimes it turns off, sometimes stays solid, slows down, speeds up.....

**Also, if I replace this line :

clockTick <= clockTick + speedFactor;

with

clockTick <= clockTick + 10;

for example, it will flash fast like I would expect it to. I'm guessing I am doing something wrong with the bit addition, although the probe seems to tell me otherwise.

**

Fixed code :

    `timescale 1ns / 1ps

module LedFlash(CLK100MHZ, led0, sw0, btn0);
input CLK100MHZ;
output reg led0;
input sw0;
input btn0;

 reg [25:0] clockTick = 0;
 reg currentlyLighting = 0;
 reg [3:0] speedFactor = 0;
 reg oldButton = 0;
 reg buttonValue = 0;



  always @(posedge CLK100MHZ)
  begin
    led0 <= 0;
    buttonValue <= 0;

    if(oldButton != btn0 && btn0 == 1)
        buttonValue <= 1;

    oldButton <= btn0;

    currentlyLighting <= clockTick[25];

    if(currentlyLighting && sw0)
    led0 <= 1;

    if(buttonValue) begin
            speedFactor <= speedFactor + 1;
    end

    clockTick <= clockTick + speedFactor;
  end  


endmodule

1 Answer 1

0

The design doesn't ensure that clockTick hits 0 while starting a new round, so speedFactor actually cannot control the toggling frequency of currentlyLighting.

For example, if clockTick is 26'h3FFFFFF and speedFactor is 4'd3, the next value of clockTick will be 26'h0000002 and currentlyLighting will not toggle for that round.

An easy solution could be using the MSB of clockTick as currentlyLighting.

currentlyLighting <= clockTick[25];

In addition; buttonValue, oldButton and currentlyLighting should be single-bit signals, but they are 2-bit in your code. The correct declarations are as follows.

 reg currentlyLighting = 0;
 reg oldButton = 0;
 reg buttonValue = 0;
Sign up to request clarification or add additional context in comments.

9 Comments

Thanks for the informative answer, it is late here so I will have to try in the morning.
I feel stupid for putting the [1:0] i need to stop connecting languages like c and verilog so much for things like these. When I see reg[1] realistically in c that would mean 1 item rather the whole [h:l] notation of verilog is something I will need to get used to.
Just confirmed and it is working great. Thanks for the help, updated bottom of OP with working code.
Keep in mind that the declarations like those belong to the test bench side of the equation. They are not synthesizable. You would need a different approach for synthesis.
@Serge I'm aware of it, but must be OK for FPGAs.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.