VHDL Counter Error (vcom-1576) - vhdl

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.

Related

Near Text "Process" expected "IF"

I know this question has been answered some times already, but all those answers are specific to the according code.
That's why I am asking it again. Why do I get this error and how do I fix it.
I am trying to make a 8-bit up/down counter.
The error:
Error (10500): VHDL syntax error at UpDownCounter.vhd(30) near text
"PROCESS"; expecting "if"
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.all;
USE IEEE.STD_LOGIC_ARITH.all; -- needed for arithmetic increment
USE IEEE.STD_LOGIC_UNSIGNED.all;
ENTITY UpDownCounter IS
port( inA, inB : IN STD_LOGIC ;
Max_count: IN std_logic_vector(7 DOWNTO 0);
result : OUT STD_LOGIC_VECTOR(7 DOWNTO 0)
);
END UpDownCounter;
Architecture behavior of UpDownCounter is
signal internal_result : STD_LOGIC_VECTOR(7 DOWNTO 0);
BEGIN
result <= internal_result;
PROCESS(inA, inB)
BEGIN
IF (inA'EVENT and inA = '1') THEN
IF internal_count < Max_count THEN
internal_result <= internal_result + 1;
END IF;
ELSIF (inB'EVENT and inB = '1') THEN
-- Check for maximum count
IF internal_count > Max_count THEN
internal_result <= internal_result - 1;
END IF;
ELSE
internal_result <= "00000000";
END PROCESS;
END behavior;
The help is appreciated!
In your code, the final ELSE is missing the terminating END IF.
This is for the previous ELSE IF and it's corresponding IF which must have an END IF; statement.

Using To_signed VHDL, "No feasible entries for subprogram To_signed"

I'm working on a delay unit for a sound synthesizer on a FPGA, but when trying to compile in Modelsim to simulate i get the following error:
"No feasible entries for subprogram TO_SIGNED".
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
ENTITY Delay IS
-- Delay time in ms
PORT(
Sample : in STD_LOGIC_VECTOR(11 DOWNTO 0);
Delay : in INTEGER RANGE 0 to 2000; -- Echo Delay in ms, <2s
Gain : in INTEGER Range 0 to 7; -- Gain of the Echo, 0/8 to 7/8
clk : in STD_LOGIC;
Reset : in STD_LOGIC;
Output : Out STD_LOGIC_VECTOR(11 DOWNTO 0)
);
END Delay;
ARCHITECTURE Delay_Arch OF Delay IS
BEGIN
DelayOffset <= Delay*40; -- Number of steps back in the buffer for x ms delay
Process(clk)
BEGIN
IF (Reset = '1') THEN -- Standard Reset
CircBuffer <= (OTHERS=>(OTHERS=>'0'));
Counter <= 0;
ELSIF RISING_EDGE(clk) THEN
CircBuffer(Counter) <= Sample; -- Save Data in to circBuffer
IF (DelayOffset > Counter) THEN -- Wrap around for counter
OutBuff(11 DOWNTO 0) <= CircBuffer(79999-(DelayOffset-Counter));
ELSE
OutBuff(11 DOWNTO 0) <= CircBuffer(Counter-DelayOffset); -- Load sound from previous Sample (Delay)
END IF;
OutBuffInt <= (To_integer(Signed(OutBuff)) * Gain); -- Multiply with gain
Outvect <= To_signed(OutBuffInt, Outvect'length); <----- ERROR
Output <= Outvect(14 DOWNTO 3);
IF (Counter = 79999) THEN
Counter <= 0;
ELSE
Counter <= Counter + 1;
END IF;
END IF;
END PROCESS;
END ARCHITECTURE;
I can't find any problems in the code. Is there something that i am missing, or is just the to_signed not working correctly?
There are multiple problems here as Morten Zilmer points out. But to answer what you asked, the "No feasible entries for subprogram" error means that the types of the arguments and/or target of the function call does not match any available declarations. In your case there is only one function named to_signed visible, which is defined like this in ieee.numeric_std:
function TO_SIGNED (ARG: INTEGER; SIZE: NATURAL) return SIGNED;
You did not include your signal declarations, but I would guess that your Outvect signal is declared as std_logic_vector and not signed, hence the error.

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.

I am trying to implement a 1-2-3-4-6 counter in VHDL but the count is incrementing form 1-7 .

This is a VHDL code to count in sequence 1-2-3-4-6-7 but seems to count form 1-7
The code seems to have a logical error somewhere . Please help
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
entity newtest is
port(C, CLR : in std_logic;
Q : out std_logic_vector(2 downto 0));
end newtest;
architecture archi of newtest is
signal tmp: std_logic_vector(2 downto 0);
begin
process (C, CLR)
begin
if (CLR='1') then
tmp <= "000";
elsif (C'event and C='1') then
if (tmp="100") then
tmp <= tmp + 1;
end if;
tmp <= tmp + 1;
end if;
end process;
Q <= tmp;
end archi;
In a process with two sequential signal assignments to tmp not separated by time the later assignment will occur. A signal has a current value and a future value. Signal assignments are not updated until after the current simulation cycle. You've updated the future value before it could be assigned to the current value in the next simulation cycle with a clock C'event and C = '1'.
The following uses the numeric_std package instead of the Synopsys std_logic_unsigned package without changing the type of tmp, hence the type conversions to and from unsigned. I simply didn't want to divert my ieee library to contain something non-standard compliant. You can use std_logic_unsigned and remove the type conversions.
You could likewise declare signal tmp as unsigned (2 downto 0) and type convert it when assigning to Q (Q <= std_logic_vector(tmp);) or if possible make both Q and tmp unsigned.
library ieee;
use ieee.std_logic_1164.all;
--use ieee.std_logic_unsigned.all;
use ieee.numeric_std.all;
entity newtest is
port(C, CLR : in std_logic;
Q : out std_logic_vector(2 downto 0));
end newtest;
architecture archi of newtest is
signal tmp: std_logic_vector(2 downto 0);
begin
process (C, CLR)
begin
if (CLR='1') then
tmp <= "000";
elsif (C'event and C='1') then
if (tmp="100") then
tmp <= std_logic_vector (unsigned (tmp) + 2);
else
tmp <= std_logic_vector (unsigned (tmp) + 1);
end if;
end if;
end process;
Q <= tmp;
end archi;
Now there is only ever one assignment to tmp and it should go from "100" to "110". Someone is bound to point out tmp could be an unsigned instead of a std_logic_vector, or tmp could be an integer instead of either.
As far as synthesized hardware adding increment by 2 requires an additional term input for the two rightmost bits of tmp input

Counting down from an input value in VHDL

I'm trying to assign the value of input aa to the signal t in the code below. It compiles successfully, but there is a warning:
WARNING[9]: C:/Modeltech_5.7f/examples/hassan1.vhd(14): (vcom-1013) Initial value of "t" depends on value of signal "aa".
Here is the code:
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.std_logic_unsigned.all ;
use ieee.numeric_std.all;
entity counter is
port(clk :in std_logic;
reset : in std_logic;
aa: in std_logic_vector(3 downto 0);
check : out std_logic_vector(3 downto 0));
end counter;
architecture imp of counter is
signal i:std_logic_vector(3 downto 0):="0000";
signal t:std_logic_vector(3 downto 0):=aa;
begin
process(clk)
begin
if rising_edge(clk) and (t>0) then
t<=t-1;
i<=i+1;
end if;
end process;
check<=i;
end imp;
What should I be doing in order to decrement the input 'aa' in the process? The program is meant to decrement the value at input aa to 0.
It looks like you are trying to implement a down-counter with a load input. In such a counter, when load_enable = '1' you should register the load input value (aa in your case) into an internal signal. When load_enable = '0', you would decrement this count value. Here is a code example that does that:
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std_unsigned.all;
entity down_counter is
port (
clock: in std_logic;
reset: in std_logic;
load_enable: in std_logic;
load_data: in std_logic_vector(3 downto 0);
output: out std_logic_vector(3 downto 0)
);
end;
architecture rtl of down_counter is
signal count: std_logic_vector(3 downto 0);
begin
process (clock, reset) begin
if reset then
count <= (others => '0');
elsif rising_edge(clock) then
if load_enable then
count <= load_data;
else
count <= count - 1;
end if;
end if;
end process;
output <= count;
end;
For the record, the code above can be improved, but I didn't want to throw too much stuff at once. It is probably a good idea to use an integer instead of std_logic_vector for your count signal. Also you should check if the count proceeds as you expected, since the example uses the numeric_std_unsigned package. I'd recommend that you change it to numeric_std once you understand the code completely.

Resources