Programmable Devices
CPLDs, FPGAs, SoC FPGAs, Configuration, and Transceivers
20641 Discussions

LED lights, SWITCHES and between :)

Altera_Forum
Honored Contributor II
1,481 Views

Hi all, 

I would like to greet and thank for beeing here and answering  

i'm kind of new to VHDL and trying to perfrom a project with my new DE2-115 and i hope that you guys can help me figure out how to : 

 

i want to use these ports: 

 

 

port( IF1: IN STD_LOGIC; --InfraRed 1 IF2: IN STD_LOGIC; --InfraRed 2 LED2: OUT STD_LOGIC); --LED 2 LED1: OUT STD_LOGIC); --LED 1  

 

when i'm switching IF1 on, and then IF2 ON - LED1 will turn on. 

that was accomplish by -  

 

LED1 <= IF1 AND IF2;  

 

my question is - how to make LED2 turned ON 1 sec after LED1 ? 

i know that is need to use the 50MHz clk_out of the DE2, but can't implement it.. 

i have this code so far: 

LIBRARY IEEE; USE IEEE.STD_LOGIC_1164.ALL; USE IEEE.STD_LOGIC_UNSIGNED.ALL; USE IEEE.STD_LOGIC_ARITH.ALL; --entity mode_one IS -- --generic (width1s : integer := 1); --pulse width1s of 1 seconds -- --port( clk_in: IN STD_LOGIC; --50Mhz DE2 input -- reset : IN std_logic; -- IF1: IN STD_LOGIC; --InfraRed 1 -- IF2: IN STD_LOGIC; --InfraRed 2 -- LED2:OUT STD_LOGIC; --LED 2 -- LED1: OUT STD_LOGIC; --LED 1 -- switch_in: in std_logic); --test switch to delay 1 sec' -- --END mode_one; -- --architecture behave OF mode_one IS ----1st process -divider- internal memories --signal counter: integer range 50000000 downto 0; --signal clk_out: std_logic; ----2nd process -oneshot- internal memories signal cnt: integer range 0 to width1s; BEGIN divider: process(clk_in) BEGIN LED1 <= IF1 AND IF2; IF clk_in'EVENT AND clk_in = '1' THEN --calculating untill counter =25M if counter = 50000000 then clk_out <= NOT clk_out; --switching the output pulse. only when counter =25M counter <= 0; ELSE counter <= counter+1; end if; end if; end process; oneshot: process (cnt,clk_out,switch_in,reset) BEGIN if reset ='0' then clk_out <= '0'; cnt <= 0; else if switch_in = '1' then if clk_out'EVENT and clk_out = '1' then if cnt < width1s then clk_out <= '1'; cnt <= cnt+1; else cnt <= 0; clk_out <= '0'; end if; end if; end if; end if; end process; end behave;
0 Kudos
12 Replies
Altera_Forum
Honored Contributor II
609 Views

Your idea is basically correct, just a few mistakes with your implementation... 

 

You are updating 'clk_out' in both your 'divider' and 'oneshot' processes. You can't do that. Only update a signal in a single process - (you can always read/test a signal in another process). 

 

By looking for an event on 'clk_out' you're trying to use it as a clock. Assuming you weren't trying to update it in the same process, this could be possible - this is a derived clock - but it's not very good practice. 

 

I suggest you simplify the first process - just run the counter to 50M. 

 

I suggest changing the second process to a clocked process. In there, check the 'counter' (e.g. for zero, which will happened every 1 second) and then act, updating IF1 & IF2. 

 

Start with that and, if you still have problems, update the post. 

 

Cheers, 

Alex
0 Kudos
Altera_Forum
Honored Contributor II
609 Views

YES!!! 

it's working, thank you a loT!!!!
0 Kudos
Altera_Forum
Honored Contributor II
609 Views

i cant seems to get it working for 5 sec' thought... 

can you help me see what i'm missing? 

LIBRARY IEEE; USE IEEE.STD_LOGIC_1164.ALL; USE IEEE.STD_LOGIC_UNSIGNED.ALL; USE IEEE.STD_LOGIC_ARITH.ALL; entity mode_one IS --Simulating mode_one:free mode --generic (width1s : integer := 1); --Pulse width of 1 seconds port( clk_in: IN STD_LOGIC; --50Mhz DE2 input. IF1: IN STD_LOGIC; --InfraRed 1 IF2: IN STD_LOGIC; --InfraRed 2 LED1:buffer STD_LOGIC; --LED1 GRID1:buffer STD_LOGIC; --GRID1 GRID2:buffer STD_LOGIC); --GRID1 END mode_one; architecture behave OF mode_one IS signal counter: integer range 50000000 downto 0; --1st process -divider- internal memories signal clk_out: std_logic; --1st process -divider- internal memories --signal cnt: integer range 0 to width1s; --2nd process -oneshot- internal memories BEGIN LED1 <= IF1 AND IF2; divider: process(clk_in) --process frequency divider BEGIN IF clk_in'EVENT AND clk_in = '1' THEN --Calculating untill counter =25M if counter = 50000000 then --If counter reached 50mhz counter <=0; --Reset counter ELSE counter <= counter+1; end if; end if; end process; oneshot: process (clk_out) --Process actions with delay BEGIN if counter <= 0 then --If X has been counted perform the following GRID1 <= LED1; GRID2 <= LED1; end if; end process oneshot; end behave;
0 Kudos
Altera_Forum
Honored Contributor II
609 Views

