So I have this lab assignment which carries on from a previous one where I implemented a single bit ALU in VHDL. The single bit ALU module takes an opcode and performs an operation based on this opcode e.g. addition or subtraction.
entity alu_slice is
Port ( a : in STD_LOGIC;
b : in STD_LOGIC;
s : out STD_LOGIC;
opcode : in STD_LOGIC_VECTOR (2 downto 0);
cin : in STD_LOGIC;
cout : out STD_LOGIC);
end alu_slice;
The opcode vector above is where the 3 bit opcode is placed at the time of simulation to tell the ALU what arithmetic operation to perform. The behavioural of the single bit ALU is given below:
architecture Behavioural of alu_slice is
architecture Behavioural of alu_slice is
begin
multiplex: process(a, b, opcode, cin) is begin
case opcode is
when "000" =>
--cin <= '0';
--s <= (a xor b) xor cin;
s <= (a xor b) xor cin;
cout <= (a and b) xor ((a xor b) and cin);
when "001" =>
s <= (a xor not b) xor cin;
cout <= (a and not b) xor ((a xor not b) and cin);
when "010" =>
s <= a and b;
when "011" =>
s <= a or b;
when "100" =>
s <= a xor b;
when "101" =>
s <= not a;
when "110" =>
--a <= cin;
cout <= a;
when "111" =>
s <= a xor cin;
cout <= a and cin;
when others =>
s <= (a xor b) xor cin;
cout <= (a and b) xor ((a xor b) and cin);
end case;
end process;
end behavioural;
I won't go into detail about what each of the opcodes are because that isn't part of the problem I'm having. I am supposed to use this alu slice as part of the architecture of a 4 bit ALU with four seperate instantiations of the alu_slice entity. The issue I am having is that if the code for the opcode is all inside the beavioural of the alu slice how is it supposed to be changed from the 4 bit module during simulation?
Here is the 4 bit alu entity I have made.
entity alu_pb is
Port ( a : in STD_LOGIC_VECTOR (3 downto 0);
b : in STD_LOGIC_VECTOR (3 downto 0);
s : out STD_LOGIC_VECTOR (3 downto 0);
--op: in STD_LOGIC_VECTOR (2 downto 0);
overflow : out STD_LOGIC;
compl_overflow : out STD_LOGIC;
zero : out STD_LOGIC);
end alu_pb;
This is using all of the signals I was told to use in my notes. I commented out the op vector because that is something I added trying to solve this problem. And so finally I have four ALU slices in the architecture of the project but I can't compile because I can't seem to figure out a way of updating the opcode logic vector in the alu slice component such that it is replicated across all of the separate slices performing the appropriate operation between each of the four bits.
Here is the rest of the code in the architecture:
architecture Behavioral of alu_pb is
component alu_slice is
Port(a: in STD_LOGIC;
b: in STD_LOGIC;
s: out STD_LOGIC;
opcode: in STD_LOGIC_VECTOR(2 down to 0);
cin: in STD_LOGIC;
cout: out STD_LOGIC);
end component;
signal carry: STD_LOGIC_VECTOR(3 down to 0);
signal op_carry: STD_LOGIC_VECTOR(2 down to 0);
signal sum_buffer: STD_LOGIC_VECTOR(3 down to 0);
signal carry_in: STD_LOGIC;
begin
slice_zero: alu_slice
port map(
--opcode(0) => op(0);
--opcode(1) => op(1);
--opcode(2) => op(2);
a => a(0),
b => b(0),
s => s(0),
--s => sum_buffer(0),
cin => carry_in,
cout=>carry(0)
);
slice_one: alu_slice
port map(
--op(0) => opcode(0),
--op(1) => opcode(1),
--op(2) => opcode(2),
a => a(1),
b => b(1),
s => s(1),
--s => sum_buffer(1)
cin => carry(0),
cout => carry(1)
);
slice_two: alu_slice
port map(
--op(0) => opcode(0),
--op(1) => opcode(1),
--op(2) => opcode(2),
a => a(2),
b => b(2),
s => s(2),
--s => sum_buffer(2)
cin => carry(1),
cout => carry(2)
);
slice_three: alu_slice
port map(
--op(0) => opcode(0),
--op(1) => opcode(1),
--op(2) => opcode(2),
a => a(3),
b => b(3),
s => s(3),
--s => sum_buffer(3),
cin => carry(2),
cout => carry(3)
);
--op_carry(0) <= op(0);
--op_carry(1) <= op(1);
--op_carry(2) <= op(2);
end Behavioral;
There is some other commented code at the end before 'end behavioral' but I omitted them because they are irrelevant to the actual problem and are to with the conditions whereby some of the ports of the alu_pb entity are set (compl_overflow, overflow, zero etc.)
If I try to simulate my model as is I get this error message:
"ERROR: [VRFC 10-704] formal opcode has no actual or default value [U:/alu/alu_pb.vhd:63]".
Hopefully one of you experienced VHDL guys will be able to help me track down a solution.
Thanks in advance,
Simon.
Related
This code works except for the add and subtract operations denoted by opcode 010 and 110 respectively. When I try to add the numbers the result looks as though a and b are being XOR'd and subtracting does A XNOR B. I have no idea why this is happening pls help. Also I am not allowed to use arithmetic plus or minus in my code the point of it is to add logically.
USE ieee.std_logic_1164.ALL;
USE ieee.std_logic_arith.ALL;
USE ieee.std_logic_unsigned.ALL;
USE ieee.numeric_std.ALL;
ENTITY Lab3ALU IS
PORT(
opcode :IN STD_LOGIC_VECTOR(2 DOWNTO 0);--INPUT
a :IN STD_LOGIC_VECTOR(31 DOWNTO 0);--INPUT
b :IN STD_LOGIC_VECTOR(31 DOWNTO 0);--INPUT
Cout :OUT STD_LOGIC;
Zero :OUT STD_LOGIC;
q :OUT STD_LOGIC_VECTOR(31 DOWNTO 0));--OUTPUT
END Lab3ALU;
ARCHITECTURE description of Lab3ALU IS
SIGNAL Reg1, Reg2, Reg3, Result : STD_LOGIC_VECTOR(31 DOWNTO 0);
SIGNAL Cin, Sum, Carry : STD_LOGIC;
BEGIN
-- Update the register output on the clock's rising edge
process (a,b, opcode)
begin
Cin <= opcode(2);
Reg1 <= a;--temporarirly store A in Reg1 local variable
Reg2 <= b;--temporarily store B in Reg2 local variable
Reg3 <= NOT b;
case opcode is
When "000" => Result <= Reg1 AND Reg2;--AND
When "001" => Result <= Reg1 OR Reg2;--OR
When "010" =>
addloop: for i in 0 to 31 loop
Result(i) <= ((Reg1(i) XOR Reg2(i)) XOR Cin);
Cin <= (((Reg1(i) XOR Reg2(i))AND Cin)OR (Reg1(i) AND Reg2(i)));
end loop addloop;
When "110" =>
subloop: for i in 0 to 31 loop
Result(i) <= ((Reg1(i) XOR Reg3(i)) XOR Cin);
Cin <= (((Reg1(i) XOR Reg3(i))AND Cin)OR (Reg1(i) AND Reg3(i)));
end loop subloop;
When "100" => Result(31 downto 1) <= reg1(30 downto 0);
Result(0) <= '0';
Cin <= '0';
When "101" => Result(30 downto 0) <= reg1(31 downto 1);
Result(31) <= '0';
Cin <= '0';
When others => Result <= "00000000000000000000000000000000";
end case;
if Result = "00000000000000000000000000000000" then
Zero <= '1';
else
Zero <= '0';
end if;
q<= Result;
Cout<= Cin;
end process;
END description;```
i am a bit new to VHDL and i try to learn by examples. So long story short i began with some basic examples like creating this Full Adder.
entity FA is
Port ( A : in STD_LOGIC;
B : in STD_LOGIC;
Cin : in STD_LOGIC;
S : out STD_LOGIC;
Cout : out STD_LOGIC);
end FA;
architecture gate_level of FA is
begin
S <= A XOR B XOR Cin ;
Cout <= (A AND B) OR (Cin AND A) OR (Cin AND B) ;
end gate_level;
After that i tried to implement this 4-bit adder
And this is the code that i wrote.
entity Ripple_Adder is
Port ( A : in STD_LOGIC_VECTOR (3 downto 0);
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 Ripple_Adder;
architecture Behavioral of Ripple_Adder is
-- Full Adder VHDL Code Component Decalaration
component FA
Port ( A : in STD_LOGIC;
B : in STD_LOGIC;
Cin : in STD_LOGIC;
S : out STD_LOGIC;
Cout : out STD_LOGIC);
end component;
-- Intermediate Carry declaration
signal c1,c2,c3: STD_LOGIC;
begin
-- Port Mapping Full Adder 4 times
FA1: FA port map( A(0), B(0), Cin, S(0), c1);
FA2: FA port map( A(1), B(1), c1, S(1), c2);
FA3: FA port map( A(2), B(2), c2, S(2), c3);
FA4: FA port map( A(3), B(3), c3, S(3), Cout);
end Behavioral;
Also i used a 4_bit_adder test bench file and i found out that the output is right. Now i am trying to implement a 4 bit multiplier with the usage of the 4 bit adder but i am a bit stuck. Actually this is the multiplier that i am trying to implement.
the code i wrote is this, but i am stuck at the port map
--library
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.std_logic_textio.all;
use IEEE.std_logic_unsigned.all;
--entity
entity multy is
port (x: in std_logic_vector(3 downto 0);
y: in std_logic_vector(3 downto 0);
p : out std_logic_vector(7 downto 0)
);
end multy ;
-- architecture
architecture rtl of multy is
component Ripple_Adder
Port ( A : in std_logic_vector (3 downto 0);
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 andgate: std_logic_vector(15 downto 0);
signal sumout: std_logic_vector( 11 downto 0);
signal carry: std_logic_vector(11 downto 0);
begin
andgate(0) <= x(0) and y(0);
andgate(1) <= x(1) and y(0); --b0
andgate(2) <= x(2) and y(0); --b1
andgate(3) <= x(3) and y(0); --b2
B
andgate(4) <= x(0) and y(1);
andgate(5) <= x(1) and y(1);
andgate(6) <= x(2) and y(1);
andgate(7) <= x(3) and y(1);
andgate(8) <= x(0) and y(2);
andgate(9) <= x(1) and y(2);
andgate(10) <= x(2) and y(2);
andgate(11) <= x(3) and y(2);
andgate(12) <= x(0) and y(3);
andgate(13) <= x(1) and y(3);
andgate(14) <= x(2) and y(3);
andgate(15) <= x(3) and y(3);
--gates
cell_1: Ripple_Adder port map();
cell_2: Ripple_Adder port map();
cell_3: Ripple_Adder port map();
--Assigning p values
p(0) <= andgate(0);
p(1) <= sumout(0);
p(2) <= sumout(4);
p(3) <= sumout(8);
p(4) <= sumout(9);
p(5) <= sumout(10);
p(6) <= sumout(11);
p(7) <= carry(11);
end rtl ;
"I am stuck on the port map" isn't a specific problem statement.
With named association members of formal ports in maps could be associated individually as well as in whole as long as all members of the formal are associated - IEEE Std 1076-2008 6.5.7 Association lists:
A formal interface object shall be either an explicitly declared interface object or member (see 5.1) of such an interface object. In the former case, such a formal is said to be associated in whole. In the latter cases, named association shall be used to associate the formal and actual; the subelements of such a formal are said to be associated individually. Furthermore, every scalar subelement of the explicitly declared interface object shall be associated exactly once with an actual (or subelement thereof) in the same association list, and all such associations shall appear in a contiguous sequence within that association list. Each association element that associates a slice or subelement (or slice thereof) of an interface object shall identify the formal with a locally static name.
Note you have too many carry elements (only need two), don't need andgate(0), don't need sumout(0), sumout(4) or sumout(11 downo 8), there's an extraneous character in the multy architecture, you're missing context clauses and have unused use clauses.
Your code using array intermediary signals:
library ieee;
use ieee.std_logic_1164.all;
-- use ieee.std_logic_textio.all; -- NOT USED
-- use ieee.std_logic_unsigned.all; -- NOT USED
entity multy is
port (
x: in std_logic_vector (3 downto 0);
y: in std_logic_vector (3 downto 0);
p: out std_logic_vector (7 downto 0)
);
end entity multy;
architecture rtl of multy is
component Ripple_Adder
port (
A: in std_logic_vector (3 downto 0);
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;
-- AND Product terms:
signal G0, G1, G2: std_logic_vector (3 downto 0);
-- B Inputs (B0 has three bits of AND product)
signal B0, B1, B2: std_logic_vector (3 downto 0);
begin
-- y(1) thru y (3) AND products, assigned aggregates:
G0 <= (x(3) and y(1), x(2) and y(1), x(1) and y(1), x(0) and y(1));
G1 <= (x(3) and y(2), x(2) and y(2), x(1) and y(2), x(0) and y(2));
G2 <= (x(3) and y(3), x(2) and y(3), x(1) and y(3), x(0) and y(3));
-- y(0) AND products (and y0(3) '0'):
B0 <= ('0', x(3) and y(0), x(2) and y(0), x(1) and y(0));
-- named association:
cell_1:
Ripple_Adder
port map (
a => G0,
b => B0,
cin => '0',
cout => B1(3), -- named association can be in any order
S(3) => B1(2), -- individual elements of S, all are associated
S(2) => B1(1), -- all formal members must be provide contiguously
S(1) => B1(0),
S(0) => p(1)
);
cell_2:
Ripple_Adder
port map (
a => G1,
b => B1,
cin => '0',
cout => B2(3),
S(3) => B2(2),
S(2) => B2(1),
S(1) => B2(0),
S(0) => p(2)
);
cell_3:
Ripple_Adder
port map (
a => G2,
b => B2,
cin => '0',
cout => p(7),
S => p(6 downto 3) -- matching elements for formal
);
p(0) <= x(0) and y(0);
end architecture rtl;
And a borrowed testbench to demonstrate:
library ieee;
use ieee.std_logic_1164.all;
entity multy_tb is -- testbench
end entity;
architecture foo of multy_tb is
signal x, y: std_logic_vector (3 downto 0);
signal yp, rp: std_logic_vector (7 downto 0);
use ieee.numeric_std.all;
function to_string (inp: std_logic_vector) return string is
variable image_str: string (1 to inp'length);
alias input_str: std_logic_vector (1 to inp'length) is inp;
begin
for i in input_str'range loop
image_str(i) := character'VALUE(std_ulogic'IMAGE(input_str(i)));
end loop;
return image_str;
end function;
begin
DUT:
entity work.multy
port map (
x => x,
y => y,
p => yp
);
STIMULI:
process
begin
for i in 0 to 15 loop
x <= std_logic_vector(to_unsigned(i, x'length));
for j in 0 to 15 loop
y <= std_logic_vector(to_unsigned(j, y'length));
wait for 0 ns; -- assignments take effect
rp <= std_logic_vector(unsigned (x) * unsigned(y));
wait for 10 ns;
if yp /= rp then
report "multy error";
report HT & "expected " & to_string (rp);
report HT & "got " & to_string (yp);
end if;
end loop;
end loop;
wait;
end process;
end architecture;
The to_string function is included for pre -2008 simulators. Context clauses were added to FA and Ripple_Adder.
I am very new to VHDL coding and I have been trying to debug my code for a 32-bit adder/subtractor. The N-bit adder/subtractor is composed multiple 1-bit adder/subtractor using a generate statement. I have been testing it for 6-bit inputs using simulation. The waveform is constantly incorrect and I have tried changing just about everything. Maybe, it is a problem with the delays and the generate statement not cycling through correctly. (I am just beginning to learn how to code in vhdl.)
My 1-bit adder/subtractor
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity addsub_1bit is
Port ( in_0 : in STD_LOGIC;
in_1 : in STD_LOGIC;
cin : in STD_LOGIC;
AddOrSub : in STD_LOGIC;
sum_sub : out STD_LOGIC;
cout_bout : out STD_LOGIC);
end addsub_1bit;
architecture data_flow_addsub_1bit of addsub_1bit is
begin
sum_sub <= (in_1 and (not in_0) and (not cin)) or ((not in_1) and in_0 and (not cin)) or ((not in_1) and (not in_0) and cin) or (in_1 and in_0 and cin) after 19 ns;
cout_bout <= (in_1 and in_0 and (not AddOrSub)) or ((not in_1)and in_1 and cin) or ((not in_1)and cin and AddOrSub) or (in_0 and cin) or (in_1 and cin and AddOrSub) after 19 ns;
end data_flow_addsub_1bit;
The N-bit adder/subtractor:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
ENTITY adder_sub32 is
GENERIC (BW : INTEGER :=32);
PORT ( a_32 : IN STD_LOGIC_VECTOR (BW -1 downto 0);
b_32 : IN STD_LOGIC_VECTOR (BW -1 downto 0);
cin : IN STD_LOGIC;
sub : IN STD_LOGIC;
sum_32 : out STD_LOGIC_VECTOR (BW -1 downto 0);
cout : INOUT STD_LOGIC ;
ov : OUT STD_LOGIC ); -- ov stands for overflow
END adder_sub32 ;
ARCHITECTURE adder_sub32_arch OF adder_sub32 IS
signal tmp : std_logic_vector (BW downto 0);
BEGIN
tmp(0) <= cin;
gen: for i IN 0 TO BW-1 GENERATE
as1: entity work.addsub_1bit
PORT MAP(
in_0 => a_32(i),
in_1 => b_32(i),
cin => tmp(i),
AddOrSub => sub,
sum_sub => sum_32(i),
cout_bout => tmp(i+1));
end GENERATE;
ov <= tmp(BW) after 95 ns;
END ARCHITECTURE;
My testbench:
LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
ENTITY adder_sub32_TB_SHan_53967364 IS
END adder_sub32_TB_SHan_53967364;
ARCHITECTURE behavior OF adder_sub32_TB_SHan_53967364 IS
-- Component Declaration for the Unit Under Test (UUT)
COMPONENT adder_sub32 IS
GENERIC (BW : INTEGER :=32);
PORT ( a_32 : IN STD_LOGIC_VECTOR (BW -1 downto 0);
b_32 : IN STD_LOGIC_VECTOR (BW -1 downto 0);
cin : IN STD_LOGIC ;
sub : IN STD_LOGIC ;
sum_32 : out STD_LOGIC_VECTOR (BW -1 downto 0);
cout : INOUT STD_LOGIC ;
ov : OUT STD_LOGIC ); -- ov stands for overflow
END COMPONENT;
signal a : std_logic_vector(5 downto 0); --:= (others => '0');
signal b : std_logic_vector(5 downto 0); --:= (others => '0');
signal cin : std_logic;
signal sub : std_logic;
signal cout : std_logic;
signal sum_32 : std_logic_vector(5 downto 0);
signal ov : std_logic;
BEGIN
test1: adder_sub32
GENERIC MAP (6)
PORT MAP (a_32 => a,b_32 => b,cin => cin,sub => sub,sum_32 => sum_32,cout => cout,ov => ov);
sub <= '0';
cin <= '0';
a <= "101010";
b <= "110101";
END;
The waveform I got:
The final sum is correct ("101010" + "110101" = "011111") in this case, but not in all cases.
EDIT2: Let's take a closer look, why the carry is not rippling as expected in your addition. The bits 0 (LSB) to 5 of the operands together, request that the carry-in is propagated from bit 0 to the carry-in of bit 6. Bits 6 of the operands generate a carry, which is carry-out of the adder. As the cin of bit 0 is '0', all intermediate carry-ins will be '0' too, but it should ripple through the carry-chain.
Now lets, take a look at the one-bit adder. You are adding two numbers, so that, AddOrSub is '0'. With this, the equation of cout_bout can be simplified to:
cout_bout <= (in_1 and in_0) or (in_0 and cin);
This equation is definitly wrong, because the carry-in is not propagated when in_1 = '1' and in_0 = '0'. Thus, some of the intermediate carries will be computed to '0' just after 19 ns without waiting for the rippling carry. The corresponding sum bit will be valid after 38 ns as shown in your waveform. The final value of the sum is not affected because this shortcuted carry is identical to the expected rippling carry. Please consider here, that all the 1-bit adder (generated by the generate statement) work concurrently.
To fix the equation, I recommend to write a testbench for the 1-bit adder. This testbench would have to check all possible 16 input combinations of in_0, in_1, cin, and AddOrSub.
Another testcase would be to add the above two operands with an cin of '1'.
(End of EDIT2.)
The ov is correct too in this case, but not in all cases.
EDIT: You mixed up the overflow ov with the carry-out cout. The overflow flag indicates an overflow in the signed number space. For the addition, the overflow flag is '1' if and only if:
the addition of two positive numbers results in a negative sum, or
the addition of two negative numbers results in a positive sum.
For subtraction it is the other way round.
Because this is a homework question, I will not solve it completely. But I will give a you a testcase where your current logic fails: if you add 1 ("000001") plus -1 ("111111"), then the sum must be zero, the overflow '0' and the carry-out '1'. (End of Edit.)
The cout is 'U' because you haven't connected it in adder_sub32. The carry-out is the top-most bit in your carry-chain, and thus:
cout <= tmp(BW);
And you should fix the direction of cout in adder_sub32. The carry-out is just an output of this component. So declare it as out instead of inout.
I'm having difficulty instantiating the fa0 portion of this code. I'm fairly new to VHDL so maybe more than just an answer would help.
This Logic 4 Module is structural code as a component to an ALU that I'm working on.
Thank you
-----------------------------------------------------------------
-- 4-bit adder/subtractor module
-----------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
entity addsub4 is
port (addl_subh : in std_logic;
X, Y : in std_logic_vector(3 downto 0);
S : out std_logic_vector(3 downto 0);
cout, ovf : out std_logic);
end addsub4;
architecture addsub4_arch of addsub4 is
component fa is
port (cin, x, y : in std_logic;
s, cout : out std_logic);
end component fa;
-- let Yhat denote the signal after Y xor addl_subh
signal Yhat: std_logic_vector(3 downto 0);
-- let carryout denote the cout signal for each fa module
signal carryout: std_logic_vector(3 downto 0);
begin
Yhat(0) <= Y(0) xor addl_subh;
Yhat(1) <= Y(1) xor addl_subh;
Yhat(2) <= Y(2) xor addl_subh;
Yhat(3) <= Y(3) xor addl_subh;
fa0: fa
port map ( cin => addl_subh, x => X(0), y => Yhat(0),
s => S(0), cout => carryout(0));
fa1: fa
port map ( cin => carryout(0), x => X(1), y => Yhat(1),
s => S(1), cout => carryout(1));
fa2: fa
port map ( cin => carryout(1), x => X(2), y => Yhat(2),
s => S(2), cout => carryout(2));
fa3: fa
port map ( cin => carryout(2), x => X(3), y => Yhat(3),
s => S(3), cout => carryout(3));
cout <= carryout(3);
ovf <= carryout(2) xor carryout(3);
end addsub4_arch;
your code has no errors and you should add a seperate file to your project that contains the fa (full adder) code. for example :
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
ENTITY fa IS
PORT(x,y,cin : IN std_logic;
s,cout : OUT std_logic);
END ENTITY;
ARCHITECTURE dataflow OF fa IS
begin
s <= x xor y xor cin;
cout <= ((x xor y) and cin) or (x and y);
end dataflow;
I am just trying to make a simple two's complement device in VHDL but it is throwing back this really annoying error and I'm unsure what I have done wrong. Probably something very silly...The error is
"Error (10327): VHDL error at twocompliment.vhd(21): can't determine definition of operator ""nand"" -- found 0 possible definitions"
The code is
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity twoscompliment is
generic
(
Nbits : positive := 8
);
port
(
--Inputs
A : in std_logic_vector (Nbits-1 downto 0);
--Outputs
Y : out std_logic_vector (Nbits downto 0)
);
end twoscompliment;
architecture twoscompliment_v1 of twoscompliment is
begin
Y <= std_logic_vector(unsigned(A NAND '1') + '1');
end twoscompliment_v1;
Any help would be awesome!
It seems to me you are trying to negate the input number... Maybe I'm missing something vital, but the other answers give a solution which, whilst achieving the goal, appear to be one step more obfuscated than they need to be.
Barring the ugly conversions, what's wrong with
y <= std_logic_vector(-signed(resize(unsigned(A)), y'length));
Of course, I would argue that if A and Y are supposed to be representing signed numbers (or unsigned numbers), they should be expressed as such:
library ieee;
use ieee.numeric_std.all;
entity twoscomplement is
generic
(
Nbits : positive := 8
);
port
(
A : in unsigned (Nbits-1 downto 0);
Y : out signed (Nbits downto 0)
);
end entity twoscomplement;
architecture a1 of twoscomplement is
begin
Y <= -signed(resize(A, Y'length));
end architecture;
Let's check the results:
entity test_twoscomplement is
end entity;
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
architecture test of test_twoscomplement is
signal A : unsigned (7 downto 0);
signal Y : signed(8 downto 0);
begin
dut : entity work.twoscomplement port map (A => A, Y=>Y);
process
begin
for i in 0 to 255 loop
A <= to_unsigned(i, A'length);
wait for 1 ns;
assert to_integer(Y) = -i severity error;
end loop;
report "tests done";
wait;
end process;
end architecture;
Running with GHDL:
$ ghdl -a twoscomp.vhd
$ ghdl --elab-run test_twoscomplement
twoscomp.vhd:40:8:#256ns:(report note): tests done
Success!
Try this:
architecture twoscompliment_v1 of twoscompliment is
signal temp : std_logic_vector(Nbits-1 downto 0);
begin
temp <= not A;
Y <= std_logic_vector(unsigned(temp + 1));
end twoscompliment_v1;
architecture twoscompliment_v1 of twoscompliment is
constant ONE: UNSIGNED(Y'RANGE) := (0 => '1', others => '0');
begin
Y <= std_logic_vector(unsigned (not A) + ONE);
end twoscompliment_v1;
Hi gentleman basically 2's complement is done by inverting the binary bits of a
given no. i.e changing ones to zeroes and zeroes to ones, after that add the
binary bit '1' to the Least significant bit of the given binary number. Now I
have a program
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
entity twoscomplementconversion is Port (
bin : in STD_LOGIC_VECTOR (3 downto 0);
twos : out STD_LOGIC_VECTOR (3 downto 0)
);
end twoscomplementconversion;
architecture Behavioral of twoscomplementconversion is
component fourbitadder45 Port (
a : in std_logic_vector (3 downto 0);
b : in std_logic_vector(3 downto 0);
cin : in std_logic;
cout : out std_logic;
sum : out std_logic_vector (3 downto 0)
);
end component;
signal onebit : std_logic_vector(3 downto 0):="0001";
signal cin1 : std_logic:='0';
signal notbin : std_logic_vector(3 downto 0);
signal cout1 : std_logic;
begin
notbin <= not(bin);
twos1: fourbitadder45 port map (
a => notbin,
b => onebit,
cin => cin1,
cout => cout1,
sum => twos
);
end Behavioral;
The four bit adder program is given below:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
entity fourbitadder45 is Port (
a : in std_logic_vector (3 downto 0);
b : in std_logic_vector(3 downto 0);
cin : in std_logic;
cout : out std_logic;
sum : out std_logic_vector (3 downto 0)
);
end fourbitadder45;
architecture Behavioral of fourbitadder45 is
component fulladder2 Port (
a : in std_logic;
b : in std_logic;
cin : in std_logic;
cout : out std_logic;
sum : out std_logic
);
end component;
signal c:std_logic_vector (3 downto 1);
begin
fa1 :fulladder2 port map (a => a(0), b => b(0), cin => cin, cout => c(1), sum => sum(0));
fa2 :fulladder2 port map (a => a(1), b => b(1), cin => c(1), cout => c(2), sum => sum(1));
fa3 :fulladder2 port map (a => a(2), b => b(2), cin => c(2), cout => c(3), sum => sum(2));
fa4 :fulladder2 port map (a => a(3), b => b(3), cin => c(3), cout => cout, sum => sum(3));
end Behavioral;
four bit adder contains 4 full adders so the full adder program is given below:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity fulladder2 is Port (
a : in std_logic;
b : in std_logic;
cin : in std_logic;
cout : out std_logic;
sum : out std_logic
);
end fulladder2;
architecture Behavioral of fulladder2 is
begin
sum <= a xor b xor cin;
cout <= ((a and b) or (b and cin) or (cin and a));
end Behavioral;
I hope that answers the question. This is a method there are many different methods