EmbDev.net

Forum: FPGA, VHDL & Verilog Input to LED


von Sania P. (Company: pers.Use) (hekk_tech)


Rate this post
0 useful
not useful
Hi I am new to VHDL and FPGA but I am trying to learn to have some fun. 
I got myself a brand new nexys 4 DDR as a present so now I have to do 
some projects. I know that perhaps for someone this project will be a 
joke but as I said earlier I am a complete beginner.

My idea is: I want to short-click a button and have some led on the 
board blink a couple of times lets say 3 times, at the same time when 
the button is pressed without letting it go I want it to blink 
continuously until the button is released.

How can I start? I know I need a clock (clk) as an input to handle the 
blinking also a button (btn_1) as an input and an led (led_1) as an 
output all declared in std_logic.

Can someone help me?

von Lothar M. (lkmiller) (Moderator)


Attached files:

Rate this post
1 useful
not useful
Sania P. wrote:
> How can I start?
Start with the simple flashing LED. With this you will learn 1. how to 
use the toolchain, 2. how to assign pins to ports to signals and 3. how 
to implement a simple counter.

Having done the flashing LED you can read in the button and implement 
synchronizer to the systems clock, additionally a debouncer and an edge 
detection. There the simple task is to implement a LED toggle with each 
button press.

Sania P. wrote:
> My idea is: I want to short-click a button and have some led on the
> board blink a couple of times lets say 3 times
Ok, thats easy then: having done the LED flasher and the button input 
stage you can implement something that waits for on a button press, then 
resets a counter thats counts up to a saturating value and lets flash 
the LED with one of the higher bits.

> at the same time when the button is pressed without letting it go
> I want it to blink continuously until the button is released.
What should happen when the button is pressed "fairly long", but lets 
say  only until the second LED flash? Or may it flash additionally 2-3 
times after releasing the button? If the second, then the task ist 
solved almost as easy as the simple 3-times-flsher: implement a 
saturating couter as shown and reset with a falling edge on the button 
signal as shown, but additonally reset the counter after pone cycle when 
the button is pressed at that very moment.

Check the attached code and the testbench to get an idea how it may be 
solved. I had to make it blink fairly fast to reduce simulation time. 
For real life you should add some bits to the counter... ;-)

And do not present this code to your teacher. She/He will recognize 
immediately that this code is not yours.

: Edited by Moderator
von Sania P. (Company: pers.Use) (hekk_tech)


Rate this post
0 useful
not useful
Thanks for the answer, I learnt how to map an led to a button, also how 
to make it blink. And how to make it blink while the button is pressed. 
Now I am trying to make the button blink only 3 times after a short 
press. I am reading a lot of blogs/tutorials online and many people call 
it double counter, correct me if I am wrong. So one counter is counting 
the clock and the other counter is counting the cycles of the first one. 
But I still cannot understand the vhdl implementation of this theory 
completely. I saw in your code you implement this technique so in 
desperation I just took your code and copy-pasted it in vivado (I am 
using 2018.3 version). I mapped the button to the led and generated 
bitstream and programmed the board. It didnt work completely (led was on 
only by pressing and holding the button) so I thought maybe it is 
because it is too fast and I cannot see the blinking altogether so I 
increased a lil bit the count vector because my original clock is 
100MHz, but it still seemed not to work correctly. The only thing which 
does work is the led lights on when the button is continously pressed, 
it is always on without blinking and after releasing the button led 
turns off.
Nevertheless all I need now is to learn how to make it blink only 3 
times, I hoped I could crack it simply by studying your code but I am 
again hopeless. Could you help me please with an advice?

von Lothar M. (lkmiller) (Moderator)


Rate this post
1 useful
not useful
Sania P. wrote:
> so I thought maybe it is because it is too fast
Take a scope and measure at the LED pin. With this tool you can easily 
see wheter there is something going on or not...

> so I increased a lil bit the count vector
In my waveform I use a 20 Bit vector and get times in the ms range. you 
want something in the second range, therefore you will need somewhat 
around 9 bits more.

So simply try that:
signal counter : unsigned (32 downto 0) := x"14000000";
:
:
       -- default count and saturate after 3 flash-cycles
       if counter/=x"14000000" then
           counter <= counter+1;
       end if;
       -- button freshly pressed? or  one flash-cycle done and button pressed further on?
       if  btnsr(2 downto 1)="01"  or  (counter=x"08000000" and btnsr(2)='1')  then 
          counter <= (others=>'0');   -- then reset the counter
       end if;
    end process;

    LED <= not counter(26); -- map the relevant bit of the counter to the LED