Run the counter to 250,000,000.... 

 

Cheers, 

Alex
0 Kudos
Altera_Forum
Honored Contributor II
609 Views

Hi alex, 

i really having har time to understand what i'm doing wrong and why it's not working as i want it... 

all i want is that GRID1 & GRID2 (LED's) will be turned on after 5 seconds from the moment LED1 is turned on. 

i am turning one of the switches on and than a LED light is on, and than, delay of 5 seconds i want that two other leds will be lighetned up. 

what am i missing? 

 

LIBRARY IEEE; USE IEEE.STD_LOGIC_1164.ALL; USE IEEE.STD_LOGIC_UNSIGNED.ALL; USE IEEE.STD_LOGIC_ARITH.ALL; entity mode_one IS --Simulating mode_one:free mode generic (width5s : integer := 5); --Pulse width of 1 seconds port( clk_in: IN STD_LOGIC; --50Mhz DE2 input. reset : IN std_logic; IF1: IN STD_LOGIC; --InfraRed 1 IF2: IN STD_LOGIC; --InfraRed 2 LED1:buffer STD_LOGIC; --LED1 GRID1:buffer STD_LOGIC; --GRID1 GRID2:buffer STD_LOGIC); --GRID1 END mode_one; architecture behave OF mode_one IS signal counter: integer range 25000000 downto 0; --1st process -divider- internal memories signal clk_out: std_logic; --1st process -divider- internal memories signal cnt: integer range 0 to width5s; --2nd process -oneshot- internal memories BEGIN LED1 <= IF1 AND IF2; divider: process(clk_in) --process frequency divider BEGIN IF clk_in'EVENT AND clk_in = '1' THEN --Calculating untill counter =25M if counter = 25000000 then --If counter reached 50mhz clk_out <= NOT clk_out; --switching the output pulse. only when counter =25M counter <= 0; ELSE counter <= counter+1; end if; end if; --counter <=0; --Reset counter --cnt <= cnt+1; -- ELSE counter <= counter+1; -- end if; -- end if; end process; oneshot: process (clk_out,cnt,reset) --Process actions with delay BEGIN if reset ='0' then clk_out <= '0'; cnt <= 0; else --if clk_out'EVENT AND clk_out = '1' then if led1 ='1' then if counter = 0 then if cnt < width5s then clk_out <= '1'; cnt <= cnt+1; GRiD1 <= led1; GRID2 <= led1; else cnt <= 0; clk_out <= '0'; --if counter <= 0 then --If X has been counted perform the following --if cnt = 5 then -- GRID1 <= LED1; --GRID2 <= LED1; end if; end if; end if; end if; end process oneshot; end behave;  

Cheers, 

Alex 

--- Quote End ---  

0 Kudos
Altera_Forum
Honored Contributor II
609 Views

You're still trying to update 'clk_out' in both processes. Only update a signal in one process. 

 

I note you've been trying clocked processes. That's the way to go - in my opinion. 

 

Try modifying your second process to:oneshot: process (clk_in, reset) begin if reset = '0' then cnt <= 0; elsif clk_in'EVENT AND clk_in = '1' then if led1 ='1' then if cnt < width5s then cnt <= cnt+1; else GRiD1 <= led1; GRID2 <= led1; end if; end if; end if; end process oneshot; 

'GRiD1' & 'GRID2' are not defined in the reset state - you need to decide how to drive then in reset. Also, you're 'reset' signal is an active low signal (resets registers when it's a 0, zero). I suggest renaming it to 'reset_l' (l for low) or 'reset_n' (n for negative), for clarity. 

 

Cheers, 

Alex
0 Kudos
Altera_Forum
Honored Contributor II
609 Views

Hi guys i really need help here,  

i know it's supposed to be simple but i guess im missing something... 

this is what i want to acheive: 

 

LED1 <= "1"; # Done 

# 1 seconds delay # Done - frequency divider generated 50Mhz to 1Hz 

LED2 <-"1"; 

 

thats it, as simple as that. and i cant seems to make it happen. 

all i get is a blinking led in 1 seconds delay : 

would appriciate any assistance here ! 

 

 

