I am trying to program an FPU unit in VHDL. I am doing my first steps. I get two errors while executing this instruction:
mantissa1 <= std_logic_vector(resize(unsigned(mantissa1),mantissa1'length + d));
The errors are:
Error: C:/Modeltech_pe_edu_10.4a/examples/fpu/shifter.vhd(38): Illegal type conversion to ieee.std_logic_1164.STD_LOGIC_VECTOR (operand type is not known).
Error: C:/Modeltech_pe_edu_10.4a/examples/fpu/shifter.vhd(36): (vcom-1078) Identifier "unsigned" is not directly visible.
Here is my code
library ieee;
USE ieee.std_logic_1164.ALL;
USE ieee.std_logic_misc.ALL;
USE ieee.std_logic_unsigned.ALL;
USE ieee.std_logic_arith.ALL;
use ieee.numeric_std.all;
entity fpu is
port (
E1,E2 : IN std_logic_vector( 30 downto 23);
M1,M2 : IN std_logic_vector( 22 downto 0);
S1,S2 : IN std_logic_vector (31 downto 31);
op : IN std_logic_vector (1 downto 0);
SUM : OUT std_logic_vector (45 downto 0);
E : OUT std_logic_vector (7 downto 0);
clk : IN std_logic
);
end entity;
architecture arch_fpu of fpu is
SIGNAL d: integer;
SIGNAL mantissa1 : std_logic_vector (22 DOWNTO 0) ;
SIGNAL mantissa2 : std_logic_vector (22 DOWNTO 0) ;
begin
process(E1,E2,M1,M2,S1,S2,clk)
BEGIN
if((op="01") or (op="00")) then
E<=E1 when E1>E2 else
E2;
d<=abs(conv_integer(E1-E2));
mantissa1 <= std_logic_vector(resize(unsigned(mantissa1),mantissa1'length + d));
end if;
END process;
end arch_fpu;
You are mixing VHDL math libraries. I suggest you use either numeric_std (my preference) or std_logic_unsigned/std_logic_arith, but not both.
There are several other issues as well. You cannot assign the larger (by 'd' bits) manitissa1 value back to manitissa1, you need a target of the appropriate size. Your subtraction of E1-E2 will need some type conversion to be legal, perhaps: signed(E1) - signed(E2)
Honestly, you probably want to rethink the whole approach to what you are trying to do, especially if you expect to synthesize this code into logic.
Related
I'm writing a simple program using Spartan 6 for signed numbers but this error pops up says :hdl 806"near line 12 syntax error"
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
entity Multiplier_Top is
Port (
A : in signed (15 downto 0);
B : in signed (15 downto 0);
Sum : out signed (15 downto 0);
Overflow : out STD_LOGIC;
);
end Multiplier_Top;
architecture Behavioral of Multiplier_Top is
signal Sum_Int signed (16 downto 0) :=(others=>'0');
begin
Sum_Int <= Resize(A,17) + B;
Sum <= Sum_Int(15 downto 0);
Overflow <= Sum_Int(16) xor Sum_Int(15);
end Behavioral;
There are 2 syntax error in the design:
Line 11: Remove the ; after out STD_LOGIC; so it becomes out std_logic
Line 17: Insert a : in Sum_Int signed so it becomes Sum_Int : signed
Some other comments:
Line 17: Remove default value assign :=(others=>'0'), since that is not required when output is assigned by continuous assignment in line 21
Line 17 and others: Use VHDL attributes line 'length to avoid constants in code
The code can then look like this:
library IEEE;
use IEEE.STD_LOGIC_1164.all;
use IEEE.NUMERIC_STD.all;
entity Multiplier_Top is
port (
A : in signed (15 downto 0);
B : in signed (15 downto 0);
Sum : out signed (15 downto 0);
Overflow : out std_logic
);
end Multiplier_Top;
architecture Behavioral of Multiplier_Top is
signal Sum_Int : signed (A'length downto 0); -- Length one bit more than A, assuming same length as B
begin
Sum_Int <= Resize(A, Sum_Int'length) + B;
Sum <= Sum_Int(Sum'range);
Overflow <= Sum_Int(Sum_Int'left) xor Sum_Int(Sum_Int'left - 1);
end Behavioral;
library ieee;
use ieee.std_logic_1164.all;
-- create a entity
entity ex1_3 is
port(
a,b,c,d: in std_logic_vector (3 downto 0);
ctrl: in std_logic;
sum: out std_logic );
end ex1_3;
architecture impl of ex1_3 is
-- declare a component of four bit ripple carry adder
component four_bit_ripple_carry_adder is
port(
a,b: in std_logic_vector (3 downto 0);
cin: in std_logic;
s: out std_logic_vector (3 downto 0);
cout:out std_logic
);
end component;
signal s: std_logic_vector (3 downto 0);
begin
process(a,b,c,d,ctrl)
begin
-- error:Illegal sequential statement.
if ctrl = '0' then
u0: four_bit_ripple_carry_adder port map(a,b,ctrl,s,sum);
elsif ctrl = '1' then
u1: four_bit_ripple_carry_adder port map(c,d,ctrl,s,sum);
end if;
end architecture;
** Error: /home/atomman/drs_exercises/exercise_04/ex1_3.vhd(30): Illegal sequential statement.
** Error: /home/atomman/drs_exercises/exercise_04/ex1_3.vhd(32): Illegal sequential statement.
** Error: /home/atomman/drs_exercises/exercise_04/ex1_3.vhd(35): near "architecture": (vcom-1576) expecting PROCESS.
Never forget that the "H" in HDL stands for "Hardware".
What you are saying is "if ctrl=0 then use a piece of hardware, name it u0 which is connect as ... else replace that piece of hardware, now name it u1 and connect it as ...".
There is no simple hardware equivalent that dynamically, based on a signal (in this case 'ctrl') swaps in and out two components.
The only difference is in the first two ports, which makes the solution simple: You make one component and use a multiplexer1 for the first two input ports:
signal a_or_c_mux: std_logic_vector (3 downto 0);
signal b_or_d_mux: std_logic_vector (3 downto 0);
a_or_c_mux <= a when ctrl='0' else c;
b_or_d_mux <= b when ctrl='0' else d;
Now you can instance your module (once! and outside a process) and use the signals a_or_c_mux and b_or_d_mux as input to the first two ports of the module.
1On purpose I am using 'hardware' nomenclature.
If I needed to perform a bitwise AND operation of two 16bit inputs and obtain a 16bit output in VHDL, would I be able to just AND the two inputs and store the result as the output vector? Or would I need to loop through each bit of the inputs, AND them, then store the result in the output vector? Would this work similarly for operations like or and xor?
The "and" operator is overloaded in the std_logic_1164 package for std_logic, std_ulogic, std_logic_vector, and std_ulogic_vector (the types typically used). It is also defined for bit and bit_vector (as well as signed and unsigned).
So it is as straightforward as just applying the "and"operator. For example:
architecture rtl of test is
signal a : std_logic_vector(15 downto 0);
signal b : std_logic_vector(15 downto 0);
signal y : std_logic_vector(15 downto 0);
begin
y <= a and b; -- Or 'y <= a xor b;' or 'y <= a or b;', etc
end architecture rtl;
You can just use and.
library IEEE;
use IEEE.std_logic_1164.all;
entity and_gate is
port(
a: in std_logic_vector(15 downto 0);
b: in std_logic_vector(15 downto 0);
q: out std_logic_vector(15 downto 0));
end and_gate;
architecture rtl of and_gate is
begin
q <= a and b;
end rtl;
http://www.edaplayground.com/x/Xuw
I am trying to make a generic 8 bit adder subtractor and I wrote all the code bit it gives me an syntax error on Line "big_mode <= (others => mode);".. any help?
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;
ENTITY AdderSubtractor IS
GENERIC(n: NATURAL :=8);
PORT ( Number1 : IN STD_LOGIC_VECTOR (n-1 DOWNTO 0);
Number2 : IN STD_LOGIC_VECTOR (n-1 DOWNTO 0);
Mode : IN STD_LOGIC;
Sum : OUT STD_LOGIC_VECTOR (n-1 DOWNTO 0);
Carry : OUT STD_LOGIC);
END AdderSubtractor;
ARCHITECTURE Behavioral OF AdderSubtractor IS
SIGNAL Tmp: STD_LOGIC_VECTOR (n DOWNTO 0);
SIGNAL big_mode: STD_LOGIC_VECTOR (n DOWNTO 0);
BEGIN
zeros<=(others=>'0');
big_mode <= (others => mode);
tmp<=('0' & Number1 + (('0' & Number2) xor big_mode)+mode);
Sum <= Tmp(n-1 DOWNTO 0);
Carry <= Tmp(n);
END Behavioral;
zeros isn't declared in your example code. On the line before the one you claim has a syntax error (and doesn't apparently).
Commenting out
-- zeros<=(others=>'0');
And your code analyzes.
You likely can comment out:
-- use ieee.std_logic_arith.all;
You're not using any declarations from it (so far).
You could also be using package numeric_std_unsigned instead of the Synopsys packages.
What VHDL tool are you using? (You didn't show us the exact wording of your syntax error).
LIBRARY ieee;
USE ieee.std_logic_1164.all;
USE ieee.std_logic_1164_unsigned.all;
ENTITY alu IS
PORT (a: IN STD_LOGIC_VECTOR (15 DOWNTO 0);
b: IN STD_LOGIC_VECTOR (15 DOWNTO 0);
operation: IN INTEGER (1 TO 10);
result: OUT STD_LOGIC_VECTOR (15 DOWNTO 0);
);
ARCHITECTURE arch-alu OF alu IS
SIGNAL arith, logic: STD_LOGIC_VECTOR (15 DOWNTO 0);
BEGIN
----rest of the code which give values to arith and logic----
WITH operation SELECT
result <= arith WHEN (1 TO 5),
logic WHEN (6 TO 10);
END arch-alu
My query is: Can I put a range after WHEN (as in the code), or I have to specify one by one each possibility of the signal.
Thanks!
According to http://tams-www.informatik.uni-hamburg.de/vhdl/tools/grammar/vhdl93-bnf.html the syntax you've used is permitted by VHDL '93 (the productions to look at there, in order: selected_signal_assignment, selected_waveforms, choices, choice, discrete_range, range) except that the grammar there doesn't seem to allow for the parentheses around the ranges. See also http://www.vhdl.renerta.com/source/vhd00063.htm (which again has no parens around the ranges).
You can use ranges in choices but you should omit the parentheses.
Not that your code fragment contained a lot more errors than just the superfluous parentheses. You had a missing end entity, a superfluous semicolon at the end of the port declaration, and incorrect integer port declaration,... A good VHDL IDE, such as Sigasi HDT, would help you catch these immediately.
Corrected fragment:
LIBRARY ieee;
USE ieee.std_logic_1164.all;
ENTITY alu IS
PORT (a: IN STD_LOGIC_VECTOR (15 DOWNTO 0);
b: IN STD_LOGIC_VECTOR (15 DOWNTO 0);
operation: IN INTEGER range 1 TO 10;
result: OUT STD_LOGIC_VECTOR (15 DOWNTO 0)
);
end entity;
ARCHITECTURE arch_alu OF alu IS
SIGNAL arith, logic: STD_LOGIC_VECTOR (15 DOWNTO 0);
BEGIN
--rest of the code which give values to arith and logic----
WITH operation SELECT
result <= arith WHEN 1 TO 5,
logic WHEN 6 TO 10;
END arch_alu;