In VHDL i want to add a number of 5 bits and a number of 8 bits.(Unsigned) And how many bits does the output have?
I want my code to answer the questions i just asked. My code currently look like this...
My code is:
library ieee;
use ieee-std_logic_1164.all;
entity adder is
port( a : in unsigned (7 downto 0);
b : in unsigned (4 downto 0); - - Need to convert this to 8 bit right? But how?
z : out unsigned(7 downto 0)); - - This one must be 8 bits right? Cuz a & b & z must have the same WL. Or am i wrong?
end adder;
archictecture add of adder is
begin
z <= a + b;
end archictecture;
In package numeric_std for function "+" (L, R: UNSIGNED) return UNSIGNED
the length of the longest argument defines the return value length:
function "+" (L, R: UNSIGNED) return UNSIGNED is
constant SIZE: NATURAL := MAX(L'LENGTH, R'LENGTH);
variable L01 : UNSIGNED(SIZE-1 downto 0);
variable R01 : UNSIGNED(SIZE-1 downto 0);
begin
if ((L'LENGTH < 1) or (R'LENGTH < 1)) then return NAU;
end if;
L01 := TO_01(RESIZE(L, SIZE), 'X');
if (L01(L01'LEFT)='X') then return L01;
end if;
R01 := TO_01(RESIZE(R, SIZE), 'X');
if (R01(R01'LEFT)='X') then return R01;
end if;
return ADD_UNSIGNED(L01, R01, '0');
end "+";
The maximum of the left and right arguments length is SIZE
, the range of the two arguments is is resized to SIZE -1 downto 0
as arguments to ADD_UNSIGNED
.
function ADD_UNSIGNED (L, R: UNSIGNED; C: STD_LOGIC) return UNSIGNED is
constant L_LEFT: INTEGER := L'LENGTH-1;
alias XL: UNSIGNED(L_LEFT downto 0) is L;
alias XR: UNSIGNED(L_LEFT downto 0) is R;
variable RESULT: UNSIGNED(L_LEFT downto 0);
variable CBIT: STD_LOGIC := C;
begin
for I in 0 to L_LEFT loop
RESULT(I) := CBIT xor XL(I) xor XR(I);
CBIT := (CBIT and XL(I)) or (CBIT and XR(I)) or (XL(I) and XR(I));
end loop;
return RESULT;
end ADD_UNSIGNED;
The RESULT
's length is that of the L argument which is the same of both arguments to UNSIGNED_ADD
. There is no carry out implied in the result.
As in your case the result, assigned to z
can be 8 bits.
Fix the comment delimiters in the port declarations, add a use clause to access package numeric_std, fix a '-' that should be a '.', spelling of architecture
and add a test bench adding values for a
and b
set to all '1's and you can analyze, elaborate and run your design without error, telling you there isn't an array length error executing.
To get that ninth 'bit' as an output of the adder you can RESIZE
one of your arguments to +
to 9 bits or concatenate one argument with leading zeros to make a 9 bit value:
z <= "0" & a + b;
It'll demonstrate that the 9th bit is needed for an accurate result:
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity adder is
port(
a: in unsigned (7 downto 0);
b: in unsigned (4 downto 0);
z: out unsigned (8 downto 0)
);
end adder;
architecture add of adder is
begin
z <= "0" & a + b;
end architecture;
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity tb_adder is
end entity;
architecture foo of tb_adder is
signal a: unsigned (7 downto 0) := (others => '1');
signal b: unsigned (4 downto 0) := (others => '1');
signal z: unsigned (8 downto 0);
function unsigned_image(inp: unsigned) return string is
variable image_str: string (1 to inp'length);
alias input_str: unsigned (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;
begin
DUT:
entity work.adder
port map (
a => a,
b => b,
z => z
);
MONITOR:
process
begin
wait for 1 ns;
report "z = " & unsigned_image(z);
wait;
end process;
end architecture;
david_koontz@Macbook: ghdl -a adder.vhdl
david_koontz@Macbook: ghdl -e tb_adder
david_koontz@Macbook: ghdl -r tb_adder
adder.vhdl:54:9:@1ns:(report note): z = 100011110