Why does this Full Adder Function not work VHDL - vhdl

Library IEEE;
use IEEE.STD_LOGIC_1164.all;
entity ALU is
port( A: in STD_LOGIC_VECTOR(7 downto 0);
B: in STD_LOGIC_VECTOR(7 downto 0);
C: in STD_LOGIC_VECTOR(3 downto 0);
Result: out STD_LOGIC_VECTOR(7 downto 0));
end ALU;
architecture arch of ALU is
----------------- SUM------------------------------------------------
function SUM (X:STD_LOGIC; Y:STD_LOGIC;CIN :STD_LOGIC) return STD_LOGIC is
variable Res: STD_LOGIC;
begin
Res:= X XOR Y XOR CIN;
return Res;
end SUM;
function Carry(X:STD_LOGIC; Y:STD_LOGIC;CIN :STD_LOGIC) return STD_LOGIC is
variable Res: STD_LOGIC;
begin
Res:=(X AND Y) OR (CIN AND X) OR (CIN AND Y);
return Res;
end Carry;
------------------------------------------------------------------
function Adder(A:STD_LOGIC_VECTOR;B :STD_LOGIC_VECTOR) return STD_LOGIC_VECTOR is
variable Res: STD_LOGIC_VECTOR(0 to 7);
variable Car: STD_LOGIC_VECTOR(0 to 8);
begin
Car(0):='0';
for i in 0 to 7 loop
Res(i):=SUM(A(i),B(i),Car(i));
Car(i+1):= Carry(A(i),B(i),Car(i));
end loop;
return Res;
end Adder;
begin
Result <= Adder("00110010","00000010");
end arch;
Hello I am a bit confused on why this full adder function does not work. I have tried multiple times to fix it however it does not give the correct output.
I am unsure where the errors are in the sum or carry or adder function. I do not know what to do to ensure it works. I also do not want to make a different component for a full adder.

Related

How can I calculate elements in one vector?

I'm new at VHDL code, and I'm trying to figure out, how is the easiest way to calculate elements in STD_LOGIC_VECTOR.
so how my ports look like:
Port ( D : in STD_LOGIC_VECTOR (width-1 downto 0); -- data input
parity : out STD_LOGIC -- parity bit
);
so I want to do something like this (code in c)
int helper = 0;
for (int i = 0; i < width; i++) {
if (D[i] == 1) {
helper++;
}
}
if (helper % 2 == 0) {
parity = 1;
}
if im not enought clear sorry for that, i can probably answer your question, if there will be.
Probably the best way to do this in VHDL is with xor_reduce from ieee.std_logic_misc. Addition modulo 2 is exactly the same as XOR, and xor_reduce XORs all of the inputs together, giving you the addition modulo 2 of your input bits. This would look like:
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_misc.xor_reduce;
entity PARITY_GEN is
generic (width : integer := 8);
port( D: in std_logic_vector(width-1 downto 0);
parity: out std_logic
);
end PARITY_GEN;
architecture bhv of PARITY_GEN is
begin
process(D)
begin
parity <= xor_reduce(D);
end process;
end bhv;
If you don't want to include xor_reduce, you could do the same just using xor:
library ieee;
use ieee.std_logic_1164.all;
entity PARITY_GEN is
generic (width : integer := 8);
port( D: in std_logic_vector(width-1 downto 0);
parity: out std_logic
);
end PARITY_GEN;
architecture bhv of PARITY_GEN is
begin
process(D)
variable temp:std_logic_vector(width-1 downto 0);
begin
temp(0) := D(0);
loop:for i in 1 to width-1 generate
temp(i) := temp(i-1) xor D(i);
end generate;
parity <= temp(width-1);
end process;
end bhv;

VHDL Waveform Simulation Line/Spikes Anomaly

