Never-ending synthesis with integer incrementation - vhdl

I have a piece of VHDL code that compile but when I try to synthesize it I get stuck, meaning the synthesization never ends and I have in the console:
Analyzing Entity Interpretor in library work (Architecture ).
I've tried to understand why but I can't. All I know is that if I comment the line CPT_PAN <= CPT_PAN - 1; then all of sudden I can synthesize.
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
entity Interpretor is
Port (SCAN_CODE : IN STD_LOGIC_VECTOR(7 downto 0));
end Interpretor;
architecture Behavioral of Interpretor is
Signal CPT_PAN : Integer range 0 to 255 := 0;
begin
process(SYS_CLK)
begin
if (SYS_CLK'EVENT and SYS_CLK = '1') then
if SCAN_CODE = "01101011" then
if CPT_PAN /= 0 then
CPT_PAN <= CPT_PAN - 1; -- Line to be commented to synthesize
end if;
end if;
end if;
end process;
end Behavioral;

Which synthesis tool? It would be useful to know.
Xilinx XST 14.3 simply reports <sys_clk> is not declared. and exits.
Add an input port for it, and it synthesises correctly, producing no hardware!
Add an output,
entity Interpretor is
Port (
SYS_CLK : in std_logic;
SCAN_CODE : IN STD_LOGIC_VECTOR(7 downto 0);
Zero : Out Boolean
);
end Interpretor;
and a line to the architecture
Zero <= CPT_Pan = 0;
and it generates pretty much what you would expect. It still optimises away to nothing since CPT_Pan is initialised to 0, and that case is not handled at all by the process.
Dare I ask if you simulated this before trying to synthesise?

Related

VHDL Counter Error (vcom-1576)

guys im trying to code a simple counter in VHDL but i always get this error:
Error: C:/Users/usrname/dir1/dir2/dir3/counter.vhd(22): near "rising_edge": (vcom-1576) expecting == or '+' or '-' or '&'.
Here is my Code:
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity counter is
port (
EXT_RST : in std_logic;
EXT_CLK : in std_logic;
EXT_LED : out std_logic_vector(7 downto 0)
);
end counter;
architecture fast of counter is
signal count : std_logic_vector(7 downto 0);
begin
process(EXT_CLK, count)
begin
if (EXT_RST = '1') then
count <= "00000000";
elseif rising_edge(EXT_CLK) then
count <= count + '1';
end if;
end process;
EXT_LED <= count;
end fast;
Has anyone an idea why im getting this error?
Besides the elsif Lars Asplund suggested using in his comment use type conversions for `count:
count <= std_logic_vector(unsigned(count) + 1);
or use package numeric_std_unsigned (VHDL -2008 only) instead of numeric_std.
Notice the 1 instead of '1' and type conversions. Those aren't needed with numeric_std_unsigned which has a "+" adding operator function with this signature:
[STD_ULOGIC_VECTOR,STD_ULOGIC return STD_ULOGIC_VECTOR]
Using package numeric_std you can also make count an unsigned instead of std_logic_vector and convert for the LED assignment -
EXT_LED <= std_logic_vector(count);
Also, count doesn't need to be in the process sensitivity list:
process(EXT_CLK)
There are no assignments in the process where the value of count is used except on the clock edge.
Modifying your code with the first suggestion and indenting (which helps show the sensitivity list doesn't need count:
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity counter is
port (
EXT_RST : in std_logic;
EXT_CLK : in std_logic;
EXT_LED : out std_logic_vector(7 downto 0)
);
end counter;
architecture fast of counter is
signal count : std_logic_vector(7 downto 0);
begin
process(EXT_CLK)
begin
if (EXT_RST = '1') then
count <= "00000000";
elsif rising_edge(EXT_CLK) then
count <= std_logic_vector(unsigned(count) + 1);
end if;
end process;
EXT_LED <= count;
end fast;
This analyzes, elaborates and will simulate.
This prompts the question of how EXT_RST and EXT_CLK are derived should you actually synthesize your design. If they are from buttons (particularly the clock), debounce could be necessary even with membrane switches which can age and later bounce.

VHDL Code: Illegal type conversion converting std_logic_vector

I am trying to be multiply the values in the line:
Q<= unsigned(reg_output) or (unsigned(multiplicand) and unsigned(shifted_lsb)*"0010");
note: I know multiplicand is a std_logic_vector, I did this for comparison via the if's.
Everytime I compile I get the error:
Illegal type conversion from ieee.std_logic_1164.STD_LOGIC to ieee.NUMERIC_STD.UNSIGNED (non-numeric to array).
here is my code below:
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity shiftaddr is
port(
clk, clear : in std_logic;
multiplicand: in std_logic_vector(3 downto 0);
reg_output: in unsigned(7 downto 0);
shifted_lsb: in std_logic;
Q: out unsigned(7 downto 0) );
end shiftaddr;
architecture arch of shiftaddr is
signal temp: std_logic_vector(3 downto 0);
begin
shift: process(clk,clear,multiplicand, shifted_lsb,reg_output) --Define a process and state the inputs
begin
if (clk = '0') then
Q <= reg_output;
end if;
if (clk = '1') then
if (multiplicand(0) = '1') then Q <= (reg_output);
end if;
if (multiplicand(1) = '1') then
Q<= unsigned(reg_output) or (unsigned(multiplicand) and unsigned(shifted_lsb)*"0010");
end if;
end if;
end process;
end arch;
How do I go about fixing this? Thanks
The problem comes from:
unsigned(shifted_lsb)*"0010"
shifted_lsb is not a vector, you cannot convert it to unsigned which is a vector type. As suggested by Khanh N. Dang you could just test its value instead.
But your code is probably bogus: your sensitivity list is not that of a synchronous process while one of your signals is named clk. Moreover, if you want your process to be a synchronous one you will have a problem because you are using both states of the clock. You should probably:
indent your code so that we can read it without too much effort,
think hardware first: if you have a clear idea of the hardware you want (registers, adders, multiplexers...), coding usually becomes very easy,
read again the part of your text book about synchronous processes.

Synthesis: Implementing a delay signal using a counter on power-up of FPGA

I am trying to have a delay of 20 seconds on power-up of the FPGA.
There is a clock input of 100Hz, so if a counter gets to 20,000, that should be 20 seconds worth of delay. After the delay, it should set an output pin high. However, for some reason, this out pin is going high immediately and never goes low at all on powerup. It's almost as if it is skipping the s_count <= 20000 completely.
Here is the code I have:
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity delay is
port
(
pi_Clock : in std_logic;
po_Delay_Done : out std_logic
);
end entity;
architecture behavioral of delay is
begin
process(pi_Clock)
variable s_count : integer := 0;
begin
if rising_edge(pi_Clock) then
if s_count <= 20000 then
s_count := s_count + 1;
po_Delay_Done <= '0';
else
po_Delay_Done <= '1';
end if;
end if;
end process;
end architecture;
I have increased the 20000 to the max integer value, just to see if my clock was incorrect but the same result.
There is no other driver of this signal on the top level file.
Anyone see what I'm doing wrong?
For some reason, setting the initial values by the declarations seems to be the problem with this FPGA/toolset (synopsis Synplify and the FPGA is Actel A3PN250) even if it works in modelsim simulation.
The following code does what I want -- Set an output high after the FPGA is turned on for 20 seconds:
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity delay is
port
(
pi_Clock : in std_logic;
pi_Reset : in std_logic;
po_Delay_Done : out std_logic
);
end entity;
architecture behavioral of delay is
begin
process(pi_Clock)
variable s_count: integer;
begin
if rising_edge(pi_Clock) then
if pi_Reset = '1' then
s_count := 0;
po_Delay_Done <= '0';
else
if s_count < 2000 then
s_count := s_count + 1;
else
po_Delay_Done <= '1';
end if;
end if;
end if;
end process;
end architecture;
The catch is that the microcontroller is now sending a reset signal (pi_Reset = '1') to the FPGA after it has been started.
Hope this helps anyone in the future, thanks to Quantum Ripple and Brian especially for suggesting the hard reset. If you had an answer I would accept it.
The code you typed has no simulation or synthesis errors and has a correct result in modelsim simulation software. (according to the above first comment "fru1tbat")
With respect to the above comments, I think if you synthesized the FPGA board correctly and the design doesn't worked (with applying a reset port to reset the output and variable parameters), the problem is related to the clock generator. Be sure about the clock generator and find the correct frequency.

Out come of vhdl code not as expected

I want to take num as as an 8 bit input and then shift it on every rising edge of clock and out it on output "res". Code is shown below. But when simulated it does not give expected results.
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;
use ieee.numeric_std.all;
entity shiftreg is
port (
num : in std_logic_vector (7 downto 0);
clk : in std_logic;
res : out std_logic_vector (7 downto 0)
);
end entity;
architecture behav of shiftreg is
signal temp_num : std_logic_vector (7 downto 0):= "00000000";
begin
process(num)
begin
if(num' event) then
temp_num <= num;
res<=temp_num;
end if;
end process;
process(clk)
begin
if(rising_edge(clk)) then
temp_num <= shr(temp_num,"01");
res<=temp_num;
end if;
end process;
end behav;
The output res and signal temp_num are both driven from both of the
processes, thus the simulator will do resolution, which is likely to result in
X values for some or all bits.
In general, then signals and output is design modules should be driven from
only a single process, since that is also what synthesis tools expect. For
test benches, then there may be multiple drivers.
So if the intention is that any change in the num input should be reflected
immediately to the res output, and any later rising edge of clk should
result in right shift, then the two processes may be combined in a single
process and assign to res like:
process (num, clk) is
begin
if (num'event) then
temp_num <= num;
elsif (rising_edge(clk)) then
temp_num <= shr(temp_num, "01");
end if;
end process;
res <= temp_num;
This will work in simulation, but the 'event wont work in synthesis, since
there is typically no hardware that can sense value changes like 'event, so
the construction can't be mapped to hardware by synthesis.
So for a synthesizeable design, you may consider adding a load input:
load : in std_logic;
And use this for load of the internal temp_num with a process like:
process (clk) is
begin
if (rising_edge(clk)) then
if load = '1' then
temp_num <= num;
else
temp_num <= shr(temp_num, "01");
end if;
end if;
end process;
res <= temp_num;
Finally, you should consider removing the use ieee.std_logic_arith.all; and
use ieee.std_logic_unsigned.all;, since these two packages are not standard
VHDL packages, despite location in the IEEE library. Simply remove the two
lines, and then use the shift_right function from the std_logic_unsigned
like:
temp_num <= std_logic_vector(shift_right(unsigned(temp_num), 1));

VHDL - How to add 1 to STD_LOGIC_VECTOR? [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question does not appear to be about programming within the scope defined in the help center.
Closed 2 years ago.
Improve this question
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
-- use ieee.std_logic_arith.all;
-- use ieee.numeric_std.all;
-- entity part contain R for output of Register
entity register_16 is
port( input: in std_logic_vector(15 downto 0);
ld, inc, clk, clr: in std_logic;
R: buffer std_logic_vector(15 downto 0));
end register_16 ;
-- it have to parallel process
architecture behavioral of register_16 is
begin
reg: process (input, ld, clk, clr)
variable R_temp: std_logic_vector(15 downto 0);
begin
if (clr = '1') then
R_temp := b"0000000000000000";
elsif (clk'event and clk = '1') then
if (ld = '1') then
R_temp := input;
end if;
end if;
R <= R_temp;
end process reg;
-- my error in this step
inc_R: process (inc)
begin
R <= R + '1';
end process inc_R;
end behavioral;
Main process (reg) works correctly, but other process has error adding 1.
You will have to convert the vector to an integer an back again, here's an example:
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
signal in : std_logic_vector( 7 downto 0 );
signal out : std_logic_vector( 7 downto 0 );
out <= std_logic_vector(to_unsigned(to_integer(unsigned( in )) + 1, 8));
For a good picture about type conversion take a look here:
http://www.bitweenie.com/listings/vhdl-type-conversion/
Sorry to say, but there are quite a lot of things wrong with your code...
You are mixing combinatorial and sequential code in the same process, which is poor coding style. If coded correctly, there really is no need for the variable R_temp.
The sensitivity list is a simulation aid only, yet you are trying to use it as a conditional (when inc changes, increment R). This will not work in hardware. When starting out with VHDL, my suggestion is to use VHDL_2008 and always use process(all) as the sensitivity list. This avoids beginner errors, since it reflects what synthesis does.
You are creating a combinatorial loop in the second process. This will not show up in simulation because of 2. above, but will cause errors in synthesis.
As already mentioned by baldyHDL, you are assigning to R in multiple processes.
Prefer unsigned to std_logic_vector when dealing with numbers. Generally you should not include std_logic_arith, nor std_logic_unsigned, just std_logic_1164 and numeric_std.
Adding a std_logic value (such as '1') is not standard, or at least not supported by all tools. Simply use an integer instead: R <= R + 1;
By your code, I gather that you are trying to write a counter with increment, load and clear signals. I don't just want to give you the code (that would ruin the learning experience for you), but try to fit the entire counter into a single process, using the following template:
process(clk) begin
if(rising_edge(clk)) then
-- Your code here vvv
if(clr = '1') then
elsif(ld = '1') then
elsif(inc = '1') then
end if;
-- Your code here ^^^
end if;
end process;
you write R in both of your processes. this leads to a multi-driver situation that is not possible to synthesise. to solve it, combine the processes, e.g.:
reg: process (clk, clr)
variable R_temp : std_logic_vector(15 downto 0);
begin
if (clr='1') then
R_temp := b"0000000000000000";
elsif (clk'event and clk='1') then
if (ld='1') then
R_temp := input;
elsif (inc='1') then
R_temp := R_temp + '1';
end if;
end if;
R <= R_temp;
end process reg;
You should be able to add a vector containing the value 1 as this, as you are using the numeric_std library:
R <= R + x"0001";
I used the following libraries and it was able to do something similar
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
...
signal cnt : std_logic_vector(3 downto 0);
begin
process(clk, reset, ce, cnt)
begin
if(reset = '1') then
cnt <= "0000";
elsif(clk'event and clk='1') then
if(ce='1') then
if(cnt = "1001") then
cnt <= "0000";
else
cnt <= cnt + 1;

Resources