convert and resize vector - vector

I have following code (simplified):
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all;
use ieee.std_logic_arith.all;
entity foo is
end entity;
architecture fum of foo is
signal slv16 : STD_LOGIC_VECTOR(15 DOWNTO 0);
signal slv5 : STD_LOGIC_VECTOR(7 DOWNTO 0);
begin
slv16 <= std_logic_vector(resize(unsigned(slv5), slv16'length));
end architecture;
I get an error message that 'resize' can not be matched to a subprogram. Why?

I think I found out the problem. I used this two libraies:
USE ieee.numeric_std.all;
USE ieee.std_logic_arith.all;
while both have the same implemenation for unsigned as follows:
type UNSIGNED is array (NATURAL range <>) of STD_LOGIC;
after deleting the synopsis library the error message is gone. Although I understand the problem here the error message above gave me a wrong direction to look at.
Thanks!

Related

Found '0' definitions of operator "=", cannot determine exact overloaded matching definition for "="

When i want to check syntax in simulation i have this error.
"Line 105: found '0' definitions of operator "=", cannot determine exact overloaded matching definition for "=" "
I tried to add libraries as others said in others similar threads but it didnt help. This is my code, and my libraries used:
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;
-- Uncomment the following library declaration if using
-- arithmetic functions with Signed or Unsigned values
--use IEEE.NUMERIC_STD.ALL;
-- Uncomment the following library declaration if instantiating
-- any Xilinx primitives in this code.
--library UNISIM;
--use UNISIM.VComponents.all;
entity multiwib is
port(trigger : in std_logic;
reset : in std_logic;
CLK : in std_logic;
led : out std_logic
);
end multiwib;
architecture multiwib_arch of multiwib is
type stany is (stabilny,niestabilny);
signal stan, stan_nast : stany;
signal licztakty : std_logic_vector(25 downto 0);
signal flaga : std_logic;
begin
reg:process(clk,reset)
begin
if(reset='1')then
stan<=stabilny;
elsif(clk'event and clk='1')then
stan<=stan_nast;
end if;
end process reg;
multi:process(clk,trigger)
begin
stan_nast<=stan;
case stan is
when stabilny=>
flaga<='0';
led<='0';
licztakty<=(others=>'0');
if(trigger='1')then
stan<=niestabilny;
led<='1';
end if;
when niestabilny=>
if flaga ='1' then
stan<=stabilny;
else
stan<=niestabilny;
end if;
end case;
end process multi;
licznik:process(clk,reset)
begin
if reset ='1' then
licztakty<=(others=>'0');
elsif(clk'event and clk='1') then
if(stan=niestabilny) then
licztakty<=licztakty+"01";
led<='1';
elsif(stan=niestabilny and licztakty="?10111110101111000010000000?")then
flaga<='1';
elsif(stan=stabilny) then
licztakty<=(others=>'0');
end if;
end if;
end process licznik;
end multiwib_arch;
You have written licztakty="?10111110101111000010000000?" .
licztakty is a std_logic_vector and ? is not a valid std_logic value. valid options are 'U', 'X', '0', '1', 'Z', 'W', 'L', 'H', '-'
'?' makes the compile try and compare std_logic_vector to a string, and I assume you havent written a custom '=' function for the compare.

subtracting std_logic_vector from integer

I have a problem subtracting a STD_LOGIC_VECTOR from a integer.
This is the code I have right now:
entity ROM is
Port ( hcount: in STD_LOGIC_VECTOR(9 downto 0);
vcount: in STD_LOGIC_VECTOR(9 downto 0);
hpos: in integer;
vpos: in integer;
clk25: in STD_LOGIC;
Pixeldata: out std_logic);
end ROM;
architecture Behavioral of ROM is
signal romtemp : std_logic_vector(9 downto 0);
shared variable yas : integer range 0 to 9 := 0;
shared variable xas : integer range 0 to 9 := 0;
Type RomType is array (9 downto 0) of std_logic_vector(9 downto 0);
Constant Rom: RomType :=
( "0001111000", "0111111110", "0111111110", "1111111111", "1111111111"
, "1111111111", "1111111111", "0111111110", "0111111110", "0001111000");
begin
process(clk25)
begin
if(hpos > hcount - 10) and (hpos <= hcount) and (vpos > vcount - 10) and (vpos <= vcount) then
xas := hpos - to_integer(unsigned(hcount));
end if;
end process;
end Behavioral;
The problem is the following line of code:
xas := hpos - to_integer(unsigned(hcount));
I am trying to put the subtraction in the integer named xas.
The following errors occur on that line:
Error: Multiple declarations of unsigned included via multiple use clauses; none are made directly visible
Error: Expecting type unsigned for < unsigned(hcount) >.
Error: Formal < arg > has no actual or default value.
Error: Type integer is not an array type and cannot be indexed
Error: found '0' definitions of operator "=", cannot determine exact overload matching definition for "-"
Someone that can help me with this error? (I am a beginner in VHDL)
You haven't included your use clauses at the top of the file, but what this error is saying is that from the use clauses, it found two different definitions of unsigned. Because of this, the tool has ignored both definitions, generating an error and forcing you to deal with the problem.
The most likely explanation is that you have:
use ieee.numeric_std.all;
use ieee.std_logic_arith.all;
std_logic_arith is nonstandard, and you should implement your design using the types and functions available in numeric_std only. Remove the std_logic_arith line.
In general, if something is a number, use a numeric type to represent it. For example, your hcount and vcount inputs are clearly counters, and could use type unsigned. If you use more appropriate types in the first place, you avoid the need for awkward looking type conversions, for example:
xas := hpos - to_integer(unsigned(hcount));
would become
xas := hpos - hcount;
Additional problems in your code:
Your process sensitivity list contains only clk25, but the process is not actually a synchronous process, and so all the input signals used should be in the list (or you can use the reserved all keyword to generate an automatic list, i.e. process(all)).
Unless this is some special case, you are better off getting into the habit of writing synchronous processes. These look like this:
process(clk)
begin
if (rising_edge(clk)) then
-- Do things
end if;
end process;
xas is a shared variable, which implies that you might be assigning it in other processes as well. This will probably not work how you expect it to. You should avoid shared variables altogether until you have a good understanding of exactly how they work, and when it might be appropriate to use them.

How to initialize signal using .mif file

For example, I have behavioral definition of ROM:
ENTITY rom_4x4_behavioral IS
PORT (address : IN NATURAL RANGE 0 TO 7;
q : OUT STD_LOGIC_VECTOR(3 DOWNTO 0));
END entity;
ARCHITECTURE rom_4x4_behavioral_arch OF rom_4x4_behavioral IS
SUBTYPE word IS STD_LOGIC_VECTOR(3 DOWNTO 0);
TYPE memory IS ARRAY(7 downto 0) OF word;
SIGNAL rom : memory;
SIGNAL addr_reg : NATURAL RANGE 0 TO 7;
BEGIN
PROCESS (address)
BEGIN
addr_reg <= address;
END process;
q <= rom(addr_reg);
END rom_4x4_behavioral_arch;
What do I have to do to initialize rom signal using .mif file?
Writing a .mif file parser in VHDL would be a lot of work to do.
If you are using the Quartus-II toolchain, then you could also generate a ROM by the Megawizard Plugin Manager (see menu tools). In the wizard you can specifiy the organization of your ROM as well as the .mif file with the initial data.
If you don't want to use that or if you are using other toolchains, then a text file in (Xilinx) .mem format would be another option. A sample implementation of how to read initialization data from such a text file can be found in the VHDL Library PoC in the namespace PoC.mem.ocrom.

using a VHDL generate statement in a function

I want to use generate statement but in my code I have a case statements which only takes sequential statements.
Then I thought I will use it in a package where I can define a function such that there also I am getting error as : 'Illegal Sequential statement'.
So what can be done. Any suggestions?
Code block:
LIBRARY ieee;
USE ieee.std_logic_1164.all;
USE work.my_package.all;
-- Entity for ALU component
-- Use this Entity for your C&A project
ENTITY ALU_E IS
PORT(
reset_n : in std_logic;
clk : in std_logic;
OperandA : in std_logic_vector(3 downto 0);
OperandB : in std_logic_vector(3 downto 0);
Operation : in std_logic_vector(2 downto 0);
Start : in std_logic;
Result_Low : out std_logic_vector(3 downto 0);
Result_High : out std_logic_vector(3 downto 0);
Ready : out std_logic;
Errorsig : out std_Logic);
END ALU_E;
architecture Behavioral_ALU of ALU_E is
signal c : std_logic_vector(7 downto 0);
signal carry_internal :std_logic_vector(4 downto 0);
COMPONENT fulladder IS
PORT(
a: IN std_logic;
b: IN std_logic;
cin : IN std_logic;
cout: OUT std_logic;
s: OUT std_logic );
END component fulladder;
begin
adders: for N in 0 to 3 generate
ff1:fulladder
port map
(a => OperandA(N),b => OperandB(N),cin => carry_internal(N),cout => carry_internal(N+1),s => c(N));
end generate adders;
c(4) <= carry_internal(4);
process(clk,reset_n)
begin
if reset_n = '0' then
if (clk'event) then
case Operation is
when "000" => --no operation
NULL;
when "001" => --Rotate left logical operator ?0000?&A by B steps
c <= rotlef (OperandA,OperandB);
when "010" => --Rotate right logical operator ?0000?&A by B steps (result width is 8 bit)
c <= rotrig (OperandA,OperandB);
when "011" => --Bitwise XOR operation
Result_Low <= OperandA xor OperandB;
when "100" => --Sum of A and B
--here i want to use a statement such that i can call the gatelevel --add function
--I have already all functions gatelevel defined when i try to use portmap or ----generate it gives an error illegal sequential statement
when Others =>
NULL;
end case;
end if;
end if;
end process;
end Behavioral_ALU;
There are a couple of misconceptions in the question.
First the title : there is no function in your actual code. What you have done with the for ... generate statement is generate a separate piece of hardware, operating in parallel with the main process. It will always operate, and always drive signal 'c' with the sum, as if you had written c <= a + b; in place of the for ... generate. It's always, continuously working, not a function you can call only when you want to.
Second, that means that both the adder and the clocked process drive c all the time, with different values. This will not go well... in fact you should see "XXXX" on signal c in simulation.
What I think you want to do is create a new signal, called sum for the adder's output, and drive sum, not c, in the for ... generate. Then, in the Case statement, assigning sum to c will accomplish the Add operation.
As far as why you get the error messages you do, a component instantiation statement or generate statement is a concurrent statement, while a case choice or a function body is comprised of sequential statements.
You don't need a function, you need the sum and carry out from the generate statement instantiated four fulladders.
o
Dummy up an entity/architecture pair for fulladder:
library ieee;
use ieee.std_logic_1164.all;
entity fulladder is
port (
a: in std_logic;
b: in std_logic;
cin: in std_logic;
cout: out std_logic;
s: out std_logic
);
end entity;
architecture foo of fulladder is
begin
s <= a xor b xor cin;
cout <= (a and b) or (a and cin) or (b and cin);
end architecture;
Dummy up a non functional my_package:
library ieee;
use ieee.std_logic_1164.all;
package my_package is
function rotlef (a, b: std_logic_vector) return std_logic_vector;
function rotrig (a, b: std_logic_vector) return std_logic_vector;
end package;
package body my_package is
function rotlef (a, b: std_logic_vector) return std_logic_vector is
variable ret_val: std_logic_vector (a'range);
begin
return ret_val;
end function;
function rotrig (a, b: std_logic_vector) return std_logic_vector is
variable ret_val: std_logic_vector (a'range);
begin
return ret_val;
end function;
end package body;
(note the function return value lengths match the left operand length)
Add a new declaration for the output of the generated fulladders:
architecture changed of alu_e is
signal c: std_logic_vector(7 downto 0);
signal carry_internal: std_logic_vector(4 downto 0);
signal s: std_logic_vector(3 downto 0); -- added
Change the generate statement to use the new signal for the sum:
adders:
for n in 0 to 3 generate
ff1:
fulladder
port map (
a => operanda(n),
b => operandb(n),
cin => carry_internal(n),
cout => carry_internal(n+1),
s => s(n) -- was c(n)
);
end generate;
-- c(4) <= carry_internal(4);
(eliminating the assignment to c(4))
And change the sequence of statements for choice "100":
when "100" => --sum of a and b
result_low <= s; -- added
result_high(0) <= carry_internal(4); --(un)signed?
And your design analyzes, elaborates and simulates (while not doing much - no assignments in the process for case others when operation is undriven and all Us, I didn't write a testbench to drive operation or provide it with a default value).
Notice the declaration of c has a length of 8 while the return value of the two functions will match their a input (length 4).
If you were to execute the dummy functions for operations "001" or "010" you'd get a simulation error due to length mismatch on the right hand side. I left this as is with no insight in to whether or not your rotlef or rotrig functions actually return a longer length.
In general you only want an 8 bit result for multiplies. The length of c and how it get's assigned to result_low and result_high aren't apparent (as yet).
It wasn't possible to discern whether you're doing signed or unsigned arithmetic without more detail. Instead of:
result_high(0) <= carry_internal(4); --(un)signed?
A signed sign extension could look like:
result_high <= (others => carry_internal(4)); --sign extended
Note that when you instantiate your multiplier you'd also want to use a new signal declaration for the 8 bit result. Modifying your rotate operations to assign result_low and result_high would allow c to be used for an instantiated multiply, although you might choose to rename it.
Think of the case statement in the process statement as instantiating a multiplexer, and in some cases you happen to be also expressing logic on inputs. The xor or the sign extension or function calls (which are expressions) are examples.
When you have instantiated components providing function you want to connect their output to a multiplexer input.

Division in VHDL (int/float)

I want to divide two numbers(16-bit binary) in VHDL in 1 cycle (combinational circuit). Numerator is an integer. Denominator is a float. Result should be float. What algorithm do i use to perform the division.
Please help
Here is an entity that does what you want (if I understand the question correctly):
library ieee;
use ieee.numeric_std.all;
use ieee.float_pkg.all;
entity integer_by_float_division is
port (
numerator: in signed(15 downto 0);
denominator: in signed(15 downto 0);
result: out float(6 downto -9)
);
end;
architecture rtl of integer_by_float_division is
subtype float16 is float(6 downto -9);
signal numerator_float: float16;
signal denominator_float: float16;
begin
numerator_float <= to_float(numerator, numerator_float);
denominator_float <= to_float(denominator, denominator_float);
result <= numerator_float / denominator_float;
end;
I don't think this is possible. Is there any reason that you need to do it in 1 clock cycle? The only way to get close would be to use a look-up table, but you would have to sacrifice some precision on the output.

Resources