WF_Blinky_with_switch.v Questions

As a beginner, here are two confusing things (of many) in this example.

A. Using Logical AND (partial code below)

switch_out_d <= switch_out;
end

 assign switch_pushed   = ~switch_out &&  switch_out_d;
 assign switch_released =  switch_out && ~switch_out_d;

My interpretation (which must be wrong):

Both switch_out and switch_out_d . are 1 bit registers.
switch_out is set as either 0 or 1 depending on whether the 3 bit switch register is 000 or 111.
Then, switch_out_d is set to switch_out, i.e. either 0 or 1

Then, in the logical AND part, these 2 values are equal but one of them is negated before the logical AND.

Which makes me think the results (switch_pushed, switch_released) will always be 0 or false.

Or, maybe there is operator precedence?

B. Concatenation ??

blink_cnt <= { blink_cnt[2:0],blink_cnt[3]}; // rotate a one

I’m thinking this is concatenation. On the first step, blink_cnt is 0001
So the concatenation produces . 001 and 0 to get 0010

The next concatenation produces 010 and 0 to get 0100
And the next: 100 and 0 to get 1000
And the next 000 and 1 to get 0001

Same thing with

if (counter == ( {blink_cnt, 20’h42400} )) begin

because the value in blink_cnt (0001, or 0010, or 0100, or 1000) is concatenated with those lower 20 bits, hex 42400.

So the flashing slows down because a higher and slower bit (21, 22, 23, or 24) is being used for the counter to decide when to toggle the LED or reset counter.

Hi robr,

You are mostly on the right path.

In the WF_switch_debounce module is where the two assignments are which you are referring to.

They are wires (switch_pushed, switch_released), registers would be in a always block.
They are one bit wires.
The wires are declared in the input/output list in the module header, with verilog 2001 standard, it is no longer needed to declare the wires, if they are one bit, but they can be. This would be a style choice.

switch_out and switch_out_d are 1 bit registers.

For the assignments these are what I term “events”. Events are not a verilog term or standard. It is my own style, others use the same as well but may not give them such a name. I will include these in tutorials.

For me events are one clock pulses that signify an event occurred.

switch_out_d <= switch_out;

The above statement creates a one clock delay of the signal switch_out. I use one post pended “_d” to indicate the one clock delayed signal. If I need to delay more I would add more such as “_ddd”, three clock delayed signal.

Now with this delayed signal I can create an event for “pushed” and “released”. The equations

 assign switch_pushed   = ~switch_out &&  switch_out_d;
 assign switch_released =  switch_out && ~switch_out_d;

are edge detectors. See the waveform below.

WF_switch_debonuce

switch_out is the debounced switch input which is active low when pushed.
switch_out_d is delayed version of that signal by one clock.

Now the edge detect logic.
switch_pushed for falling edge of switch_out; just and the not switch_out with switch_out_d.
switch_released for rising edge of switch_out; just and the switch_out with not switch_out_d.

These signals now can be used to trigger logic to run when a switch is pushed or released.
The amount of logic is extremely small and very simple and clean.

More to come…

Mick