Why do I get "Found '0' definitions of operator "+"" when adding bit_vectors? Are Delta Delays a factor? - vhdl

I'm in the process of coding a 3-bit ALU. The problem I'm running into is in the multiplier, when Opcode = "001". I'm trying to add 3 bit_vectors(5 downto 0), and it's throwing the error "Found '0' definitions of operator "+"". I've looked around and found some links found '0' definitions of operator "+" in VHDL, but adding any packages doesn't seem to fix the error for me.
Also, I read somewhere that since you're coding hardware in VHDL, it's wise to keep in mind delta delays. Since i'm assigning values to a signal in a process, will it actually work to output the final product? Or will the delta delays cause the signals to not be updated until the process is suspended.
The error occurs on line 67, "Z <= t4 + t5 + t6", in the block where Opcode = "001". Thank you to anyone who can give a little advice.
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
entity ALU is
PORT(
X,Y : IN BIT_VECTOR(2 downto 0);
Opcode : IN BIT_VECTOR(2 downto 0);
Z : OUT BIT_VECTOR(5 downto 0);
CLK : IN BIT
);
end ALU;
architecture Behavioral of ALU is
COMPONENT adder3 is
PORT (
A1 ,A2, A3, B1, B2, B3, Cin : IN BIT ;
Sum1 ,Sum2, Sum3, Cout : OUT BIT );
END COMPONENT;
SIGNAL adder_output: BIT_VECTOR(3 downto 0);
SIGNAL temp: BIT_VECTOR(2 downto 0);
SIGNAL t1,t2,t3: BIT_VECTOR(2 downto 0);
SIGNAL t4,t5,t6: BIT_VECTOR(5 downto 0);
begin
ADD3: adder3 PORT MAP(
A1 => X(0),
B1 => Y(0),
A2 => X(1),
B2 => Y(1),
A3 => X(2),
B3 => Y(2),
Cin => '0',
Sum1 => adder_output(0),
Sum2 => adder_output(1),
Sum3 => adder_output(2),
Cout => adder_output(3)
);
PROCESS(X, Y, CLK, Opcode)
BEGIN
IF(CLK'EVENT AND CLK='1')THEN
IF Opcode = "000" THEN
Z <= adder_output;
ELSIF Opcode = "001" THEN
IF Y(0) = '1' THEN
t1 <= X;
ELSE
t1 <= "000";
END IF;
IF Y(1) = '1' THEN
t2 <= X;
ELSE
t2 <= "000";
END IF;
IF Y(2) = '1' THEN
t3 <= X;
ELSE
t3 <= "000";
END IF;
t4 <= "000"&t1;
t5 <= "00"&t2&"0";
t6 <= "0"&t3&"00";
Z <= t4+t5+t6;
ELSIF Opcode = "010" THEN
Z <= X AND Y;
ELSIF Opcode = "011" THEN
Z <= X OR Y;
ELSIF Opcode = "100" THEN
Z <= X XOR Y;
ELSIF Opcode = "101" THEN
temp <= NOT X;
Z <= "000"&temp;
ELSIF Opcode = "110" THEN
IF Y = "000" THEN
Z <= "000"&X(2 downto 0);
ELSIF Y = "001" THEN
Z <= "00"&X(2 downto 0)&"0";
ELSIF Y = "010" THEN
Z <= "0"&X(2 downto 0)&"00";
ELSIF Y = "011" THEN
Z <= X(2 downto 0)&"000";
ELSIF Y = "100" THEN
Z <= X(1 downto 0)&"0000";
ELSIF Y = "101" THEN
Z <= X(0)&"00000";
ELSE
Z <= "000000";
END IF;
ELSE
IF Y = "000" THEN
Z <= "000"&X(2 downto 0);
ELSIF Y = "001" THEN
Z <= "0000"&X(2 downto 1);
ELSIF Y = "010" THEN
Z <= "00000"&X(2);
ELSE
Z <= "000000";
END IF;
END IF;
END IF;
END PROCESS;
end Behavioral;

If you want to do unsigned arithmetic with bit_vector, you need to use the numeric_bit_unsigned library that is part of the VHDL 2008 spec. For signed arithmetic, you need to use unsigned or signed types from either numeric_std or numeric_bit (the only difference is the base type).

Related

VHDL Getting a simulation fatal error in the loading design in modelsim

(Yes I know there's an easier way, yes my professor is asking for the long way.)
The following is the code for my 1 bit adder/subtractor.
library ieee;
use ieee.std_logic_1164.all;
entity FA1Bit is
port(x,y,Cin: in std_logic;
op: in std_logic;
S, Cout: out std_logic);
end FA1Bit;
architecture FA1Bit_arch of FA1Bit is
begin
behavior : PROCESS(op,x,y,Cin)
begin
if op = '0' then --if we're adding the bits;
if Cin = '0' then
if x = y then
S <= '0';
if (x= '1' and y = '1') then
Cout <= '1';
else --if x = 0 and y = 0;
Cout <= '0';
end if;
else --if x not equal to y;
S <= '1';
Cout <= '0';
end if;
else --if Cin = 1 then;
if x = y then
S <= '1';
if (x= '1' and y = '1') then
Cout <= '1';
else --if x = 0 and y = 0;
Cout <= '0';
end if;
else --if x not equal to y;
S <= '0';
Cout <= '1';
end if;
end if;
else -- if we're subtracting bits (op = 1);
if Cin = '0' then
if x = y then
Cout <= '0';
S <= '0';
elsif (x ='1' and y = '0') then
Cout <= '0';
S <= '1';
else --if x not equal to y;
S <= '1';
Cout <= '1';
end if;
else --if Cin = 1 then;
if x = y then
Cout <= '1';
S <= '1';
elsif (x ='1' and y = '0') then
Cout <= '0';
S <= '0';
else --if x not equal to y;
S <= '0';
Cout <= '1';
end if;
end if;
end if;
end PROCESS;
end FA1Bit_arch;
Now I use this component in my 4 bit adder/subtractor in this code:
library IEEE;
use IEEE.std_logic_1164.all;
entity FA4Bit is
port (
X : in STD_LOGIC_VECTOR(3 downto 0);
Y : in STD_LOGIC_VECTOR(3 downto 0);
C0: in STD_LOGIC;
S : out STD_LOGIC_VECTOR(3 downto 0);
C4: out STD_LOGIC;
OP1: in STD_LOGIC_VECTOR(3 DOWNTO 0));
end FA4Bit;
architecture FA4Bit_arch of FA4Bit is
component FA1bit
port ( X: in STD_LOGIC; Y: in STD_LOGIC; CIN : in STD_LOGIC;
SI : out STD_LOGIC; COUT: out STD_LOGIC;
OPA : in STD_LOGIC);
end component;
signal C : std_logic_vector(1 to 3);
begin
U1: FA1bit port map (X=>X(0), Y=>Y(0), CIN=> C0, SI=>S(0), COUT=>C(1), OPA => OP1(0));
U2: FA1bit port map (X=>X(1), Y=>Y(1), CIN=> C(1), SI=>S(1), COUT=>C(2), OPA => OP1(1));
U3: FA1bit port map (X=>X(2), Y=>Y(2), CIN=> C(2), SI=>S(2), COUT=>C(3), OPA => OP1(2));
U4: FA1bit port map (X=>X(3), Y=>Y(3), CIN=> C(3), SI=>S(3), COUT=>C4, OPA => OP1(3));
end FA4Bit_arch;
Everything compiles perfectly same goes for the following testbench.
library ieee;
use ieee.std_logic_1164.all;
entity FA4Bit_tb is
end ;
architecture arch of FA4Bit_tb is
component FA4Bit
port ( X1 : in std_logic_vector(3 downto 0);
Y : in std_logic_vector(3 downto 0);
C0 : in std_logic;
S : out std_logic_vector(3 downto 0);
C4 : out std_logic;
OP1: in std_logic_vector(3 downto 0));
end component;
signal X : std_logic_vector(3 downto 0) := "0000";
signal Y : std_logic_vector(3 downto 0) := "0000";
signal C0 : std_logic := '0';
signal opa: std_logic_vector(3 downto 0) := (others=>'0');
signal S : std_logic_vector(3 downto 0);
signal C4 : std_logic;
begin
UUT : FA4Bit
port map (X1 => X, Y => Y, C0 => C0, S => S, C4 => C4, OP1=> opa);
X <= not X after 5 ns;
Y <= not Y after 7 ns;
opa <= not opa after 9 ns;
end arch;
However, I'm receiving a FATAL ERROR in the loading design.
# ** Fatal: (vsim-3817) Port "X" of entity "fa4bit" is not in the component being instantiated.
# Time: 0 ns Iteration: 0 Instance: /fa4bit_tb/UUT File: C:/Users/Omar/Desktop/320 PROJECT 3ANJAD HAL MARRA/FA4Bit.vhd Line: 5
# FATAL ERROR while loading design
# Error loading design
This is one reason why I hate component instantiations. In your component instantiation, the port is called X1, not X. Renaming to X should fix this issue. Then you have a couple of similar ones to fix (OP and S on FA1bit).
If you use entity instantiations, then a lot of problems like this go away.

VHDL 1-bit ALU - behavioral

I just wrote this code of a 1-bit ALU with behavioral way.The code contains an overflow check. Can someone explain me if the code is correct ?
Here is the code:
entity ALU_VHDL is
port
(
a, b: in std_logic_vector(1 downto 0);
Operation : in std_logic_vector(2 downto 0);
Carry_Out : out std_logic;
Flag : out std_logic;
Result : out std_logic_vector(1 downto 0)
);
end entity ALU_VHDL;
architecture Behavioral of ALU_VHDL is
signal Temp: std_logic_vector(2 downto 0);
begin
process(a, b, Operation, temp) is
begin
Flag <= '0';
case Operation is
when "000" => -- resu = a + b, flag = carry = overflow
Temp <= std_logic_vector((unsigned("0" & a) + unsigned(b)));
Result <= temp(1 downto 0);
Carry_Out <= temp(2);
when "001" => -- resu = |a - b|, flag = 1 iff a > b
if (a >= b) then
Result <= std_logic_vector(unsigned(a) - unsigned(b));
Flag <= '0';
else
Result <= std_logic_vector(unsigned(a) - unsigned(b));
Flag <= '1';
end if;
when "010" =>
Result <= a and b;
when "011" =>
Result <= a or b;
when "100" =>
Result <= a xor b;
when "101" =>
Result <= not a;
when "110" =>
Result <= not b;
when others => -- resu = a + not b + 1, flag = 0
Temp <= std_logic_vector((unsigned("0" & Nibble1) + unsigned(not Nibble2)) + 1);
Result <= temp(1 downto 0);
Flag <= temp(2);
end case;
end process;
end architecture Behavioral;
I am new in VHDL so any advice is appreciated. Thanks in advance.

VHDL code error

I have this code for a Serial Adder in VHDL. I am trying to get it to work, but I keep on getting an error that says:
Errors found in VHDL File -
Line : 17, Error : Index constraint expected in the subtype indication
This error is referring to the line:
signal state, next_state : integer range 0 to 3;
I'm not sure why this is happening. Any help? Please find the full code below.
library ieee;
use ieee.std_logic_1164.all;
entity adder is
port(
start : in std_logic;
clk : in std_logic;
a_out : out std_logic_vector(3 downto 0)
);
end adder;
architecture behave of adder is
signal a, b : std_logic_vector(3 downto 0);
signal shift : std_logic;
signal Cin, Cout : std_logic;
signal sum_in : std_logic;
signal state, next_state : integer range 0 to 3;
begin
sum_in <= a(0) xor b(0) xor Cin;
Cout <= (Cin and a(0))or(Cin and b(0))or(a(0) and b(0));
a_out <= a;
process(state, start)
begin
case state is
when 0 =>
if start = '1' then shift <= '1'; next_state <= 1;
else shift <= '0'; next_state <= 2; end if;
when 1 => shift <= '1'; next_state <= 2;
when 2 => shift <= '1'; next_state <= 3;
when 3 => shift <= '1'; next_state <= 0;
end case;
end process;
process(clk)
begin
if clk'event and clk = '0' then
state <= next_state;
if shift = '1' then
a <= sum_in & a(3 downto 1);
b <= b(0) & b(3 downto 1);
Cin <= Cout;
end if;
end if;
end process;
end behave;
Try to replace your line in which you are getting error by:
signal state, next_state : integer is range 0 to 3;
If you are specifying range then you should use is range instead of range

How to force synthesizer to use RAM blocks to storage data - VHDL

I need to force my synthesizer or compiler to use RAM blocks to storage data.
For example, here's code:
type REG_Memory is array (0 to 3) of std_logic_vector(15 downto 0);
signal Memory : REG_Memory :=
(x"0001",
x"0010",
x"0100",
x"1000");
When I compile it and see compiler results it don't use any RAM blocks but logic cells. I need to use RAM blocks as Register storage, how I can do that? Device I'm using is IGLOO, can I do this? or it will loose data on device reboot?, synplify pro is the synthesizer.
Look in the documentation. Synplify has a good FPGA reference manual with code examples and constraints for how to get the behavior you desire. There are multiple ways to achieve what you want (in HDL, in constraint file, etc).
You want to look at the Synopsys FPGA Synthesis Reference Manual. Specifically in the Microsemi section. In the same manual, you can also find sections on RAM and ROM inference.
The manual is located in the "doc" directory of your installation.
Here is a ROM example they provide (there are other examples given):
library ieee;
use ieee.std_logic_1164.all;
entity rom4 is
port (a : in std_logic_vector(4 downto 0);
z : out std_logic_vector(3 downto 0));
end rom4;
architecture behave of rom4 is
begin
process(a)
begin
if a = "00000" then
z <= "0001";
elsif a = "00001" then
z <= "0010";
elsif a = "00010" then
z <= "0110";
elsif a = "00011" then
z <= "1010";
elsif a = "00100" then
z <= "1000";
elsif a = "00101" then
z <= "1001";
elsif a = "00110" then
z <= "0000";
elsif a = "00111" then
z <= "1110";
elsif a = "01000" then
z <= "1111";
elsif a = "01001" then
z <= "1110";
elsif a = "01010" then
z <= "0001";
elsif a = "01011" then
z <= "1000";
elsif a = "01100" then
z <= "1110";
elsif a = "01101" then
z <= "0011";
elsif a = "01110" then
z <= "1111";
elsif a = "01111" then
z <= "1100";
elsif a = "10000" then
z <= "1000";
elsif a = "10001" then
z <= "0000";
elsif a = "10010" then
z <= "0011";
else
z <= "0111";
end if;
end process;
end behave;

VHDL Code for Binary Division bug

I've written code for a binary divider that takes in an 8 bit dividend, 3 bit divisor, and gives a 5 bit quotient (3 bit remainder). I've literally spent hours trying to fix a bug that gives incorrect results but I haven't been able to identify it. Any help would be GREATLY appreciated! I basically get wrong answers for my inputs but I can't figure out why. There is a bus that takes in values and on the first clock cycle where st is 1, the dividend register is loaded. On the second clock cycle after, the divisor register is loaded and the calculation is made for the next three clock cycles.
The V signal is the output to signify that an overflow has occured (the result can't be fit into the five bits of the quotient), my st is the start signal to start the process, sh is the shift signal for the shift register, su is the subtract signal for the subtractor.
library IEEE;
use IEEE.STD_LOGIC_1164.all;
use IEEE.STD_LOGIC_ARITH.all;
use IEEE.STD_LOGIC_UNSIGNED.all;
entity Divider is
Port (bus_in: in std_logic_vector(8 downto 0);
St, Clk, reset: in std_logic;
Quotient: out std_logic_vector(4 downto 0);
Remainder: out std_logic_vector(2 downto 0);
v: out std_logic);
end Divider;
architecture Behavioral of Divider is
signal State, NextState: integer range 0 to 5;
signal C, Ld1, Ld2, Su, Sh: std_logic;
signal Divisor: std_logic_vector(2 downto 0);
signal Subout: std_logic_vector(3 downto 0);
signal Dividend: std_logic_vector(8 downto 0);
begin
Subout <= Dividend(8 downto 5) - ('0' & divisor);
C <= not Subout (3);
Remainder <= Dividend(7 downto 5);
Quotient <= Dividend(4 downto 0);
State_Graph: process (State, St, C)
begin
Ld1 <= '0';
Ld2<='0';
v <= '0';
Sh <= '0';
Su <= '0';
case State is
when 0 =>
if (St = '1') then
Ld1 <= '1';
NextState <= 1;
else
NextState <= 0;
end if;
when 1 =>
if (St = '1') then
Ld2 <= '1';
NextState <= 2;
else
Ld2<='1';
NextState <= 2;
end if;
when 2 =>
if (C = '1') then
v <= '1';
NextState <= 0;
else
Sh <= '1';
NextState <= 3;
end if;
when 3 | 4 =>
if (C = '1') then
Su <= '1';
NextState <= State;
else
Sh <= '1';
NextState <= State + 1;
end if;
when 5 =>
if (C = '1') then
Su <= '1';
end if;
NextState <= 0;
end case;
end process State_Graph;
Update: process (Clk)
begin
if Clk'event and Clk = '1' then
State <= NextState;
--if Load = '1' then
-- Dividend <= '0' & bus_in;
--end if;
if Ld1 = '1' then
Dividend <= '0'&Bus_in(7 downto 0);
end if;
if Ld2 = '1' then
Divisor <= Bus_in(2 downto 0);
end if;
if Su = '1' then
Dividend(8 downto 5) <= Subout;
Dividend(0) <= '1';
end if;
if Sh = '1' then --94
Dividend <= Dividend(7 downto 0) & '0';
end if;
end if;
end process update;
end Behavioral;
Here's my input and outputs:
[Signals]: http://imgur.com/fqfiYJZ 1
The picture shows that my registers for the divisor and dividend is loading correctly. So I think the issue is with the actual division code. The state machine also seems to be working correctly.
Don't write this yourself. You are re-inventing the wheel.
Either write q <= a / b;
or use an IP core from your FPGA vendor.

Resources