I'm currently building a n-bit subtractor, and it appears to be working fine, but my waveform has these anomalous lines that instantaneously come and go. I'm not sure what's causing them, and it's been bugging me for days. You can see the spikes happening for the "negative" signal - I suspect it's because of some concurrency issue but I have tried searching all kinds of keywords to find the root of this problem and haven't come up with anything:
Code:
One bit full adder
library ieee;
use ieee.std_logic_1164.all;
entity one_bit_full_adder is
port (
x, y, cin : in std_logic;
sum, cout: out std_logic);
end one_bit_full_adder;
architecture arch of one_bit_full_adder is
begin
sum <= x xor y xor cin;
cout <= (x and y) or (cin and (x xor y));
end arch;
N-bit subtractor
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity n_bit_subtractor is
generic(constant BIT_LENGTH : integer);
port (
a, b : in std_logic_vector(BIT_LENGTH - 1 downto 0);
negative: out std_logic;
difference: out std_logic_vector(BIT_LENGTH - 1 downto 0));
end n_bit_subtractor;
architecture arch of n_bit_subtractor is
component one_bit_full_adder port (x, y, cin: in std_logic; sum, cout: out std_logic); end component;
signal carry_ins: std_logic_vector(BIT_LENGTH downto 0) := (0 => '1', others => '0');
signal differences: std_logic_vector(BIT_LENGTH - 1 downto 0);
signal b_operand: std_logic_vector(BIT_LENGTH - 1 downto 0);
begin
b_operand <= not b;
difference <= differences;
negative <= differences(BIT_LENGTH - 1) and '1';
adders: for i in 0 to BIT_LENGTH-1 generate
H2: one_bit_full_adder port map(x=>a(i), y=>b_operand(i), cin=>carry_ins(i), sum=>differences(i), cout=>carry_ins(i+1));
end generate;
end arch;
Testbench:
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity n_bit_subtractor_test is
end n_bit_subtractor_test;
architecture arch_test of n_bit_subtractor_test is
constant BIT_LEN : integer := 3;
component n_bit_subtractor is
generic(constant BIT_LENGTH : integer);
port (
a, b : in std_logic_vector(BIT_LENGTH - 1 downto 0);
negative: out std_logic;
difference: out std_logic_vector(BIT_LENGTH - 1 downto 0));
end component n_bit_subtractor;
signal p0, p1, difference: std_logic_vector(BIT_LEN-1 downto 0) := (others => '0');
signal negative: std_logic;
begin
uut: n_bit_subtractor
generic map (BIT_LENGTH => BIT_LEN)
port map (a => p0, b => p1, difference => difference, negative => negative);
process
variable difference_actual: std_logic_vector(BIT_LEN-1 downto 0) := (others => '0');
begin
for i in 0 to (2**BIT_LEN)-1 loop
for k in 0 to (2**BIT_LEN)-1 loop
wait for 200 ns;
p1 <= std_logic_vector(unsigned(p1) + 1);
end loop;
p0 <= std_logic_vector(unsigned(p0) + 1);
end loop;
report "No errors detected. Simulation successful." severity failure;
end process;
end arch_test;
Any help would be greatly appreciated. The ModelSim version is v10.1d

What happens if VHDL calls an infinite recursive function?

