How to deal with signed numbers correctly and still use "+" - vhdl

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
entity alu_16 is
Port ( a : in STD_LOGIC_VECTOR(15 downto 0);
b : in STD_LOGIC_VECTOR(15 downto 0);
sel : in STD_LOGIC_VECTOR (1 downto 0);
gt : out STD_LOGIC;
lt : out STD_LOGIC;
eq : out STD_LOGIC;
result : out SIGNED(15 downto 0);
overflow : out STD_LOGIC;
cout : in STD_LOGIC);
end alu_16;
architecture Behavioral of alu_16 is
signal inter_res : SIGNED(16 downto 0);
signal subtraction : SIGNED(16 downto 0);
signal addition : SIGNED (16 downto 0);
signal carry_in : STD_LOGIC;
signal carry_out : STD_LOGIC;
signal msb_bit_add : STD_LOGIC;
begin
gt <= '1' when a > b else '0';
lt <= '1' when a < b else '0';
eq <= '1' when a = b else '0';
subtraction <= signed(a) - signed(b);
addition <= signed(a) + signed(b);
with sel select
inter_res <= addition when "00",
subtraction when "01",
signed(a) AND signed(b) when "10",
signed(a) OR signed(b) when others;
carry_out <= inter_res(16);
msb_bit_add <= std_logic(a(15) + b(15));
carry_in <= msb_bit_add XOR inter_res(15);
overflow <= NOT(carry_in XOR carry_out);
result <= inter_res(15 downto 0);
end Behavioral;
So.. I'm trying to make a 16 bit signed adder without using a ripple carry adder. However, I am getting errors about overloading the + operator at the one bit add for msb_bit_add. Can anyone shed some light on what I should do on that line?
Thanks!

Related

VHDL 8-bit adder with carry & testbench