LIBRARY IEEE; USE IEEE.STD_LOGIC_1164.ALL; USE IEEE.STD_LOGIC_UNSIGNED.ALL; USE IEEE.STD_LOGIC_ARITH.ALL; entity test_mode_tst is port ( CLK_50MHz: in std_logic; IF1: IN STD_LOGIC; --InfraRed 1 IF2: IN STD_LOGIC; --InfraRed 2 LED1:buffer STD_LOGIC; --LED1 GRID1:buffer STD_LOGIC; --GRID1 GRID2:buffer STD_LOGIC --GRID1 ); end test_mode_tst; architecture Behavioral of test_mode_tst is signal Counter: std_logic_vector(24 downto 0); signal CLK_1Hz: std_logic; begin LED1 <= IF1 and IF2; Prescaler: process(CLK_50MHz) begin if rising_edge(CLK_50MHz) then --everytime clk50 is on a rise if Counter < "1011111010111100001000000" then --if counter smaller than 25,000,000 Counter <= Counter + 1; else CLK_1Hz <= not CLK_1Hz; Counter <= (others => '0'); end if; end if; end process Prescaler; one_shot: process (Counter,GRID1,GRID2) BEGIN if (Counter = 0) then if (LED1 = '1') then --add and next compilation!!!! if led1='1' AND counter =0 then act GRID1 <= CLK_1Hz; else GRID1 <= '0'; end if; if (GRID1 = '1') and (LED1 = '1') then GRID2 <= GRID1; else GRID2 <= '0'; end if; end if; end process one_shot; end Behavioral;
0 Kudos
Altera_Forum
Honored Contributor II
609 Views

Why not start the counter running when led1 gets turned on - then turn on LED2 1s later? 

The following code will set GRID1 and GRID2 to '1' exactly 1s after LED1, and stay at '1' for exactly 1 clock cycle. I leave it as an exercise for you if you want it to remain on for longer 

 

library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; entity test_mode_tst is port ( CLK_50MHz: in std_logic; IF1 : IN STD_LOGIC; --InfraRed 1 IF2 : IN STD_LOGIC; --InfraRed 2 LED1 : in STD_LOGIC; --Dont get into the habit of using buffer - it can cause problems GRID1: out STD_LOGIC; GRID2: out STD_LOGIC ); end test_mode_tst; architecture rtl of test_mode_tst is signal cnt : unsigned(24 downto 0) := (others => '0'); -- must be initialised as you have no reset -- would otherwise be U in simulation signal led1_i : std_logic; signal led1_r : std_logic; begin LED1 <= IF1 and IF2; led1_i <= IF1 and IF2; process(CLK_50MHZ) begin if rising_edge(CLK_50MHZ) then led1_r <= led1_i; GRID1 <= '0'; GRID2 <= '0'; if led1_i = '1' and led1_r = '0' then --rising edge of led1 cnt <= cnt + 1; -- start counter elsif cnt /= 0 then cnt <= cnt + 1; -- keep counting elsif cnt >= 50000000-1 then -- 1s later cnt <= (others => '0'); GRID1 <= '1'; GRID2 <= '1'; end if; end if; end process; end arcitecture rtl;
0 Kudos
Altera_Forum
Honored Contributor II
609 Views

First of all, thank you for the time end the knowledge sharing. 

some points: 

1. LED1 : in STD_LOGIC; --i defined it as buffer only cause the compilation log told me too.. would love to read\know how and why 

2 .led1_i & led1_r stands for imaginary and real i assume. if ill have another daleyd process, should i also used _i and _r to future variables in ordere to wait for count? 

3. I dont have the board with me at the moment to test the code, where can i read about simulating this in quartus? 

4. I think that i order the grid1 and grid2 to stay longer ill have to : 

elsif cnt >= 50000000-5 then -- 5s later? cnt <= (others => '0'); -- counts 5 clock cycle and reseting the counter and do whatever i need it to do. GRID1 <= '1'; - Am i right? GRID2 <= '1';
0 Kudos
Altera_Forum
Honored Contributor II
609 Views

1. I assume it asked to make it buffer because in VHDL (pre 2008 version) it is illegal to read outputs of a module internally. Making it a buffer makes it readable, but this can give you problems in larger designs where you istantiate many modules as buffers can only be connected to buffers. 

2. Here, I use _i = internal and _r = register. Its a faily common convention 

3. You simulate using modelsim. You will need to write a testbench to drive your code. There are plenty of tutorials on the internet. 

4. Nope. That will just turn it on 4.9999995s later. Remember, with a 50Mhz clock, it takes 50000000 clocks to make 1s. 5s would be 250,000,000 

Also, because GRID1/2 are set to 0 at the start of the process, they will only be lit in the states where they are explicitly turned on. If you want to turn a signal on and off at different points in time - remove the default assignments at the start of the process.
0 Kudos
Altera_Forum
Honored Contributor II
609 Views

Hi, 

thank you again, 

well, i just tested it, and for some reason it's not working. 

when i switch on the first two switches (IF1 & IF2) LED1 is lit up, and according to the code, 1 sec' after that, two more leds (GRID1/2) should be turned on, and they just dont. 

when i change elsif cnt <= 50000000-1 then ...  

GRID1/2 are being turned on immidiatly when programming is done, and turned off when led1 is on, and then light up 1 sec like they should have act. 

 

what should i do..?
0 Kudos
Altera_Forum
Honored Contributor II
609 Views

Write a testbench and debug it....

0 Kudos
Reply