What happens in a design if VHDL calls an infinite recursive function? E.g. if I write some random code like:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity recursion is
port ( num : in std_logic_vector(15 downto 0);
exor_out : out std_logic_vector(1 downto 0)
);
end recursion;
architecture Behavioral of recursion is
function exor( num : std_logic_vector ) return std_logic_vector is
variable numf : std_logic_vector(num'length-1 downto 0):=(others => '0');
variable exorf : std_logic_vector((num'length/2)-1 downto 0):=(others => '0');
begin
numf := num;
exorf := exor(numf(num'length-1 downto num'length/2)) xor exor(numf((num'length/2)-1 downto 0));
return exorf;
end exor;
begin
exor_out <= exor(num);
end Behavioral;

VHDL : error in converting std_logic_vector to integer

I was writing a code in vhdl (xilinx) for a digital tachometer.
While converting the std_logic_vector m1 to integer the following errors were shown by the compiler.
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.numeric_std.all;
entity tacho is
Port ( A : in STD_LOGIC;
B : out STD_LOGIC_vector (15 downto 0));
end tacho;
architecture Behavioral of tacho is
component counter
port(
clk: in std_logic;
m: out std_logic_vector (4 downto 0));
end component;
signal m1 : std_logic_vector (4 downto 0);
variable y: integer := 0;
variable z: integer := 0;
begin
x: counter port map(A,m1);
y:= to_integer(unsigned(m1)); --error1:Syntax error near ":=". error2:Expecting type void for <to_integer>.
z:= y * 60; --Syntax error near ":=".
B <= std_logic_vector(to_unsigned(z, 16));
end Behavioral;
I found in many websites that the syntax i wrote is correct.
Please help!
Variables y and z can't be declared at architecture level. Use signals instead, and the signal assign <=, like:
...
signal y : integer;
signal z: integer := 0;
begin
x: counter port map(A, m1);
y <= to_integer(unsigned(m1));
z <= y * 60;
B <= std_logic_vector(to_unsigned(z, 16));
...
Or simply combine it and avoid the intermediates y and z, like:
...
x: counter port map(A, m1);
B <= std_logic_vector(resize(60 * unsigned(m1), B'length));
...
A non-shared variable can only be declared in a process statement or subprogram. You could place your scaling code in a process:
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity tacho is
port ( A: in std_logic;
B: out std_logic_vector (15 downto 0)
);
end entity tacho;
architecture behavioral of tacho is
component counter is
port (
clk: in std_logic;
m: out std_logic_vector (4 downto 0)
);
end component;
signal m1 : std_logic_vector (4 downto 0);
begin
x: counter port map (A, m1);
scaling:
process (m1)
variable y: integer := 0;
variable z: integer := 0;
begin
y := to_integer(unsigned(m1));
z := y * 60;
B <= std_logic_vector(to_unsigned(z, 16));
end process;
end architecture behavioral;
Or you could move your calculations to a subprogram:
architecture scaled of tacho is
component counter is
port (
clk: in std_logic;
m: out std_logic_vector (4 downto 0)
);
end component;
signal m1 : std_logic_vector (4 downto 0);
function scale(m1: std_logic_vector (4 downto 0); SIZE: natural := 16)
return std_logic_vector is
variable y: integer;
variable z: integer;
begin
y := to_integer(unsigned(m1));
z := y * 60;
return std_logic_vector(to_unsigned(z, SIZE));
end function;
begin
x: counter port map (A, m1);
scaled_output:
B <= scale(m1);
end architecture;
Both of these analyze.

Multiplication of a scalar with a vector

I am writing code in VHDL in which a number is multiplied by a vector. But it gives an error.
Library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all;
entity multi is
port ( clk : in std_logic;
ipixel : in std_logic_vector(15 downto 0);
opixel : out std_logic_vector(15 downto 0)
);
end entity multi;
architecture rtl of multi is
begin
process (clk) begin
if rising_edge (clk) then
opixel (15 downto 11) <= std_logic_vector(unsigned(ipixel(15 downto 11))*3);
opixel (10 downto 5) <= std_logic_vector(unsigned(ipixel(10 downto 5))* 3);
opixel (4 downto 0) <= std_logic_vector(unsigned(ipixel(4 downto 0))* 3);
end if;
end process;
end architecture rtl;
The error is:
Target slice 5 elements; Value is 10 elements
When you multiply an unsigned value with a natural, this is defined in NUMERIC_STD as follows:
function "*" (L: UNSIGNED; R: NATURAL) return UNSIGNED is
begin
return L * TO_UNSIGNED(R, L'LENGTH);
end "*";
Return value will result in 2 * length of your unsigned factor!

Resources