- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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;
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
YES!!!
it's working, thank you a loT!!!!- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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;
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Run the counter to 250,000,000....
Cheers, Alex- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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 ---
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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;
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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;
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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';
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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 changeelsif 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..?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Write a testbench and debug it....
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page