: Edited by Moderator
von Sania P. (Company: pers.Use) (hekk_tech)


Attached files:

Rate this post
0 useful
not useful
I have also found and read your previous answers on this forum, in this 
topic:

Beitrag "Xilinx VHDL Blinker-Programm Problem"

it is somewhat relevant to my problem, so I tried this time the code you 
gave the other guy for the answer (I attached your code so that you know 
what I am talking about). As before the board is programmed well without 
interruptions, but on the board the same thing happens, I press the 
button the led turns on (without blinking), i let it go the led turns 
off (without any 3 blinks)

I am using vivado 2018.3 and the board is nexys4 ddr (clock=100MHz). My 
OS is win10pro. I still cannot figure out why your codes don't work.

Unfortunately I have no scope, I tried to record leds on iPhone's slow 
mo camera to see the lights but the light on led is steady without any 
blinking.

Do you have any idea why this can happen?

I also have another board MIMAS V.2 but it is not supported in vivado 
2018.3 so I think if I won't find a workaround, I will try the code in 
ISE with MIMAS V.2 (XC6SLX9).

von Lothar M. (lkmiller) (Moderator)


Rate this post
1 useful
not useful
Sania P. wrote:
> Do you have any idea why this can happen?
No.
My usual way is to write the code, simulate it and debug it in the 
simulator. Then I synthesize it and it runs as expected...  ;-)

Did you get the simple straightforward flashing LED to work?
Its a simple unsigned counter with 32 bits and one of the higher counter 
bits assigned to the LED.
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;

entity flashled is
    Port ( clk50M : in  STD_LOGIC;  -- lets assume this clock has 50MHz
           led    : out STD_LOGIC); -- light when '1'
end flashled;

architecture Behavioral of flashled is
signal counter : unsigned (31 downto 0) := x"00000000";
begin      
    counter <= counter+1 when rising_edge(clk);
    LED <= counter(26); -- map one of the higher counter bits to the LED
end Behavioral;

von Sania P. (Company: pers.Use) (hekk_tech)


Attached files:

Rate this post
0 useful
not useful
I have attached the file this is how far I got so far.
This code is working fine on the board. I press the button and the led 
blinks with a period around a second, I release it and it turns off.

von Lothar M. (lkmiller) (Moderator)


Rate this post
1 useful
not useful
Sania P. wrote:
> the led blinks with a period around a second
So you know what bit to take (and my guess was not too bad ;-)
From there it is fairly easy.
For 3 times flashing the calculation is done this way:
counter
bit
28   0 0 0 0 1 1
27   0 0 1 1 0 0
26   0 1 0 1 0 1

LED  1 0 1 0 1 0 = bit 26 inverted
With a rising edge at the button input the counter must be reset, so 
that all bits an espacially bits 26..28 are "000". Then the counter 
counts up till bits 28 downto 26 are "101". Reaching that value the LED 
is off and it has flashed up 3 times. First job "short press": done!
When the counter bits 28 downto 26 reach "010" you must check whether 
the button is pressed further on (long press). If so, then the counter 
mus be reset to the start value "000". Second job "long press": done!

So finally this should work:
----------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;


entity flashled is
    Port ( clk50M : in  STD_LOGIC;  -- lets assume this clock has 50MHz
           button : in  STD_LOGIC;  -- pressed = '1'
           led    : out STD_LOGIC); -- light when '1'
end flashled;

architecture Behavioral of flashled is
signal counter : unsigned (28 downto 0) := (others=>'0');
signal btnsr   : std_logic_vector (2 downto 0) := "000";

begin
    -- sync the button to the 50MHz system clock
    btnsr <= btnsr(1 downto 0) & button when rising_edge(clk50M);

    process begin
       wait until rising_edge(clk50M);
       -- default count and saturate after 3 flashing cycles
       if counter(28 downto 26)/=x"101" then
           counter <= counter+1;
       end if; 
       -- button freshly pressed?   or   one flash cycle done and button pressed further on?
       if  btnsr(2 downto 1)="01"   or   (counter(28 downto 26)="010" and btnsr(2)='1')  then 
          counter <= (others=>'0');   -- then reset the counter
       end if;
    end process;

    LED <= not counter(26); -- map the relevant bit of the counter to the LED
    
end Behavioral;

von Sania P. (Company: pers.Use) (hekk_tech)


Rate this post
0 useful
not useful
Unfortunately it does not work either. But at least it blinks now 
straight from the beginning, when I press the button the light stays 
just a tiny bit longer on and then continues blinking, the same thing 
happens when I release it, the led stays on a tiny moment longer. It is 
like if by pressing the button I interrupt the blinking and shift it a 
tiny little bit forward and then the blinking interval continues 
normally like before.