Heyo!
I've been trying to get into programming vhdl again for some upcoming classes and tried to do an simple 8-bit adder and wanted to test it with a testbench. (I'm working with the Vivado Xilinx Software btw~)
I don't get any syntax errors, but it shows the variables as "U" (I guess undefined?)
Hope it's easy to see what I did (and why lol). Yea but I can't really find the problem??
My code:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity addierer is
Port ( a : in STD_LOGIC_VECTOR(7 downto 0);
b : in STD_LOGIC_VECTOR(7 downto 0);
cin : in STD_LOGIC;
s : out STD_LOGIC_VECTOR(7 downto 0);
cout : out STD_LOGIC);
end addierer;
architecture Behavioral of addierer is
COMPONENT volladdierer is
Port ( a : in STD_LOGIC;
b : in STD_LOGIC;
cin : in STD_LOGIC;
s : out STD_LOGIC;
cout : out STD_LOGIC
);
end COMPONENT;
signal c : STD_LOGIC_VECTOR(6 downto 0);
begin
PROCESS (a,b,cin)
BEGIN
s(0) <= a(0) xor b(0) xor cin; --erstes s wird noch mit cin berechnet
c(0) <= (cin and b(0)) or (cin and a(0)) or (a(0) and b(0)); --sowie das erste cout
for i in 1 to 7 loop --Schleife um Stellen der Arrays durchzugehen
s(i) <= a(i) xor b(i) xor c(i-1);
c(i) <= (c(i-1) and b(i)) or (c(i-1) and a(i)) or (a(i) and b(i));
end loop;
cout <= c(6);
END PROCESS;
end Behavioral;
testbench I used:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity testbench_addierer is
-- Port ( );
end testbench_addierer;
architecture Behavioral of testbench_addierer is
SIGNAL a : STD_LOGIC_VECTOR(7 downto 0);
SIGNAL b : STD_LOGIC_VECTOR(7 downto 0);
SIGNAL cin : STD_LOGIC;
SIGNAL s : STD_LOGIC_VECTOR(7 downto 0);
SIGNAL cout : STD_LOGIC;
COMPONENT addierer IS
PORT(
a : IN STD_LOGIC_VECTOR(7 downto 0);
b : IN STD_LOGIC_VECTOR(7 downto 0);
cin : IN STD_LOGIC;
s : OUT STD_LOGIC_VECTOR(7 downto 0);
cout: OUT STD_LOGIC
);
END COMPONENT;
begin
U1: addierer
PORT MAP(
a => a,
b => b,
cin => cin,
s => s,
cout => cout
);
process
begin
a <= "00000000" after 0ms;
a <= "00000001" after 10ms;
a <= "01010101" after 20ms;
b <= "00000000" after 0ms;
b <= "10001001" after 10ms;
b <= "00000001" after 20ms;
cin <= '0' after 0ms;
cin <= '0' after 10ms;
cin <= '0' after 20ms;
end process;
end Behavioral;
Thanks already and hmu if something's unclear in my code!!
(and pls keep in mind I'm an total beginner.. xD)

LFSR doesn't generate random values during simulation

I am new to VHDL, but have some idea. I made this LFSR but don't know why it is stuck between the initial seed value and the other XOR value.
I am working with Altera Quartus 16 Lite and ISim.
library ieee;
use ieee.std_logic_1164.all;
--creating a galois LFSR
entity LFSR is
port (
clk : in std_logic;
rst : in std_logic;
en : in std_logic;
rdm_out : out std_logic_vector(15 downto 0);
rdm_out_a : out std_logic_vector(7 downto 0);
rdm_out_b : out std_logic_vector(7 downto 0);
lfsr_Done : out std_logic --lfsr done
);
end entity LFSR;
architecture behavioral of LFSR is
signal temp_out : std_logic_vector(15 downto 0) := (0 => '1' ,others => '0'); --initial value as seed
signal temp_done : std_logic;
begin
process (clk, rst)
begin
if rising_edge (clk) then --module operates only when enabled
if (rst = '1') then
temp_out <= (0 => '1' ,others => '0');
temp_done <= '0';
elsif (en = '1') then
temp_out <= temp_out(15 downto 11) & (temp_out(10) xor temp_out(0)) & temp_out(9 downto 5) & (temp_out(4) xor temp_out(0)) & temp_out(3 downto 0);
--temp_out <= (temp_out(15) xor temp_out(0)) & (temp_out(14) xor temp_out(0)) & temp_out(13) & (temp_out(12) xor temp_out(0)) & temp_out(11 downto 4) & (temp_out(3) xor temp_out(0)) & temp_out(2 downto 0);
temp_done <= '1';
end if;
end if;
end process;
rdm_out <= temp_out(15 downto 0);
rdm_out_a <= temp_out(15 downto 8);
rdm_out_b <= temp_out(7 downto 0);
lfsr_Done <= temp_done;
end architecture behavioral;`
The commented out temp_out is actual feedback (taps are 16,15,13, and 4) as I checked with random taps but still no improvement.
And the testbench I used is this:
library ieee;
use ieee.std_logic_1164.all;
entity lfsr_tb is
end lfsr_tb;
architecture test_bench of lfsr_tb is
component LFSR
port (
clk : in std_logic;
rst : in std_logic;
en : in std_logic;
rdm_out : out std_logic_vector(15 downto 0);
rdm_out_a : out std_logic_vector(7 downto 0);
rdm_out_b : out std_logic_vector(7 downto 0);
lfsr_Done : out std_logic );
end component;
signal clk1: std_logic;
signal rst1: std_logic;
signal en1 : std_logic;
signal rdm_out1 : std_logic_vector(15 downto 0);
signal rdm_out_a1 : std_logic_vector(7 downto 0);
signal rdm_out_b1 : std_logic_vector(7 downto 0);
signal lfsr_Done1 : std_logic ;
begin
mapping: LFSR port map(
clk => clk1,
rst => rst1,
en => en1,
rdm_out => rdm_out1,
rdm_out_a => rdm_out_a1,
rdm_out_b => rdm_out_b1,
lfsr_Done => lfsr_Done1 );
clock: process
begin
clk1 <= '0'; wait for 10 ps;
clk1 <= '1'; wait for 10 ps;
end process;
reset: process
begin
rst1 <= '1'; wait for 10 ps;
rst1 <= '0';
en1 <= '1'; wait for 800 ps;
end process;
end test_bench;
This is the result I am getting:
Yes it was not shifting but this is one is working now.
temp_out(15) <= temp_out(0);-- shifting bit
temp_out(14) <= temp_out(15);
temp_out(13) <= temp_out(14) xor temp_out(0);
temp_out(12) <= temp_out(13) xor temp_out(0);
temp_out(11) <= temp_out(12);
temp_out(10) <= temp_out(11) xor temp_out(0);
temp_out(9 downto 0) <= temp_out(10 downto 1);
Hope it helps others. Thanks guys

How to initialize a VHDL std_logic_vector to "0001"

i want to initialize my vectors from "0001" instead of "0000" default cause i'm doing an "automatic" 4 Bit multiplier and (x * 0) isn't useful, so
I want to skip the "0000" value.
Here is my Entity:
ENTITY multiplier IS
PORT (
clk, rst : IN std_logic;
q, r : INOUT std_logic_vector (3 DOWNTO 0) := "0001"; -- this not work
f : OUT std_logic_vector(7 DOWNTO 0)
);
END multiplier;
Use intermediate signals
library ieee;
use ieee.std_logic_1164.all;
entity multiplier IS
port (
clk : in std_logic;
rst : in std_logic;
q : out std_logic_vector(3 downto 0);
r : out std_logic_vector(3 downto 0);
f : out std_logic_vector(7 downto 0)
);
end entity;
architecture rtl of multiplier is
use ieee.numeric_std.all;
signal q_temp: unsigned(3 downto 0) := "0001"; -- or signed
signal r_temp: unsigned(3 downto 0) := "0001"; -- or signed
begin
[...your code...]
q <= std_logic_vector(q_temp);
r <= std_logic_vector(r_temp);
end architecture;

Simple VHDL ALU will not show inputs or overflow in the waveform

I'm supposed to write up a 16-bit ALU. My professor wants us to try and code the adder and sub of the ALU with a
signal tmp : std_logic_vector(16 downto 0); and then in the case for the select input s we put:
tmp <= conv_std_logic_vector(conv_integer(a) + conv_integer(b), 17);
After experimenting with it for a while, my waveform only showed the inputs' values as UUUUUUUUUUUUUUUU. Even after I had commented out the conv_std_logic_vector(...) stuff.
Is there a simple explanation as to why my inputs aren't showing up in the waveform?
Here is my code:
-- 16-Bit ALU
-- By: Logan Jordon
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
use IEEE.NUMERIC_STD.ALL;
--use ieee.std_logic_arith.all;
 
entity alu16 is
port (
a : in std_logic_vector(15 downto 0);
b : in std_logic_vector(15 downto 0);
s : in std_logic_vector(1 downto 0);
r : out std_logic_vector(15 downto 0);
cout : out std_logic;
lt, eq, gt : out std_logic;
overflow : out std_logic
);
end entity alu16;
architecture beh of alu16 is
signal tmp : std_logic_vector(16 downto 0);
signal add_overflow : std_logic;
signal sub_overflow : std_logic;
begin
-- PROCESS
process(a, b, add_overflow, sub_overflow)
begin
case s is
--ADD
when "00" =>
--tmp <= conv_std_logic_vector(conv_integer(a) + conv_integer(b), 17);
tmp <= a + b;
overflow <= add_overflow;
--SUB
when "01" =>
--tmp <= conv_std_logic_vector(conv_integer(a) - conv_integer(b), 17);
tmp <= a - b;
overflow <= sub_overflow;
--AND
when "10" =>
tmp <= '0' & a AND b;
overflow <= '0';
--OR
when "11" =>
tmp <= '0' & a OR b;
overflow <= '0';
when others =>
tmp <= "00000000000000000";
end case;
--One-Bitters
if a > b then
gt <= '1';
lt <= '0';
eq <= '0';
elsif a < b then
lt <= '1';
gt <= '0';
eq <= '0';
elsif a = b then
eq <= '1';
lt <= '0';
gt <= '0';
end if;
end process;
--OUTPUTS
cout <= tmp(16);
r <= tmp(15 downto 0);
add_overflow <= '1' when (a(15) = b(15)) and (a(15) /= tmp(15))
else '0';
sub_overflow <= '1' when (a(15) = NOT b(15)) and (a(15) /= tmp(15))
else '0';
end beh;
EDIT: In the case that it might be my test bench, here's the code for my testbench:
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
use IEEE.NUMERIC_STD.ALL;
entity alu16_tb is
end alu16_tb;
architecture behavior of alu16_tb is
component ALU16
port(
a : in std_logic_vector(15 downto 0);
b : in std_logic_vector(15 downto 0);
s : in std_logic_vector(1 downto 0);
r : out std_logic_vector(15 downto 0);
cout : out std_logic;
lt, eq, gt : out std_logic;
overflow : out std_logic
);
end component;
-- Signals to interface with the UUT
-- Set each of the input vectors to unique values to avoid
-- needing a process to drive them below
signal a : std_logic_vector(15 downto 0) := "0000000000000000";
signal b : std_logic_vector(15 downto 0) := "0000000000000000";
signal s : std_logic_vector(1 downto 0) := "00";
signal r : std_logic_vector(15 downto 0):= "0000000000000000";
signal cout : std_logic := '0';
signal lt : std_logic := '0';
signal gt : std_logic := '0';
signal eq : std_logic := '0';
signal overflow : std_logic := '0';
constant tick : time := 10 ns;
begin
-- Instantiate the Unit Under Test (UUT)
uut : ALU16 port map (
a => a,
b => b,
s => s,
r => r,
cout => cout,
lt => lt,
gt => gt,
eq => eq,
overflow => overflow
);
-- Drive selector bits
drive_s : process
begin
a <= "0000000000000001";
b <= "0000000000000010";
wait for (tick*2);
s <= "00";
wait for (tick*2);
s <= "01";
wait for (tick*2);
s <= "10";
wait for (tick*2);
s <= "11";
end process drive_s;
end;

32-bit comparator waveform issue (VHDL)

My waveform does not change:
I am working on my 32-bit comparator project. I already have an 1 bit one. I do not know where is the issue. Anyone can help me find that?
Thanks so much
Code:
1bit:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
ENTITY comp1 is
port (a : IN std_logic ;
b : IN std_logic ;
g : IN std_logic ;
l : IN std_logic ;
e : IN std_logic ;
great : OUT std_logic ;
less : OUT std_logic ;
equal : OUT std_logic );
END ;
ARCHITECTURE comp1_arch OF comp1 IS
signal s1,s2,s3: std_logic;
begin
s1 <= (a and (not b));
s2 <= (not ((a and (not b)) or (b and (not a))));
s3 <= (b and (not a));
equal <= (e and s2) after 30 ns;
great <= (g or(e and s1)) after 27 ns;
less <= (l or(e and s3)) after 27 ns;
end comp1_arch;
32 bit:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
ENTITY comp32 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);
g_32 : OUT STD_LOGIC ;
l_32 : OUT STD_LOGIC ;
e_32 : OUT STD_LOGIC );
END comp32;
ARCHITECTURE comp32_arch OF comp32 IS
COMPONENT comp1
PORT (a,b,g,l,e : IN std_logic ;
great,less,equal : OUT std_logic);
END COMPONENT comp1;
signal gre : std_logic_vector(BW downto 0);
signal les : std_logic_vector(BW downto 0);
signal equ : std_logic_vector(BW downto 0);
begin
gre(0)<='0';les(0)<='0';equ(0)<='0';
gen: for i in 0 to BW-1 generate
biti: comp1 port map( a => a_32(i),b => b_32(i), g => gre(i), l => les(i), e =>equ(i),
great => gre(i+1), less => les(i+1), equal => equ(i+1));
end generate;
g_32 <= gre(BW-1);
l_32 <= les(BW-1);
e_32 <= equ(BW-1);
end comp32_arch;
Test Bench:
LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
ENTITY comp32_TB IS
END comp32_TB;
ARCHITECTURE behavior OF comp32_TB IS
COMPONENT comp32
PORT(
a_32 : IN std_logic_vector(31 downto 0);
b_32 : IN std_logic_vector(31 downto 0);
g_32 : OUT std_logic;
l_32 : OUT std_logic;
e_32 : OUT std_logic
);
END COMPONENT;
signal a_32 : std_logic_vector(31 downto 0) := (others => '0');
signal b_32 : std_logic_vector(31 downto 0) := (others => '0');
signal g_32 : std_logic;
signal l_32 : std_logic;
signal e_32 : std_logic;
BEGIN
uut: comp32 PORT MAP (
a_32 => a_32,
b_32 => b_32,
g_32 => g_32,
l_32 => l_32,
e_32 => e_32
);
stim_proc: process
begin
a_32 <="00000000000000000000000000000000";b_32<="00000000000000000000000000000000";wait for 1500 ns;
a_32 <="00000000000000000000000000000001";b_32<="00000000000000000000000000000000";wait for 1500 ns;
a_32 <="00000000000000000000000000000000";b_32<="10000000000000000000000000000000";wait for 1500 ns;
wait;
end process;
END;
You had your chained signals backward, and the first inputs want to show equal:
architecture comp32_arch of comp32 is
component comp1
port (a,b,g,l,e : in std_logic ;
great,less,equal : out std_logic);
end component comp1;
signal gre : std_logic_vector(BW downto 0);
signal les : std_logic_vector(BW downto 0);
signal equ : std_logic_vector(BW downto 0);
begin
gre(BW) <= '0'; -- gre(0) <= '0';
les(BW) <= '0'; -- les(0) <= '0';
equ(BW) <= '1'; -- equ(0) <= '0';
gen:
for i in 0 to BW-1 generate
biti:
comp1
port map (
a => a_32(i),
b => b_32(i),
g => gre(i+1), -- gre(i),
l => les(i+1), -- les(i),
e => equ(i+1), -- equ(i),
great => gre(i), -- gre(i+1),
less => les(i), -- les(i+1),
equal => equ(i) -- equ(i+1)
);
end generate;
g_32 <= gre(0); -- gre(BW);-- (BW-1);
l_32 <= les(0); -- les(BW); -- (BW-1);
e_32 <= equ(0); -- equ(BW); -- (BW-1);
end architecture comp32_arch;
And that gives:
The most significant bit without an equals defines either less than or greater than. If they're all equal that propagates all the way through.

Resources