VHDL Delay before lighting led - vhdl

I want to make a simple vhdl code which makes a delay of 20 sec before a led will be ON. i used a signal counter to make the delay of the 20 sec, but i've noticed to very strange thing, if i am not declare that the led is OFF before the delay, the led will be always ON.
look at the two codes (the clock is 50MHz):
in this code the led is always ON.
library ieee;
use ieee.std_logic_1164.all;
entity check is
port(clk : in std_logic;
led : out std_logic);
end check;
architecture arc of check is
signal counter : integer range 0 to 100e6;
begin
process(clk)
begin
if rising_edge(clk) then
if counter<500e6 then
counter<=counter+1;
else
led<='1';
end if;
end if;
end process;
end arc;
in this code the led is ON only after 20 seconds.
library ieee;
use ieee.std_logic_1164.all;
entity check is
port(clk : in std_logic;
led : out std_logic);
end check;
architecture arc of check is
signal counter : integer range 0 to 100e6;
begin
process(clk)
begin
if rising_edge(clk) then
if counter<500e6 then
counter<=counter+1;
led<='0';
else
led<='1';
end if;
end if;
end process;
end arc;

You should initialize both counter and led. In simulation, when you don't do this, value of each uninitialized signal will be 'U', which means you simply cannot be sure what value it will have in real system. Can be both 0 or 1.
You can use := '0' in port declaration.
Probably led is always on, because according to this code, if counter<500e6, the value of 'led' doesn't matter and else it's 1, so compiler simplified it, because the only one value the program sets to 'led' is '1'.

Related

Wait statement to be synthesizable

