Wait statement to be synthesizable - vhdl

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'.

Related

VHDL - Register for Push Button

I'm trying to create a simple push button in VHDL that turns on after an input switch or pb goes from 0 to 1 to 0 using a clock and a process. However, my code seems to be giving me undefined output. Here's what I have so far.
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
Entity captureInput is port
(
CLK : in std_logic := '0';
RESET_n : in std_logic := '0';
buttonState : in std_logic := '0';
buttonOut : out std_logic := '0'
);
end Entity;
ARCHITECTURE one of captureInput is
signal lastButtonState: std_logic := '0';
signal btnState : std_logic := '0';
BEGIN
process (CLK, RESET_n) is
begin
if (RESET_n = '0') then
lastButtonState <= '0';
elsif (rising_edge(CLK)) then
if (buttonState ='0' and lastButtonState = '1') then
btnState <= '1';
end if;
lastButtonState <= buttonState;
end if;
end process;
buttonOut <= btnState
end;
Try to initialize your btnState in the reset branch of your register and also have an else statement where you set your btnState back to 0, under some condition. I would bet that your undefined output comes from the fact that you do not define your btnState anywhere else outside your if conditions. It's good practice to not rely on the initial value of your declaration: Synthesis tools ignore it and some simulators will as well. Also, remember that the clocked body of the if will generate a register for every signal that gets assigned a value inside it, and that signals will keep the last value assigned to them inside a process.
You are also missing the Library ieee; statement at the top and a semicolon after buttonOut <= btnState.
Reading a button do need a debouncer.
Please take a look at:
VHDLWhiz generate statement
or
VHDLWhiz How to read a button in VHDL
Even though I see that you have already accepted Dimitris' answer, I can add that your code is almost right, you just need to toggle on the falling edge of of the latch instead of setting it to '1' as you do.
Try
if(rising_edge(CLK)) then
lastButtonState <= buttonState;
if(buttonState='0' and lastButtonState='1') then
btnState <= not btnState;
end if;
end if;
buttonOut <= btnState -- etc...
You don't need to initialize anything to '0' but you DEFINITELY need a switch debouncer as lukipedio said otherwise your toggle will not be consistent.
If you think about it, what you're doing is putting a "clock divider" on your lastButtonState register by toggling in order to set the btnState register at half the "frequency" of lastButtonState, which is what you want.
BTW, if you switch your toggling condition to
(buttonState='1' and lastButtonState='0')
then it will toggle on the rising edge of lastButtonState, in other words it will be toggle-on-press instead of toggle-on-release.

'Opt_Design Error' in Vivado when trying Run Implementation