I am hopeless, I have posted the same question on xilinx forum but no 
one really gave me something valuable yet. One guy suggested debouncing 
the button, but I still don't see any relationship to the 3 times blink 
while pressing the button with debouncing it, correct me if I am wrong. 
I would love to have a working code in front of me to be able to study 
it and understand how it actually works. Perhaps it is not the right way 
to learn but this is how I do it and it works for me.

I understand that I have to create two signals, the first one will count 
the clock and increment it in a loop of desired bits (in my case 26 
downto 0). The second signal starts counting the first one once I press 
the button and counts minimum till 3, if the button is released before 
the 3 count-cycle is over. If the button is still pressed I need to make 
sure that the second signal keeps counting. And finally I need to pin my 
signal to led (this is not a problem anymore, I know how to do it 
already)

von Lothar M. (lkmiller) (Moderator)


Rate this post
1 useful
not useful
Sania P. wrote:
> One guy suggested debouncing the button
Having a second thougt he will recognize: thats not neccessary here. 
Even a bouncing button will work with my code above.

> Unfortunately it does not work either.
Did you simulate your design? What does your simulation look like? Is it 
ok?

No, it is not. And the problem is the remaining erronous 'x' here:
if counter(28 downto 26)/=x"101" then
Wipe it out and it runs as expected:
if counter(28 downto 26)/="101" then
Because with that 'x' the compare value is a hex number and it does not 
match the desired stop value.

But I'm asking myself: why the heck didn't the simulator throw an error 
due to mismatching vector lengths..


> I am hopeless
Look for a scope or a logic analyzer (a cheap one will do the job) to 
see a little bit more of the reality...

: Edited by Moderator
von Sania P. (Company: pers.Use) (hekk_tech)


Rate this post
0 useful
not useful
Now everything is working perfectly!!!!

I dont understand only one line:

 btnsr <= btnsr(1 downto 0) & button when rising_edge(clk);

you commented over it that this is to synchronise the button to the 
clock frequency, I understand what this means but I do not understand 
how it works.

My guess is everytime I press the button the action will wait till the 
rising edge of the clock and then begin together synchronised am I 
right?

One more thing why did you assign 2 dimensional vector (1 downto 0) of 
btnsr to the original 3 dimensional vector (2 downto 0) of btnsr?

von Lothar M. (lkmiller) (Moderator)


Rate this post
0 useful
not useful
Sania P. wrote:
> My guess
...is fundametally wrong ;-)
In a FPGA nothing "waits" for the rising/falling edge of the clock.
Instead the clock is connected to flipflops. And due to is a 
rising/falling edge, then the flipflop transfers the level at it input 
to its output and stores it there.

> One more thing why did you assign 2 dimensional vector (1 downto 0) of
> btnsr to the original 3 dimensional vector (2 downto 0) of btnsr?
Read about the '&' operator in VHDL. It is obviously that you don't know 
it close enough. It has nothing to do with any kind of AND function like 
the ampersand '&' and '&&' operator in C (*).
Instead it is the "glue" that concatenates signals and/or vectors to a 
new and "longer" vector.

> btnsr <= btnsr(1 downto 0) & button when rising_edge(clk);
btnsr is a 3 bit shift register (it comes from BuTtoN Shift Register). 
So it is 3 flipflops one behind the ohter. Each one is clocked with the 
systems clock. The last two flipflops are used to detect the edge ot the 
button signal.

Have a look at the simulation how it works. And have a look in the RTL 
schematics how it is realized...

This here is some background to it:
http://www.lothar-miller.de/s9y/archives/52-Kompakte-Flankenerkennung.html
(Google translator may help, its German)



(*) read out this sentence loud and clear, listen to it and you will 
find a smile on your face.. ;-)

: Edited by Moderator

Reply

Entering an e-mail address is optional. If you want to receive reply notifications by e-mail, please log in.

Rules — please read before posting

  • Post long source code as attachment, not in the text
  • Posting advertisements is forbidden.

Formatting options

  • [c]C code[/c]
  • [avrasm]AVR assembler code[/avrasm]
  • [vhdl]VHDL code[/vhdl]
  • [code]code in other languages, ASCII drawings[/code]
  • [math]formula (LaTeX syntax)[/math]




Bild automatisch verkleinern, falls nötig
Note: the original post is older than 6 months. Please don't ask any new questions in this thread, but start a new one.