I have this problem with the VHDL synthesis. I read in multiple articles that the "wait" statement is synthesizable if I only use one "wait until"/process, so that's what I did. So I tried to make a counter which shows at what floor I am (my project consists of an elevator in Logic Design), and it should open the doors for 5 seconds at floors which were ordered. The problem is with the wait statement. I don't know what to replace it to make it work in ISE too.
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
use ieee.std_logic_arith.all;
entity counter is
port(clk1: in std_logic;
enable2:in std_logic;
input_mux: in std_logic;
dir: in std_logic;
reset,s_g,s_u: in std_logic;
q_open: out std_logic;
q: out std_logic_vector(3 downto 0));
end counter;
architecture c1 of counter is
signal flag: std_logic:='0';
component test
port(clock: in std_logic;
a: in std_logic_vector(3 downto 0);
notify: out std_logic);
end component;
begin
delay: test port map(clk1,"0101",flag);
process
variable temp:std_logic_vector(3 downto 0):="0000";
variable q_open_var:std_logic:='0';
begin
if (enable2='1') then
if (s_g='1' and s_u='1') then
if (RESET='1') then
temp:="0000";
elsif (CLK1'EVENT and CLK1='1') then
if (DIR='1') then
temp:=temp+1;
elsif(DIR='0') then
temp:=temp-1;
end if;
end if;
end if;
end if;
if (input_mux='1') then
q_open_var:='1';
q_open<=q_open_var;
wait until (flag'event and flag='1');
q_open_var:='0';
end if;
q<=temp;
q_open<=q_open_var;
wait on clk1, reset;
end process;
end c1;
Although this structure is supported, you pushed over the limit of what is supported. The synthesis tool must generate registers from what you code. A register does have a clock and a reset input, but the synthesis tool does not know the words clk1 and reset. I.e. is you write
wait on clk1, reset;
The tool will not know what the reset is, nor what the clock is. Actually, both signals are considered clock triggers.
But you design is more problematic, as you have if-statements before the asynchronous reset and clock trigger. Although clock-gating is supported, you probably did not intend it.
Then there is a /second/ clock trigger in you statement: wait until (flag'event and flag='1');. I don't know what you are doing there, but how would you imagine this being realized in hardware?
You should really stick to standard/advised coding style for predictable behavior. I.e.
library ieee;
use ieee.numeric_std.all;
[...]
signal temp : unsigned(3 downto 0) := (others => '0');
begin
temp_proc: process(clk1, reset)
variable q_open_var : std_logic := '0';
begin
if rising_edge(clk1) then
if enable2='1' and s_g='1' and s_u='1' then
if dir = '1' then
temp <= temp + 1;
elsif dir = '0' then
temp <= temp - 1;
end if;
end if;
end if;
if reset = '1' then
temp <= (others => '0');
end if;
end process;
q <= std_logic_vector(temp);
(I left out the q_open part, as it is unclear what you want. Make a SEPARATE process for that, as it is not dependent on reset)
p.s. I like the five lines of end if; the most ;) Please use proper indenting next time. And use 'elsif' not 'else if'.

Not able to write the output of testbench to file

LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.NUMERIC_STD.ALL;
use IEEE.STD_LOGIC_ARITH.all;
use IEEE.STD_LOGIC_SIGNED.all;
use std.env.all;
USE IEEE.STD_LOGIC_TEXTIO.ALL;
USE STD.TEXTIO.ALL;
ENTITY tb_top IS
END tb_top;
ARCHITECTURE behavior OF tb_top IS
-- Component Declaration for the Unit Under Test (UUT)
COMPONENT c4b
PORT(
clock : IN std_logic;
reset : IN std_logic;
count : OUT std_logic_vector(3 downto 0)
);
END COMPONENT;
--Inputs
signal clock : std_logic := '0';
signal reset : std_logic := '0';
--Outputs
signal count : STD_LOGIC_vector(3 downto 0) := "0000";
-- Clock period definitions
constant period : time := 100 ns;
-- Opening the file in write mode
file myfile : TEXT open write_mode is "fileio.txt";
BEGIN
-- Instantiate the Unit Under Test (UUT)
uut: c4b PORT MAP (
clock => clock,
reset => reset,
count => count
);
clock_process :process --providing clock to the counter
begin
clock <= '1';
wait for period/2;
clock <= '0';
wait for period/2;
end process;
write_process: process
variable abd: LINE;
--variable val1: integer;
begin
--val1 := CONV_INTEGER(count); --saw this in another program. even they converted a std_logic_vector to integer. didn't work!
loop --tried the infinite loop to check for the value 1111,
if (count = "1111") then --so that as soon as count reaches the value 1111,
finish (0); --it would stop, because i only need to write one entire sequence of the cycle to the file!!
else
write (abd, count);
writeline (myfile, abd);
end if;
end loop;
end process;
-- Stimulus process
stim_process: process
begin
reset <= '0'; --because it only works when reset is 0!
wait for 100 ns;
if (count = "1111") then --the value is written to the text file in a continuous loop,
finish (0); --which makes he file size go to as much as 1 GB
end if; --thus to stop it at exactly one cycle!
end process;
END;
So, basically what I want to do here is let the counter count up from 0000 too 1111 and then write the entire sequence to a text file. But I only wish to write exactly just one cycle. Hence I've added a loop to check the same. Here in the code above I'm not able to simulate the testbench properly. When I don't include the write_process part of the code, the simulation works perfectly, giving me exactly just one cycle! (Simulator result w/o write_process picture no 1). But when I try to use the write_process, not only does it not simulate (Simulator result after adding the write_process) picture no 2, it also writes UUUU continuously to the file, until I close the ISim, and file size goes to at least a few hundred MBs! Please help!
Without the entity/architecture for c4b no one can duplicate your error, it's visible however.
Note that the write process has no sensitivity list nor wait statement and a loop statement that won't exit unless external stimuli is provided - if (count = "1111") then ...
It doesn't seem proper to be using finish in both stim_process and write_process, there's no guarantee of execution order you can lose the last write (if you cure the write process defect).
You have four unused use clauses (numeric_std, std_logic_arith, std_logic_signed, std_logic_textio, with VHDL -2008).
So, basically what I want to do here is let the counter count up from 0000 too 1111 and then write the entire sequence to a text file.
There's nothing in your code that spools up output until your simulation finishes. Writing a line to file textio.txt occurs for events driving the write process.
Adding a model for c4b:
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std_unsigned.all;
entity c4b is
port (
clock: in std_logic;
reset: in std_logic;
count: out std_logic_vector(3 downto 0)
);
end entity;
architecture foo of c4b is
begin
process (clock, reset)
begin
if reset = '1' then
count <= (others => '0');
elsif rising_edge (clock) then
count <= count + 1;
end if;
end process;
end architecture;
Removing unused use clauses (not strictly necessary):
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
-- USE IEEE.NUMERIC_STD.ALL;
-- IEEE.STD_LOGIC_ARITH.all;
-- use IEEE.STD_LOGIC_SIGNED.all;
use std.env.all;
-- USE IEEE.STD_LOGIC_TEXTIO.ALL;
USE STD.TEXTIO.ALL;
Changing the write_process to not endlessly loop:
-- write_process: process
-- variable abd: LINE;
-- --variable val1: integer;
-- begin
-- --val1 := CONV_INTEGER(count); --saw this in another program. even they converted a std_logic_vector to integer. didn't work!
-- loop --tried the infinite loop to check for the value 1111,
-- if (count = "1111") then --so that as soon as count reaches the value 1111,
-- finish (0); --it would stop, because i only need to write one entire sequence of the cycle to the file!!
-- else
-- write (abd, count);
-- writeline (myfile, abd);
-- end if;
-- end loop;
-- end process;
write_process:
process
variable abd: LINE;
begin
wait on count;
wait for 100 ns;
write (abd, count);
writeline (myfile, abd);
if count = "1111" then
finish (0);
elsif IS_X(count) then
report "count contains a metavalue and may not increment";
finish (-1);
end if;
end process;
The wait 100 ns; accommodates a reset to insure the counter can increment. It's possible to provide a design description of c4b that doesn't depend on reset. For purposes here, the supplied c4b doesn't do that. The wait 100 ns also provides the sample interval for count, which from the component declaration for c4b is free running, driven by clock events.
Changing the stim_process to not finish and wait instead:
-- -- Stimulus process
-- stim_process: process
-- begin
-- reset <= '0'; --because it only works when reset is 0!
-- wait for 100 ns;
-- if (count = "1111") then --the value is written to the text file in a continuous loop,
-- finish (0); --which makes he file size go to as much as 1 GB
-- end if; --thus to stop it at exactly one cycle!
-- end process;
-- END;
stim_process:
process
begin
reset <= '1';
wait for 100 ns;
reset <= '0';
wait for 100 ns;
wait;
end process;
Notice this also provides a reset interval seen on the following waveform.
And that gives us:
With the contents of textio.txt:
more fileio.txt
0000
0001
0010
0011
0100
0101
0110
0111
1000
1001
1010
1011
1100
1101
1110
1111
It's also possible to end simulation after detecting count is "1111" by stopping clock, avoiding the use of the finish procedure. Along with a write procedure supplied using the Synopsys package std_logic_texio:
procedure WRITE(L:inout LINE; VALUE:in STD_LOGIC_VECTOR;
This would allow the use of VHDL simulators complying to VHDL standard revisions earlier than -2008.

VHDL generate a constant signal

I need to generate a constant high signal pulse_out to output to an oscilloscope.
I tried letting the output signal pulse_out <='1' and this didnt work either. I believe due to my knowledge that an output port signal needs to be driven by a clock.
I also tried using combinational logic and letting a two signals that were opposite of each other make a new signal by using AND,OR and this did not work either.
I know it is a stupid question, but I am stumped.
Any sample code of showing how to output a constant high value of '1' would be great.
I agree with Josh's comment on checking your pin numbers and pin report to make sure you are driving the pin you think you are. Setting a signal to '1' should drive the pin high.
You can double check it too by driving a divided clock out and give yourself an edge to trigger a scope on.
LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
USE ieee.std_logic_arith.ALL;
ENTITY test IS
PORT (i_clk : IN std_logic;
i_reset : IN std_logic;
o_scope : OUT std_logic
);
END test;
ARCHITECTURE behv OF test IS
SIGNAL scope : std_logic;
BEGIN
p1 : PROCESS (i_clk, i_reset)
BEGIN
IF i_reset = RESET_LEVEL THEN
scope <= '0';
ELSIF clk'event AND clk = '1' THEN
scope <= NOT scope;
END IF;
END PROCESS p1;
o_scope <= scope;
END behv;

Vhdl ERROR that I don't understand

I have a problem with my vhdl code . In active-hdl it works perfectly , but when i tried to implement it on the FPGA board using ise design xilinx i have a problem with one component . The error i found is:
ERROR:Xst:827 - "E:/proiect_final/dispozitiv_impartitor/src/generator_square_wave.vhd" line 16: Signal numar_intermediar<0> cannot be synthesized, bad synchronous description. The description style you are using to describe a synchronous element (register, memory, etc.) is not supported in the current software release.
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;
entity generator_square_wave is
port(clock,reset :in bit;
controler:std_logic_vector(2 downto 0);
numar:out std_logic_vector(7 downto 0);
data_clock:out bit);
end generator_square_wave ;
architecture descriere of generator_square_wave is
signal reset1:std_logic;
begin
process (clock,reset) -- here it shows me the error
variable numar_intermediar:bit_vector(3 downto 0 ):="0000";
variable numar_intermediar2:std_logic_vector(3 downto 0);
variable bitul:bit;
begin
reset1<=to_stdulogic(reset);
if rising_edge(reset1) then
numar_intermediar:="0001";
numar_intermediar2:=To_StdLogicVector(numar_intermediar);
numar(0)<=numar_intermediar2(0);
numar(1)<=numar_intermediar2(1);
numar(2)<=numar_intermediar2(2);
numar(3)<=numar_intermediar2(3);
numar(4)<='0';
numar(5)<='0';
numar(6)<='0';
numar(7)<='0';
else if( clock'event and clock ='1' and controler="001")then
bitul:=numar_intermediar(0);
numar_intermediar:=numar_intermediar srl 1;
numar_intermediar(3):=bitul;
numar_intermediar2:=To_StdLogicVector(numar_intermediar);
numar(0)<=numar_intermediar2(0);
numar(1)<=numar_intermediar2(1);
numar(2)<=numar_intermediar2(2);
numar(3)<=numar_intermediar2(3);
numar(4)<='0';
numar(5)<='0';
numar(6)<='0';
numar(7)<='0';
if(reset/='1' and controler/="001")then
numar<="00000000";
end if;
end if;
end if;
data_clock<=clock;
end process;
end descriere;
You have a few problems. First, you shouldn't be treating reset as a clock (i.e. using rising_edge()). If it's asynchronous, you should just write:
if reset1 = '1' then
...
The following line also has a problem (not sure if this is strictly illegal, but it's not recommended):
if( clock'event and clock ='1' and controler="001")then
This should be:
if clock'event and clock = '1' then
if controler = "001" then
(with additional end if to match.)
That should at least allow it to synthesize.
You may also want to make the statement reset1<=to_stdulogic(reset) concurrent instead of including it in the process, and there are a couple other possible changes you could make, but they're not as critical (unless I've missed something).

Can't have a simulation for my VHDL code

I'm looking after a reason or an answer for my problem which is :
My VHDL code is working, i'm trying to create a frequency divider by 10.
The problem is that the simulation report keep giving me an undefined output(no value).
This is my VHDL code, I'd be so grateful for any help! Thank You!
Library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;
entity Frequency_divider is
port(clk: in std_logic;
Q:out std_logic);
end Frequency_divider;
architecture desc_freq_divider_10 of Frequency_divider is
signal S: std_logic:='0';
begin
process(clk,S)
variable cpt: integer:=0;
begin
if (rising_edge(clk)) then
cpt:=cpt+1;
end if;
if (cpt=5) then
S<=not(S);
cpt:=0;
end if;
end process;
Q<=S;
end desc_freq_divider_10;
I got rid of the extraneous use clauses:
--use ieee.std_logic_arith.all;
--use ieee.std_logic_unsigned.all;
Added a test bench:
library ieee;
use ieee.std_logic_1164.all;
entity freq_test is
end entity;
architecture tb of freq_test is
signal CLK: std_logic :='0';
signal Q: std_logic;
begin
CLOCK:
process
begin
if Now < 300 ns then
wait for 10 ns;
clk <= not clk;
else
wait;
end if;
end process;
DUT:
entity work.frequency_divider
port map (clk,q);
end architecture;
Analyzed all of it, elaborated and simulated and got it to work.
It says your code is functional and that you have a tool chain usage error more than likely.
Simulation should be fine, as David Koontz describes, but for a synthesizable design the process should have only clk in sensitivity list, and should have all updates in the if statement like:
process(clk)
variable cpt : integer range 0 to 5 := 0; -- Must be constrained for synthesis
begin
if (rising_edge(clk)) then
cpt := cpt+1;
if (cpt = 5) then
S <= not(S);
cpt := 0;
end if;
end if;
end process;
The other design is likely to infer latches and similar issues.
2014-02-17 edit: Added constrain on cpt integer, since synthesis can't figure out minimal size, thus will make too many flip-flops.

Resources