Forum Discussion
LED lights, SWITCHES and between :)
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;
12 Replies
- Altera_Forum
Honored Contributor
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 - Altera_Forum
Honored Contributor
YES!!!
it's working, thank you a loT!!!! - Altera_Forum
Honored Contributor
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; - Altera_Forum
Honored Contributor
Run the counter to 250,000,000....
Cheers, Alex - Altera_Forum
Honored Contributor
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?
Cheers, Alex --- Quote End ---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; - Altera_Forum
Honored Contributor
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:
'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, Alexoneshot: 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; - Altera_Forum
Honored Contributor
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; - Altera_Forum
Honored Contributor
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 longerlibrary 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; - Altera_Forum
Honored Contributor
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'; - Altera_Forum
Honored Contributor
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.