VHDL - ror and rol operations - syntax

How can I solve this problem?
reg variable is defined as:
signal reg:STD_LOGIC_VECTOR(7 downto 0):="00000001";
There is a problem with ror operation in the code below. The error message is:
Line 109: Syntax error near "ror".
Line 108: found '0' definitions of operator "=", cannot determine exact overloaded matching definition for "="
--
process(clk1,up_down,enable,reset)
begin
if up_down="1" then
reg ror 1;
end if;
end process;

Your problem is the the ror operator is not defined for std_logic_vector.
VHDL exhibits a behaviour of computer (and hardware description) languages called overloading. Overloading is where an operator, function or procedure is multiply defined for different types. The compiler looks at the combination of types when the operator (etc) is used (called the signature) and tries it match that with the various versions that have been declared. This only works if there is exactly one match. Any more and the code is ambiguous, because the compiler doesn't know which version to used. Any less and there is no version for the compiler to use. This is your problem - there is no version of the ror operator that uses std_logic_vector.
You have two solutions:
(i) RECOMMENDED : implement your rotate right behaviour manually using the concatenation operator and slicing:
if up_down="1" then
reg <= reg(0) & reg(7 downto 1);
end if;
(ii) NOT RECOMMENDED : convert your std_logic_vector to a different type that does have a version of the ror operator defined, eg unsigned. Why "not recommended"? Because I would not recommend using any the the following operators ever, because they can behave strangely (and their behaviour doesn't seem to be consistent across different EDA tools);
ror rol sla sra sll srl
By the way, this line would be wrong even if ror were defined for std_logic_vector:
reg ror 1;
You can't just say that any more than you could just say
reg + 1;
You need to assign the result of the operation in both cases to something. I have assumed you want to assign it to reg in both cases.

Related

VHDL type conversion - found 4 possible definitions

I am trying convert two std_logic bits to an integer as follows
LIBRARY IEEE;
USE IEEE.std_logic_1164.ALL;
USE IEEE.numeric_std.ALL;
ENTITY TEST IS
PORT (sw1, sw0 : IN std_logic;
x : OUT integer RANGE 3 DOWNTO 0);
END ENTITY TEST;
ARCHITECTURE dflow OF TEST IS
SIGNAL mes_sel : integer RANGE 3 DOWNTO 0;
BEGIN
mes_sel <= to_integer(unsigned(std_logic_vector(SW1 & SW0)));
x <= mes_sel;
END ARCHITECTURE dflow;
but the compiler does not like the mes_sel assignment. I get the following compiler error message:
Error (10327): VHDL error at Q4.vhd(92): can't determine definition of operator ""&"" -- found 4 possible definitions
Can I not concatenate 2 bit of std_logic to a vector and then convert? Or is it something else?
regards
D
The error message tells you roughly what's wrong, and it's not a problem with the assignment.
GHDL gives a better diagnosis:
ghdl -a test.vhd
test.vhd:13:57: can't resolve overload for operator "&"
test.vhd:13:57: possible interpretations are:
../../src/ieee/numeric_std.v93:66:18: array type "signed"
../../src/ieee/numeric_std.v93:65:20: array type "unsigned"
../../src/ieee/std_logic_1164.v93:69:30: array type "std_logic_vector"
../../src/ieee/std_logic_1164.v93:54:31: array type "std_ulogic_vector"
ghdl: compilation error
VHDL allows overloaded operators, distinguishable by the types of their arguments (in this case, std_logic) and their return types, (in this case ... well... what?)
There are apparently 4 types which have a std_logic_vector() type conversion function declared on them, as well as a & operator taking two std_logic arguments; and ghdl (unlike whatever tool you're using) helpfully lists them.
In such cases, VHDL (unlike some other languages) insists that you pick one, rather than arbitrarily making a hidden (and possibly wrong) choice for you.
You can do this with a type mark. As you actually want an unsigned, the obvious choice is unsigned'() (note the "'" symbol, also used for attributes).
mes_sel <= to_integer(unsigned'(SW1 & SW0));
Note that if VHDL allowed anything simpler, like to_integer(SW1 & SW0) it would be positively dangerous as there is nothing to distinguish between signed and unsigned conversions, making the conversion at least non-obvious, and quite possibly wrong.

VHDL assignment when ... else renders syntax error

Simply, what would be wrong with this line?
zero <= '1' when alu_out = "00000000" else '0';
It is within a process. zero is std_logic and alu_out is std_logic_vector(7 downto 0). Both are defined in the entity and the assignment is made in the architecture. The error is:
Error (10500): VHDL syntax error at alu.vhd(27) near text "when"; expecting ";"
Sounds like using VHDL-2002 revision, where the concurrent conditional signal assign format can't be used as a statement in a process.
Try to enable VHDL-2008 revision support if the tool allows, otherwise use an if statement or write your own ternary function.
Also see this question and answer.
For Altera Quartus Prime ver. 15.1 the VHDL input version selection is shown in the figure below.

Vhdl code simulation

I'm trying to simulate the following code :
entity schal is port ( SW : in bit_vector(7 downto 0);
LED : out bit_vector(7 downto 0));
end schal;
architecture BEHAVIOUR of schal is
begin
INOUT_PROS : process (SW)
begin
LED <= SW;
end process INOUT_PROS;
end BEHAVIOUR;
I wrote this do file
vsim work.schal
restart
view wave
radix hex
add wave -height 25 -radix default sim:/schal/*
force SW 01000001
run 20ns
force SW 01000000
run 20ns
here is what I get :
as you can see the simulation affect only the first bit but not the whole vector ?
any idea how should I adjust the do file to get the right simulation ?
I think your force command is not using the correct syntax. You are trying to force a binary value, but the correct way to do this would be force SW 2#01000001, with the 2# specifying a binary value.
In ModelSim, go to Help > Documentation > PDF Bookcase, then open the 'Command Reference Manual'. This contains documentation on all commands, including force.
This is a Read-The-Fine-Manual moment. See the <value> argument description under the force command Arguments section in the Command Reference Manual.
A one-dimensional array of character enumeration can be forced as a sequence of character literals or as a based number with a radix of 2, 8, 10 or 16. For example, the following values are equivalent for a signal of type bit_vector (0 to 3):
You could note that IEEE Std 1076-2008 15.5.3 Based literals tells us:
A based literal is an abstract literal expressed in a form that specifies the base explicitly. The base shall be at least two and at most sixteen.
There are VHDL standard compliant based literals that can't be expressed with the force command.
Also notice the question's use of
force SW 01000001
is compatible with the sequence of character literals example in the Command Reference Manual. See the following NOTE:
For based numbers in VHDL, ModelSim translates each 1 or 0 to the appropriate value for the number’s enumerated type. The translation is controlled by the translation table in the pref.tcl file. If ModelSim cannot find a translation for 0 or 1, it uses the left bound of the signal type (type’left) for that value.
Also note from the question's value and waveform that the right most position of SWs enumeration translates properly. This suggests that the behavior doesn't match the force command &LT;value> description.
In VHDL terms you're being force to use a bit string literal as demonstrated in scary_jeff's answer and not a string literal for providing the value. (Both sans quotation marks).
The character literal sequence is correct according to the example but does not translate correctly. You could wonder if quotation marks would help - how would otherwise force a string type object's value containing a leading space?
As an early MTI Modelsim user the simulator originally only supported VHDL. The problem is either the simulator or the example.
And of course there's the use of a VHDL test bench instead of embedding simulation sequence in a do file.
This method would be portable between VHDL simulators:
entity schal_tb is
end entity;
architecture foo of schal_tb is
signal SW: bit_vector(7 downto 0);
signal LED: bit_vector(7 downto 0);
begin
DUT:
entity work.schal
port map (
SW => SW,
LED => LED
);
STIMULUS:
process
begin
SW <= "01000001";
wait for 20 ns;
SW <= "01000000";
wait for 20 ns;
wait for 60 ns; -- to show 100 ns on waveform
wait; -- suspends process permenently
end process;
end architecture;
And gives:
There are also online VHDL Testbench outline generators such as the Doulos VHDL Testbench generator or this Online VHDL Testbench Template Generator.

found '0' definitions of operator "+" in VHDL

At first I wanna point out that this is my first attempt with VHDL so be kind. I want to read the X1 ... X4 inputs and produce the sum of the ones at the output. This my code
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity counter_of_aces is
Generic(N: integer := 3);
port( X1, X2, X3, X4 : IN BIT;
count: out std_logic_vector(N-1 downto 0));
end counter_of_aces;
architecture behavioral of counter_of_aces is
signal counter : std_logic_vector(Ν-1 downto 0);
begin
process (X1, X2, X3, X4)
begin
counter <= "0";
if(X1='1' OR X2='1' OR X3='1' OR X4='1')then
counter <= counter + "1"; --O counter λειτουργεί ως στοιχείο μνήμης
else
counter <= counter;
end if;
end process;
end behavioral;
and I get the following errors
ERROR:HDLCompiler:69 - Line 11: <í> is not declared.
ERROR:HDLCompiler:1731 - Line 17: found '0' definitions of operator "+", cannot determine exact overloaded matching definition for "+"
ERROR:HDLCompiler:854 - Line 10: Unit <behavioral> ignored due to previous errors.
Which "i" is it referring to and what about the others? Thanks in advance.
Start your VHDL with
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use ieee.std_logic_unsigned.all;
These are observations based analyzing the example code a simulator.
ERROR:HDLCompiler:69 - Line 11: <í> is not declared.
This is caused by a non ISO 8859-1 character. I replaced the N with a new N and got past that point. My analyzer pointed at line 11, character 36 and examination showed a two byte character there (X"CE9D").
A VHDL analyzer constructs lexical elements out of specific subsets of the ISO 8859-1 character. Comments can contain any characters in VHDL -2008, while previous revisions of the standard required comments to be comprised of the graphic character subset.
ERROR:HDLCompiler:1731 - Line 17: found '0' definitions of operator "+", cannot determine exact overloaded matching definition for "+"
The context of overload resolution for operator overload functions depends on signatures - the types and number of parameters and type of the return value. A VHDL analyzer will only look where it's directed to other than for an implicit context clause available to every design unit:
library STD, WORK; use STD.STANDARD.all;
This is why we add the likes of:
library ieee;
use ieee.std_logic_1164.all;
to make all the declarations in library ieee package std_logic_1164 visible so they can be used in a design specification.
Without adding the right use and library clauses the analyzer can't find a "+" function with a signature of [std_logic_vector string return std_logic_vector].
to provide the overload function for the "+" operator on line 17:
counter <= counter + "1"; --O counter λειτουργεί ως στοιχείο μνήμης
The string literal "1" would have it's type determined from context (here the entire assignment.
There are two candidate packages for providing an operator overload function: std_logic_unsigned from Synopsys and numeric_std_unsigned a -2008 IEEE package. Neither are made visible currently by a use clause.
Because non- ISO 8859-1 characters are found in the comment it seems you have a IEEE Std 1076-2008 compliant analyzer.
For older VHDL implementations you can stick with the Synopsys package, write your own "+" function, or use type conversions with package numeric_std:
counter <= std_logic_vector(unsigned(counter) + "1");
There's are additional issues
An enable for a latch shouldn't be combinatorial derived. There can be different routing delays or timing causing glitches.
counter(N - 1 downto 0) depends on synthesis (mapping) for implementation behavior to match simulation. If implemented as a latch with an increment there's a feedback path (counter <= counter + "1";) that will produce gated oscillation on the counter outputs. An increment is guaranteed to invert at least one input. Output frequencies would be dependent on routing delays, latch and increment delays.
There are historical synthesis attributes used to direct the else assignment of counter to itself be implemented in logic. Otherwise a synthesis tool would ignore them (as do simulators mostly, an assignment without a change in effective value doesn't cause an event). The attributes likely have been useful for Earle latches in CPLDs while FPGA vendors typically manage all aspects of implementing latches.
In Vivado itself, it is written to add this LAST line mentioned below:
-- Uncomment the following library declaration if using
-- arithmetic functions with Signed or Unsigned values
use IEEE.NUMERIC_STD.ALL
try this,
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use ieee.std_logic_unsigned.all;
use ieee.std_logic_arith.all;

VHDL, using arithmetic & variables in "downto"?

Quick VHDL question, I don't have access to Xilinx at the moment due to dead laptop, so can't test this.
I was wondering if it's possible to use variables and arithmetic in 'downto' statements, e.g:
proc: process (x)
begin
y <= z(x downto 0) & z(7 downto x);
end process;
Thanks.
Yes, for reference look this page. Arrays allow integer expressions as a definition of the endpoints of a range.
My guess is that it would synthesize to a large and ugly multiplexer instead of a simple shift register which is looks like you are trying to create.

Resources