1
\$\begingroup\$

I'm trying to make a 4 bit adder with carry in & out, but I am having trouble converting Cin (Carry-in) to the type std_logic_vector when summing Sum and Cin together below in the architecture. Do you have any idea how i can make these types fit so that I can perform arithmetic on them together?

library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity four_bit_adder_simple is
 port(
 A, B : in std_logic_vector(3 downto 0);
 Cin : in std_logic;
 Sum : out std_logic_vector(3 downto 0);
 Cout : out std_logic);
end four_bit_adder_simple;
architecture unsigned_impl of four_bit_adder_simple is
 signal total : std_logic_vector(4 downto 0);
begin
 Sum <= std_logic_vector(resize(unsigned(A),5) + resize(unsigned(B),5));
 total <= Sum + Cin;
 Cout <= total(4);
end unsigned_impl;

EDIT: It was an error that I made Cout a 2 bit std_logic_vector. It should just have been a simple std_logic.

asked Oct 19, 2019 at 17:58
\$\endgroup\$
5
  • 1
    \$\begingroup\$ Cout is 2 bits wide, which is odd... You are possibly missitg the fact that an array aggregate with one member can't use positional association. So use named association. (0 => Cin) is a 1 bit SLV. \$\endgroup\$ Commented Oct 19, 2019 at 18:45
  • \$\begingroup\$ @BrianDrummond You need to add Cin, not concatenate it. So the total line is wrong. \$\endgroup\$ Commented Oct 19, 2019 at 18:53
  • \$\begingroup\$ As @BrianDrummond says, Cout looks like it should be corrected to a std_logic output. \$\endgroup\$ Commented Oct 19, 2019 at 18:54
  • \$\begingroup\$ If Cout should be an SLV, it should be a 1 bit SLV, e.g. (0 downto 0). And I was merely converting Cin to a SLV. Who mentioned concatenation? \$\endgroup\$ Commented Oct 19, 2019 at 18:58
  • 1
    \$\begingroup\$ Re: your edit. You still have an error. Your output Sum doesn't take Cin into account. \$\endgroup\$ Commented Oct 19, 2019 at 21:06

3 Answers 3

2
\$\begingroup\$

You need to cast cin to an unsigned, then add it in.

library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity four_bit_adder_simple is
 Port ( a : in std_logic_vector(3 downto 0);
 b : in std_logic_vector(3 downto 0);
 cin : in std_logic;
 sum : out std_logic_vector (3 downto 0);
 cout : out std_logic );
end four_bit_adder_simple;
architecture Behavioral of four_bit_adder_simple is
 signal total : std_logic_vector(4 downto 0);
begin
 total <= std_logic_vector(resize(unsigned(a),5) + resize(unsigned(b),5) + unsigned'('0'&cin));
 sum <= total(3 downto 0);
 cout <= total(4);
end Behavioral;

You'll end up with this: adder

Note that resize returns an unsigned here.

answered Oct 19, 2019 at 20:53
\$\endgroup\$
1
  • \$\begingroup\$ To simplify the code above, most type conversion/casting can be avoided by simply giving signals and ports the appropriate numeric type in the first place. \$\endgroup\$ Commented Oct 23, 2019 at 8:11
2
\$\begingroup\$

Seeing as to how the question was not actually answered:

signal s_vector: std_logic_vector(0 downto 0);
signal s_bit : std_logic : = '1';
...
s_vector <= (0 => s_bit);
answered Apr 28, 2021 at 20:11
\$\endgroup\$
0
\$\begingroup\$

The following is a simplification of your design that meets all the requirements and compiles in VHDL-93 onwards. It uses std_logic_unsigned rather than numeric_std. (Forgive the style changes, automatic when I typed and tested it.)

library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
entity FOUR_BIT_ADDER_SIMPLE is
 port(
 A : in std_logic_vector( 3 downto 0);
 B : in std_logic_vector( 3 downto 0);
 C_IN : in std_logic;
 SUM : out std_logic_vector( 3 downto 0);
 C_OUT : out std_logic
 );
end FOUR_BIT_ADDER_SIMPLE;
architecture RTL of FOUR_BIT_ADDER_SIMPLE is
 signal total : std_logic_vector( 4 downto 0);
begin
 total <= ('0' & A) + ('0' & B) + ("0000" & C_IN);
 SUM <= total( 3 downto 0);
 C_OUT <= total( 4);
end architecture RTL;

The 5-bit addition is done in one line by first padding each element with leading zeroes.

answered Oct 19, 2019 at 18:53
\$\endgroup\$
12
  • 2
    \$\begingroup\$ You cannot add std_logic_vectors like that. You need to cast them to a numeric type first. \$\endgroup\$ Commented Oct 19, 2019 at 18:56
  • 1
    \$\begingroup\$ It doesn’t work. It is only supported in VHDL-2008, but you must use ieee.numeric_std_unsigned. \$\endgroup\$ Commented Oct 19, 2019 at 19:08
  • \$\begingroup\$ @user110971 this does work but uses std_logic_unsigned, which is a non-standard package. You are correct that in VHDL-2008 the same functionality has been included in the standard library numeric_std_unsigned. \$\endgroup\$ Commented Oct 19, 2019 at 20:51
  • 1
    \$\begingroup\$ @ks0ze My above comment was a reply to a now deleted comment, so it seems confusing. Indeed the edited answer now works, but uses non-standard libraries, which is just bad practice. If you want to avoid excessive casting, you should just use Verilog. VHDL is a strongly typed language, which can be really annoying at times. In fact, I do prefer Verilog. See the original answer for the full context of my comment. \$\endgroup\$ Commented Oct 19, 2019 at 21:30
  • 1
    \$\begingroup\$ @TonyM Well I know about a case wherein the change of an FPGA vendor almost resulted in someone’s death due to the use of non-standard libraries. Avoid good practice at your own peril. \$\endgroup\$ Commented Oct 19, 2019 at 21:34

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.