I have just started learning how to use VHDL and Quartus and I use it for a Cyclone II FPGA.
I need to write a code , which makes my Output High after a fixed time interval , 60 seconds for example. Thus I wrote the following code for the same, however it gives me a warning that my Output pins are stuck at VCC and therefore the the Output ( an LED ) , which is ideally supposed to be OFF and glow only after 60 seconds, is always ON. I also tried using a wait for 60 seconds statement, however that gives me a Wait statement error, saying that at WAIT UNTIL is required. --------------------- The code is library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.numeric_std.all; entity timer is port ( q : buffer bit := '0'); end entity; architecture behaviour of timer is begin q <= '1' after 60 sec; end behaviour;連結已複製
Hi shbhuk,
To provide a delay,you need to use the counter.Counter can divide the frequency and you should use the divided frequency to provide delay.The code you have written can work in simulation.But when you synthesize it "after" keyword will be ignored by the synthesis tool and that is why value of q will remain 1. Regards, KrupeshFor a timer of 20 seconds.
I wrote the following code, however the code still gives me the OUTPUT as always high. The clock used is 50 MHz ( 20 ns ) and therefore I seek to count till 10^9 to obtain 20 seconds. Below is the code - --------------------------------------- library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.numeric_std.all; entity timer is port ( clk : in std_logic ; q : buffer bit ); end entity; architecture Behavioral of timer is begin process(clk) variable cnt, cnt1: integer range 0 to 10**9 := 0 ; constant int: integer := (10**6)+1 ; begin if rising_edge(clk) then cnt := (cnt + 1)mod int; if cnt = 10**6 then cnt1 := (cnt1 + 1) mod 1001; end if; end if; if cnt1 = 1000 then q <= '1' ; end if ; end process; end behavioral; Please help.There's no point in using mod function: test when the counter reaches the divider value and then reset it.
if rising_edge(clk) then if cnt = int cnt := 0; else cnt:= (cnt + 1); end if; end if; Same for cnt1You can use simple 16 or 32 bit counter and output of this counter can be assigned to your output.For example,we can divide a frequency by 8 using 3 bit counter.You can assign msb of counter to your output which will stay high for four clock cycle and low for four clock cycle.
--- Quote Start --- You can use simple 16 or 32 bit counter and output of this counter can be assigned to your output.For example,we can divide a frequency by 8 using 3 bit counter.You can assign msb of counter to your output which will stay high for four clock cycle and low for four clock cycle. --- Quote End --- The problem with that would be the low frequency I require . My final time requirement ranges from 30 sec to 30 minutes. I changed the code to the following , which still gives OUTPUT as always HIGH. library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use ieee.std_logic_unsigned.all;
entity timernew is
port (clk : in std_logic;
flag : out std_logic:='0' );
end timernew;
architecture behavioral of timernew is
begin
process(clk)
variable count : integer:=0;
variable count1: integer:=0;
constant int: integer :=(10**6);
begin
if(clk'event and clk='1') then
count := count +1; --increment counter.
end if;
if count = int then
count := 0;
else
count := count + 1;
end if;
if count1 > 1000 then flag <= '1' ;
end if;
end process;
end behavioral;
There are 3 major errors:
- You increment count twice and count1 never. - When count1>1000 you also need to reset count1 to 0 in addition to setting flag output. - You set flag output but never reset itThe new code is -
library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.STD_LOGIC_ARITH.ALL; use IEEE.STD_LOGIC_UNSIGNED.ALL; entity timernew is port (clk : in std_logic; flag : out std_logic := '0' ); end timernew; architecture Behavioral of timernew is begin process(clk) variable count : integer:=0; variable count1: integer:=0; constant int: integer :=(10**6); begin if(clk'event and clk='1') then count := count +1; --increment counter. if count = int then count := 0; else count1 := count1 + 1; if count1 > 1000 then flag <= '1' ; end if; end if; end if; end process; end Behavioral;Do the counters create registers? Check the RTL schematic. You have used a variable after updating it, which usually risks the synthesisor not creating a register for it. The best way to avoid this as a beginner is to always use signals, never variables.
I changed the variables to signals, however still the LED glows instantaneously rather than waiting for 20 seconds and glowing.
Is the structure of the IF statements correct ( Nested or not ) .