I am trying to convert a std_logic_vector in its two's complement. I am trying to perform -2 multiplication on a vector.
library ieee;
use ieee.std_logic_1164.all;
entity twoscomplement is
port ( x : in std_logic_vector(15 downto 0);
y : out std_logic_vector(15 downto 0)
);
end entity;
architecture model of twoscomplement is
signal x_c : std_logic_vector (15 downto 0);
x_c <= (not(x) +'1')*2 ; -- x_c = -2*x
end model;
add library
use IEEE.numeric_std.all;
... inside architecture
x_c <= signed(x);
Try converting to integers and work with them.
Check out this webpage on conversions.
visit http://www.bitweenie.com/listings/vhdl-type-conversion/
Related
I try to implement an architecture that has only an 8-bit adder-subtractor. But there is an issue I can't solve. When I use subtractor architecture, I need to calculate carry-out, but I couldn't.
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use ieee.numeric_std.all;
entity sub is
port ( a : in std_logic_vector(7 downto 0);
b : in std_logic_vector(7 downto 0);
o : out std_logic_vector(7 downto 0)
);
end sub;
architecture Behavioral of sub is
signal a2,b2 : unsigned (7 downto 0);
begin
a2<=unsigned(a);
b2<=unsigned(b);
o<=std_logic_vector(a2-b2);
end Behavioral;
Edit: I'm talking about "c1" and "c5" signals in the picture.
You need to extend both operands by one bit, so the carry out is collected in the MSB of the result. The result is decomposed into carry bit c and subtraction result o.
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.numeric_std.all;
entity sub is
port (
a : in std_logic_vector(7 downto 0);
b : in std_logic_vector(7 downto 0);
o : out std_logic_vector(7 downto 0);
c : out std_logic
);
end entity;
architecture rtl of sub is
begin
(c, o) <= std_logic_vector(unsigned('0' & a) - unsigned('0' & b));
end architecture;
Note: This is VHDL-2008 code.
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 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.
I am trying to add two std_logic_vectors using the notation given below:-
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;
entity adder is
port( a:in std_logic_vector(31 downto 0);
b:in std_logic_vector(31 downto 0);
o:out std_logic_vector(31 downto 0));
end adder;
architecture Behavioral of adder is
begin
o<=a+b;
end Behavioral;
One possibility is to generate the result with carry, and then split that afterwards, like:
architecture Behavioral of adder is
signal c_o : std_logic_vector(o'length downto 0); -- Result with carry
signal c : std_logic; -- Carry only
begin
c_o <= ('0' & a) + b; -- Result with carry; extended with '0' to keep carry
o <= c_o(o'range); -- Result without carry
c <= c_o(c_o'left); -- Carry only
end Behavioral;
You can do this. The carry is not saved, but it's being reported that there was an overflow.
function "+" (Add1: std_logic_vector; Add2: std_logic_vector) return std_logic_vector is
variable big_sum: bit_vector(Add1'LENGTH downto 0);
begin
big_sum = Add1 + Add2;
assert big_sum(Add1'LENGTH) = 0
report "overflow"
severity warning;
return big_sum(Add1'LENGTH-1 downto 0);
Of course you'll need to define a new package and also include that package in your already existing file.
o<=std_logic_vector(unsigned(a)+unsigned(b))
Although I suggest you use unsigned/signed on your ports (and have a clock cycle of latency).
If you want the carry
o_with_carry <= std_logic_vector('0'&unsigned(a)+unsigned(b));
o_carry <= o_with_carry(o_with_carry'high);
o <= o_with_carry(o'range);
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).