Trying to make a UART Transmitter to send a data from FPGA to PC; 9600 baudrate, 8-bits, no parity, 1 start & stop bit; I wrote a code with VHDL, run synthesis and simulate it in a way I like it to be. I wanted to see it with BASYS 3 FPGA, After created constraints, Run Implementation issued an error in which its called "Opt_Design Error".
library ieee;
use ieee.std_logic_1164.all;
entity rs232_omo is
generic(clk_max:integer:=10400); --for baudrate
port(
clk : in std_logic;
rst : in std_logic;
start : in std_logic;
input : in std_logic_vector(7 downto 0);
done : out std_logic;
output : out std_logic;
showstates: out std_logic_vector(3 downto 0)
);
end entity;
architecture dataflow of rs232_omo is
type states is (idle_state,start_state,send_state,stop_state);
signal present_state,next_state : states;
signal data,data_next : std_logic;
begin
process(clk,rst)
variable count : integer range 0 to clk_max;
variable index : integer range 0 to 10;
begin
if rst='1' then
present_state<=idle_state;
count:=0;
data<='1';
done<='0';
elsif rising_edge(clk) then
present_state<=next_state;
count:=count+1;
index:=index+1;
data<=data_next;
end if;
end process;
process(present_state,data,clk,rst,start)
variable count : integer range 0 to clk_max;
variable index : integer range 0 to 10;
begin
done<='0';
data_next<='1';
case present_state is
when idle_state =>
showstates<="1000";
data_next<='1';
if start='1' and rst='0' then
count:=count+1;
if count=clk_max then
next_state<=start_state;
count:=0;
end if;
end if;
when start_state =>
showstates<="0100";
data_next<='0';
count:=count+1;
if count=clk_max then
next_state<=send_state;
count:=0;
end if;
when send_state =>
showstates<="0010";
count:=count+1;
data_next<=input(index);
if count=clk_max then
if index=7 then
index:=0;
next_state<=stop_state;
else
index:=index+1;
end if;
count:=0;
end if;
when stop_state =>
showstates<="0001";
count:=count+1;
if count=clk_max then
next_state<=idle_state;
done<='1';
count:=0;
end if;
end case;
end process;
output<=data;
end architecture;
This's the error message in detail
"[DRC MDRV-1]Multiple Driver Nets:Net done_OBUF has multiple drivers:
done_OBUF_inst_i_1/O,and done_reg/Q"
"[Vivado_Tcl 4-78] Error(s) found during DRC. Opt_Design not run."
What would be the reason for this error?
You are assigning done both in the first and the second process, which is exactly what the implementation is complaining about, you cannot have multiple drivers.
Remove done<='0'; from the first process and it should complete the implementation.
(I didn't check if the rest of the code is doing exactly what you want.)

how to read image file and convert it to bits in vhdl

I am trying to read an image file using textio package in vhdl.
If i open an .jpg with notepad , i will get some junk data but actually it is ASCII data . Here i am trying to read these ascii data and convert them into bytes.
below is my code:
library ieee;
use ieee.std_logic_1164.all;
use std.textio.all;
use ieee.std_logic_textio.all;
entity file_io is
port (
clk: in std_logic;
Data: out std_logic_vector(7 downto 0)
);
end entity;
architecture behav of file_io is
signal test_data : std_logic_vector(7 downto 0);
use ieee.numeric_std.all;
use std.textio.all;
use ieee.std_logic_textio.all;
begin
File_reader:process(clk)
file f : text open read_mode is "C:\Users\Public\Pictures\Sample Pictures\Chrysanthemum.jpg";
variable L: line;
variable var_int: integer:= 0;
variable var_char: character;
begin
if rising_edge(clk) then
while not endfile(f) loop
readline(f, L);
read(L, var_char);
var_int := character'pos(var_char);
test_data <= std_logic_vector(to_unsigned(var_int, test_data'length));
end loop;
end if;
Data <= test_data;
end process;
end architecture behav;
testbench:
LIBRARY ieee;
use ieee.std_logic_1164.ALL;
use std.textio.all;
ENTITY file_io_test IS
END file_io_test;
ARCHITECTURE behavior OF file_io_test IS
use work.io.all;
signal clk: std_logic := '0';
signal Data: std_logic_vector(7 downto 0);
-- Clock period definitions
constant clk_period : time := 10 ns;
BEGIN
-- Instantiate the Unit Under Test (UUT)
UUT:
entity work.file_io(behav)
port map (
clk => clk,
Data => Data
);
-- Clock process definitions( clock with 50% duty cycle is generated here.
clk_process :process
begin
clk <= '1';
wait for clk_period/2; --for 5 ns signal is '1'.
clk <= '0';
wait for clk_period/2; --for next 5 ns signal is '0'.
end process;
end behavior;
I am getting only one byte in waveform. expected result is : Every clock cycle new character should be rread and new byte should be obtained.
below is waveform:
below is the image I am trying to read:
You have a while loop placed inside the rising_edge part of your process. What happens is that when the first clock edge occurs, the while loop iterates until the end of the file and gives you the last byte of the input image.
Removing the while loop statement should solve your issue.
The question has a fundamental flaw. You can't use textio to read binary values, it's for text.
See IEEE Std 1076-2008 16.4 Package TEXTIO paragraphs 3 (in part) and 4:
Procedures READLINE, WRITELINE, and TEE declared in package TEXTIO read and write entire lines of a file of type TEXT. Procedure READLINE causes the next line to be read from the file and returns as the value of parameter L an access value that designates an object representing that line. If parameter L contains a non-null access value at the start of the call, the procedure may deallocate the object designated by that value. The representation of the line does not contain the representation of the end of the line. ...
The language does not define the representation of the end of a line. An implementation shall allow all possible values of types CHARACTER and STRING to be written to a file. However, as an implementation is permitted to use certain values of types CHARACTER and STRING as line delimiters, it might not be possible to read these values from a TEXT file.
And that can be demonstrated with your Chrysanthemum.jpg:
It is possible in VHDL to read raw characters one at a time (matching your need).
See IEEE Std 1076-2008 5.5 File types:
So all we have to do is declare a file type and we get these procedures defined implicitly.
We can use them to invoke raw read, without any end of line issues caused by textio:
library ieee;
use ieee.std_logic_1164.all;
entity file_io is
port (
clk: in std_logic;
Data: out std_logic_vector(7 downto 0);
done: out boolean
);
end entity;
architecture foo of file_io is
use ieee.numeric_std.all;
begin
File_reader:
process (clk)
-- "C:\Users\Public\Pictures\Sample Pictures\Chrysanthemum.jpg";
constant filename: string := "Chrysanthemum.jpg"; -- local to sim
variable char_val: character;
variable status: FILE_OPEN_STATUS;
variable openfile: boolean; -- FALSE by default
type f is file of character;
file ffile: f;
variable char_count: natural := 0;
begin
if rising_edge (clk) then
if not openfile then
file_open (status, ffile, filename, READ_MODE);
if status /= OPEN_OK then
report "FILE_OPEN_STATUS = " &
FILE_OPEN_STATUS'IMAGE(status)
severity FAILURE;
end if;
report "FILE_OPEN_STATUS = " & FILE_OPEN_STATUS'IMAGE(status);
openfile := TRUE;
else
if not endfile(ffile) then
read(ffile, char_val);
-- report "char_val = " & character'image(char_val);
char_count := char_count + 1;
Data <= std_logic_vector (
to_unsigned(character'pos(char_val),
Data'length) );
end if;
if endfile(ffile) then -- can occur after last character
report "ENDFILE, read " &
integer'image(char_count) & "characters";
done <= TRUE;
FILE_CLOSE(ffile);
end if;
end if;
end if;
end process;
end architecture foo;
library ieee;
use ieee.std_logic_1164.all;
entity file_io_test is
end file_io_test;
architecture behavior of file_io_test is
signal clk: std_logic := '0';
signal data: std_logic_vector(7 downto 0);
signal done: boolean;
constant clk_period: time := 10 ns;
begin
uut:
entity work.file_io(foo)
port map (
clk => clk,
data => data,
done => done
);
clk_process:
process
begin
if not done then
clk <= '1';
wait for clk_period/2;
clk <= '0';
wait for clk_period/2;
else
wait;
end if;
end process;
end architecture behavior;
Now we can have all the characters than can delimit a line show up in our read:
Note that package std.textio is not made visible through any context item.

VHDL Delay before lighting led

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'.

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).

Resources