Multiplication unit skips overflow bit during addition - vhdl

I made a simple multiplication unit (16-bit operands, 32-bit result) based on the "shift-left, add" principle, and it does not work properly in the adder part when the overflow bit needs to be considered.
I have an idea what should be done (make a 17-bit sum vector and add an overflow bit to the product), but I don't know how to implement it. Below you can find the waveform file where I am showing the error location and the MPU.vhd file. The screenshot does not show the final result, but it is obvious that it will be wrong. How can I get it to work with large 16-bit numbers?
MPU.vhd
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all;
entity MPU_OP is
port (C: in std_logic; -- Clock
RST : in std_logic; -- Reset
LAB : in std_logic; -- Load A and B, P <= 0
SHIFT : in std_logic; -- Shift B and P
OUTHL : in std_logic; -- Output most(0) or least(1) significant word P
DA : in std_logic_vector(15 downto 0); -- Data A
DB : in std_logic_vector(15 downto 0); -- Data B
DP : out std_logic_vector(15 downto 0)); -- Word result P
end entity;
architecture BEH of MPU_OP is
signal A, B : std_logic_vector(15 downto 0); -- A, B
signal Pi, Ai, Si : integer;
signal S : signed(15 downto 0); -- Sum
signal S2 : signed(16 downto 0);
signal P : signed(31 downto 0); -- Product
begin
RG_A : process(C, RST) -- Register for A
begin
if (RST = '1') then
A <= X"0000";
elsif rising_edge(C) then `-- Reg_A`
if LAB = '1' then
A <= DA;
end if;
end if;
end process;
RG_B : process(C, RST) -- Register for B
begin
if (RST = '1') then
B <= X"0000";
elsif rising_edge(C) then
if LAB = '1' then
B <= DB;
elsif (SHIFT = '1') then
B <= std_logic_vector(shift_left(unsigned(B), 1)); `-- Reg_B`
end if;
end if;
end process;
Adder : process (C)
begin
Pi <= to_integer(unsigned(std_logic_vector(P(15 downto 0))));
Ai <= to_integer(unsigned(A));
if B(15) = '1' then
S <= P(15 downto 0) + signed(A); -- Adder
Si <= Pi + Ai;
else
S <= P(15 downto 0);
Si <= Pi;
S2 <= to_signed(Si, S2'length);
end if;
end process;
RG_P : process (C, RST, P) -- Register for P
begin
if RST = '1' then
P <= X"00000000";
elsif rising_edge(C) then
if LAB = '1' then
P <= X"00000000";
elsif SHIFT = '1' then
if B /= "1000000000000000" then
P <= P(30 downto 16) & S & '0'; -- Shift LEFT `-- Reg_Product`
else
P <= P(31 downto 16) & S;
end if;
end if;
end if;
end process;
MUX_P : DP <= std_logic_vector(P(15 downto 0)) when OUTHL = '1' else
std_logic_vector(P(31 downto 16));
end architecture;
Below is the minimal code to reproduce the above problem and the testbench for it.
MPU.vhd
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all;
entity MPU_TEST is
port (C: in std_logic;
LAB : in std_logic;
SHIFT : in std_logic;
DA : in std_logic_vector(15 downto 0);
DB : in std_logic_vector(15 downto 0);
DP : out std_logic_vector(31 downto 0));
end entity;
architecture BEH of MPU_TEST is
signal A, B : std_logic_vector(15 downto 0);
signal S : signed(15 downto 0);
signal P : signed(31 downto 0);
begin
RG_A : process(C)
begin
if rising_edge(C) then
if LAB = '1' then
A <= DA;
end if;
end if;
end process;
RG_B : process(C)
begin
if rising_edge(C) then
if LAB = '1' then
B <= DB;
elsif (SHIFT = '1') then
B <= std_logic_vector(shift_left(unsigned(B), 1));
end if;
end if;
end process;
Adder : process (C)
begin
if B(15) = '1' then
S <= P(15 downto 0) + signed(A);
else
S <= P(15 downto 0);
end if;
end process;
RG_P : process (C, P)
begin
if rising_edge(C) then
if LAB = '1' then
P <= X"00000000";
elsif SHIFT = '1' then
if B /= "1000000000000000" then
P <= P(30 downto 16) & S & '0';
else
P <= P(31 downto 16) & S;
end if;
end if;
end if;
end process;
DP <= std_logic_vector(P);
end architecture;
MPU_TB.vhd
library ieee;
use ieee.NUMERIC_STD.all;
use ieee.std_logic_1164.all;
entity mpu_test_tb is
end mpu_test_tb;
architecture TB_ARCHITECTURE of mpu_test_tb is
component mpu_test
port(
C : in STD_LOGIC;
LAB : in STD_LOGIC;
SHIFT : in STD_LOGIC;
DA : in STD_LOGIC_VECTOR(15 downto 0);
DB : in STD_LOGIC_VECTOR(15 downto 0);
DP : out STD_LOGIC_VECTOR(31 downto 0) );
end component;
signal C : STD_LOGIC;
signal LAB : STD_LOGIC;
signal SHIFT : STD_LOGIC;
signal DA : STD_LOGIC_VECTOR(15 downto 0);
signal DB : STD_LOGIC_VECTOR(15 downto 0);
signal DP : STD_LOGIC_VECTOR(31 downto 0);
begin
UUT : mpu_test
port map (
C => C,
LAB => LAB,
SHIFT => SHIFT,
DA => DA,
DB => DB,
DP => DP
);
process
begin
C <= '0';
wait for 5 ns;
C <= '1';
wait for 5 ns;
end process;
LAB <= '1', '0' after 10 ns;
SHIFT <= '0', '1' after 10 ns, '0' after 170 ns;
DA <= X"1234";
DB <= X"F234";
end TB_ARCHITECTURE;
And a new signal with an incorrect multiplication result. The error occurs in adder.

I managed to get it to work. I explicitly added "0" when shifting the product and added a 17th bit to S to keep the overflow bit. Also, the signal ranges have been changed, which should be stored in the product and sum. Ended up with the code below.
MPU.vhd
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all;
entity MPU_TEST is
port (C: in std_logic;
LAB : in std_logic;
SHIFT : in std_logic;
DA : in std_logic_vector(15 downto 0);
DB : in std_logic_vector(15 downto 0);
DP : out std_logic_vector(31 downto 0));
end entity;
architecture BEH of MPU_TEST is
signal A, B : std_logic_vector(15 downto 0);
signal S : signed(16 downto 0);
signal P : signed(31 downto 0);
begin
RG_A : process(C)
begin
if rising_edge(C) then
if LAB = '1' then
A <= DA;
end if;
end if;
end process;
RG_B : process(C)
begin
if rising_edge(C) then
if LAB = '1' then
B <= DB;
elsif (SHIFT = '1') then
B <= std_logic_vector(shift_left(unsigned(B), 1));
end if;
end if;
end process;
Adder : process (C)
begin
if B(15) = '1' then
S <= P(16 downto 0) + signed(A);
else
S <= P(16 downto 0);
end if;
end process;
RG_P : process (C, P)
begin
if rising_edge(C) then
if LAB = '1' then
P <= X"00000000";
elsif SHIFT = '1' then
if B /= "1000000000000000" then
P <= P(30 downto 17) & S & '0';
else
P <= P(31 downto 17) & S;
end if;
end if;
end if;
end process;
DP <= std_logic_vector(P);
end architecture;
Simulation screenshots of the correct waveforms

Related

register Design in vhdl with modelsim

I'm trying to write register vhdl code in modelSim,My code is here:
Library ieee;
use ieee.std_logic_1164.all;
------------------------------
entity reg_8Bit is
Generic(N:integer := 8);
port(clk,reset:in std_logic;
ctrl:in std_logic_vector(1 downto 0);
d:in std_logic_vector(n-1 downto 0);
q:out std_logic_vector(n-1 downto 0);
d2:out std_logic
);
end reg_8Bit;
-------------------------------
Architecture arch_8bit of reg_8Bit is
signal r_reg,r_next:std_logic_vector(n-1 downto 0);
begin
process(clk,reset)
begin
if(reset = '1') then
q <= (others => '0');
elsif(clk='1' and clk 'event) then
r_reg <= r_next;
end if;
end process;
with ctrl select
r_next <= r_reg when "00",
r_reg(n-2 downto 0) & d(i) when "10",
d(7) & r_reg(n-1 downto 1) when "01",
d when others;
q <= r_reg;
end arch_8bit;
I Want to create shift to right when ctrl = "01" and shift to left when
ctrl = "10" But I get just d(0) or d(7),How I can fixed it?
Problems with your code:
Signal q is multiple driven.
Your are resetting q but not r_reg
Improved code:
library ieee;
use ieee.std_logic_1164.all;
------------------------------
entity reg_8Bit is
generic(
N:integer := 8
);
port(
clk : in std_logic;
reset : in std_logic;
ctrl : in std_logic_vector(1 downto 0);
d : in std_logic_vector(n-1 downto 0);
q : out std_logic_vector(n-1 downto 0);
d2 : out std_logic
);
end entity;
-------------------------------
architecture arch_8bit of reg_8Bit is
signal r_reg : std_logic_vector(n-1 downto 0) := (others => '0');
begin
process(clk,reset)
begin
if(reset = '1') then
r_reg <= (others => '0');
elsif rising_edge(clk) then
if ctrl = "11" then
r_reg <= d;
elsif ctrl = "10" then
r_reg <= r_reg(r_reg'high - 1 downto r_reg'low) & d(0);
elsif ctrl = "01" then
r_reg <= d(7) & r_reg(r_reg'high downto r_reg'low + 1);
end if;
end if;
end process;
q <= r_reg;
end arch_8bit;
Other hints:
Don't use asynchronous resets.
Use rising_edge(clk) instead of clk'event ....
You can avoid the additional signal r_reg if you enabled VHDL-2008 in your tool.
In VHDL-2008, you can read back values from out ports.

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;

My VHDL ALU code behave awkward

I have a problem with VHDL ALU code. I have to make simple ALU with 4 operations with 4-bit operands. I implemented these operations correctly and they work well. For executing I use E2LP board. For choosing the operation I selected 4 JOY buttons,one for each operation. Problem is that when I press button to execute operation and depress it I want result to stay on LEDs while I don't select any other operation, but that's not happening. For first 5 LEDs this works fine, but upper 3 not.This only works for one operation. My simulation results are correct. Here is code an schema of project.Thank you in advance.
---------------------------------------------------------------------------------- Control logic
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
Port ( --clk : in STD_LOGIC;
in_saberi : in STD_LOGIC;
in_mnozi : in STD_LOGIC;
in_ili : in STD_LOGIC;
in_rotiraj : in STD_LOGIC;
out_saberi : out STD_LOGIC;
out_mnozi : out STD_LOGIC;
out_ili : out STD_LOGIC;
out_rotiraj : out STD_LOGIC);
end upravljanje;
architecture Behavioral of upravljanje is
signal tmps : std_logic := '1';
signal tmpm : std_logic := '1';
signal tmpi : std_logic := '1';
signal tmpr : std_logic := '1';
begin
logika : process(in_saberi,in_mnozi,in_ili,in_rotiraj)
begin
if (in_saberi='0' and in_mnozi='1' and in_ili='1' and in_rotiraj='1') then
tmps <= in_saberi;
tmpm <= in_mnozi;
tmpi <= in_ili;
tmpr <= in_rotiraj;
elsif (in_mnozi='0' and in_saberi='1' and in_ili='1' and in_rotiraj='1') then
tmps <= in_saberi;
tmpm <= in_mnozi;
tmpi <= in_ili;
tmpr <= in_rotiraj;
elsif (in_saberi='1' and in_mnozi='1' and in_ili='0' and in_rotiraj='1') then
tmps <= in_saberi;
tmpm <= in_mnozi;
tmpi <= in_ili;
tmpr <= in_rotiraj;
elsif (in_saberi='1' and in_mnozi='1' and in_ili='1' and in_rotiraj='0') then
tmps <= in_saberi;
tmpm <= in_mnozi;
tmpi <= in_ili;
tmpr <= in_rotiraj;
elsif (in_saberi='1' and in_mnozi='1' and in_ili='1' and in_rotiraj='1') then
tmps <= tmps;
tmpm <= tmpm;
tmpi <= tmpi;
tmpr <= tmpr;
else
tmps <= '1';
tmpm <= '1';
tmpi <= '1';
tmpr <= '1';
end if;
end process logika;
out_saberi <= tmps;
out_mnozi <= tmpm;
out_ili <= tmpi;
out_rotiraj <= tmpr;
end Behavioral;
--------------------------------------------------------------------------
-- this is for operation add
entity sabirac is
Port ( clk : in STD_LOGIC;
data1 : in STD_LOGIC_VECTOR (3 downto 0);
data2 : in STD_LOGIC_VECTOR (3 downto 0);
saberi : in STD_LOGIC;
result : out STD_LOGIC_VECTOR (7 downto 0));
end sabirac;
architecture Behavioral of sabirac is
signal c : std_logic_vector (5 downto 0) := "000000";
signal tmp : std_logic_vector (7 downto 0) := "00000000";
begin
sabiranje : process(clk,saberi)
begin
if (saberi='0') then
tmp(0) <= data1(0) xor data2(0);
c(0) <= data1(0) and data2(0);
tmp(1) <= data1(1) xor data2(1) xor c(0);
c(1) <= (data1(1) and data2(1)) or (data1(1) and c(0)) or (data2(1) and c(0));
tmp(2) <= data1(2) xor data2(2) xor c(1);
c(2) <= (data1(2) and data2(2)) or (data1(2) and c(1)) or (data2(2) and c(1));
tmp(3) <= data1(3) xor data2(3) xor c(2);
if(data1(3) = data2(3)) then
c(3) <= (data1(3) and data2(3)) or (data1(3) and c(2)) or (data2(3) and c(2));
tmp(4) <= c(3);
tmp(5) <= c(3);
tmp(6) <= c(3);
tmp(7) <= c(3);
else
c(3) <= data1(3) xor data2(3) xor c(2);
tmp(4) <= c(3);
tmp(5) <= c(3);
tmp(6) <= c(3);
tmp(7) <= c(3);
end if;
else
tmp <= "ZZZZZZZZ";
end if;
end process sabiranje;
result <= tmp;
end Behavioral;
-----------------------------------------------------------------------------
entity mul is
Port (
clk : in STD_LOGIC;
pomnozi : in STD_LOGIC;
data1 : in STD_LOGIC_VECTOR (3 downto 0);
data2 : in STD_LOGIC_VECTOR (3 downto 0);
result : out STD_LOGIC_VECTOR (7 downto 0));
end mul;
architecture Behavioral of mul is
begin
mnozenje : process (clk,pomnozi)
begin
if (pomnozi='0') then
result <= std_logic_vector(signed(data1) * signed(data2));
else
result <= "ZZZZZZZZ";
end if;
end process mnozenje;
end Behavioral;
--------------------------------------------------------------------------
entity rotate is
Port ( clk : in STD_LOGIC;
rotiraj : in STD_LOGIC;
data1 : in STD_LOGIC_VECTOR (3 downto 0);
data2 : in STD_LOGIC_VECTOR (3 downto 0);
result : out STD_LOGIC_VECTOR (7 downto 0));
end rotate;
architecture Behavioral of rotate is
signal tmp : std_logic_vector (3 downto 0) := "0000";
signal tmp2 : std_logic_vector (7 downto 0) := "00000000";
begin
rotacija : process(clk,rotiraj)
begin
if (rotiraj='0') then
tmp <= std_logic_vector(rotate_left(unsigned(data1),to_integer(unsigned(data2))));
tmp2(0) <= tmp(0);
tmp2(1) <= tmp(1);
tmp2(2) <= tmp(2);
tmp2(3) <= tmp(3);
tmp2(4) <= '0';
tmp2(5) <= '0';
tmp2(6) <= '0';
tmp2(7) <= '0';
else
tmp2 <= "ZZZZZZZZ";
end if;
end process rotacija;
result <= tmp2;
end Behavioral;
--------------------------------------------------------------------------
-- Logic OR operation
entity logicko_ILI is
Port ( clk : in STD_LOGIC;
data1 : in STD_LOGIC_VECTOR (3 downto 0);
data2 : in STD_LOGIC_VECTOR (3 downto 0);
logili : in STD_LOGIC;
result : out STD_LOGIC_VECTOR (7 downto 0));
end logicko_ILI;
architecture Behavioral of logicko_ILI is
signal c : std_logic_vector (5 downto 0) := "000000";
signal tmp : std_logic_vector (7 downto 0) := "00000000";
begin
logicko : process(clk,logili)
begin
if (logili = '0') then
tmp(0) <= data1(0) or data2(0);
tmp(1) <= data1(1) or data2(1);
tmp(2) <= data1(2) or data2(2);
tmp(3) <= data1(3) or data2(3);
tmp(4) <= '0';
tmp(5) <= '1';
tmp(6) <= '1';
tmp(7) <= '1';
else
tmp <= "ZZZZZZZZ";
end if;
end process logicko;
result <= tmp;
end Behavioral;
I think you should even use your clk and reset signals in process. Your design is completely asynchron! This is a very bad idea.
A synchron process with asynchron reset look like this:
test : process (clk,reset)
begin
if (reset) then
c = 0;
elsif (rising_edge(clk)) then
c = a + b;
end if;
end process:
None of your sensitivity lists are correct. This does not comply with IEEE standard on syntesizable RTL. It poses a a high risk of getting synthesis results that are different from your simulation results.
line: 24 Incomplete sensitivity list. Missing signals: tmpm, tmps, tmpr, tmpi
line: 86 Incomplete sensitivity list. Missing signals: data1, data2, c
line: 137 Incomplete sensitivity list. Missing signals: data1, data2
line: 166 Incomplete sensitivity list. Missing signals: tmp, data1, data2
line: 205 Incomplete sensitivity list. Missing signals: data1, data2,
(line numbers might be slightly off because I had to add use/library clauses for ieee.std_logic_1164)
Please check your synthesis results for warnings, or use a VHDL code checker before your synthesize.

How to implement clock divider to universal shift register

I'm trying to make a VHDL code for 4-bit universal shift register, where I want to load 4 bits and choose the shift-operation from the ctrl. I don't know how to implement a clock divider to run the outputs on a FPGA.
Here is my code so far:
library IEEE;
use IEEE.STD_LOGIC_1164.all;
entity shift_register is
generic(N : integer := 4);
port(
clk, reset : in std_logic;
ctrl : in std_logic_vector(1 downto 0);
d : in std_logic_vector((N-1) downto 0);
q : out std_logic_vector((N-1) downto 0)
);
end shift_register;
architecture Behavioral of shift_register is
signal r_reg : std_logic_vector((N-1) downto 0);
signal r_next : std_logic_vector((N-1) downto 0);
begin
process(clk, reset)
begin
if(reset = '1') then
r_reg <= (others => '0');
elsif(clk'event and clk = '1') then
r_reg <= r_next;
end if;
end process;
with ctrl select
r_next <=
r_reg when "00", --do nothing
r_reg(N-2 downto 0) & d(0) when "01", --shift left
d(N-1) & r_reg(N-1 downto 1)when "10", --shift right
d when others; --load
q <= r_reg;
end Behavioral;
Divider code template with enable asserted a single cycle every RATIO clock cycles:
library ieee;
use ieee.numeric_std.all;
architecture syn of mdl is
constant RATIO : natural := 10;
signal prescale : std_logic_vector(9 downto 0); -- Scale to fit RATIO - 1
signal enable : std_logic;
begin
process (clk, reset) is
begin
if reset = '1' then
enable <= '0';
prescale <= std_logic_vector(to_unsigned(RATIO - 1, prescale'length));
elsif rising_edge(clk) then
if unsigned(prescale) = 0 then
enable <= '1';
prescale <= std_logic_vector(to_unsigned(RATIO - 1, prescale'length));
else
enable <= '0';
prescale <= std_logic_vector(unsigned(prescale) - 1);
end if;
end if;
end process;
end architecture;

Why does VHDL shift register need 2 clock rising_edge to shift?

I'm trying to make a 8-bit shift register using D flipflop.
The problem is that when simulating it takes two clock rising edges for the register to shift, one for the D input to change, the other for the Q to change. I don't know why.
entity Registry_8 is
port (input : in std_logic;
output : out std_logic;
clk : in std_logic;
clear : in std_logic;
load : in std_logic;
LR : in std_logic;
pIn : in std_logic_vector (7 downto 0);
pOut : out std_logic_vector (7 downto 0);
shift : in std_logic);
end Registry_8;
architecture Behavioral of Registry_8 is
component D_flipflop
port(D, clk, clear, preset : in std_logic;
Q, Q_b : out std_logic);
end component;
signal D, Q : std_logic_vector (7 downto 0);
begin
GEN_FLIP :
for i in 0 to 7 generate
D_i : D_flipflop port map(clk => clk, preset => '0', clear => clear, D => D(i), Q => Q(i));
end generate GEN_FLIP;
process (clk, load, LR, shift)
begin
if (load = '1')
then D <= pIn;
end if;
if (clk'event and clk = '1' and shift = '1')
then
if (LR = '0')
then D(7 downto 0) <= Q(6 downto 0) & input;
output <= Q(7);
else
D(7 downto 0) <= input & Q(7 downto 1);
output <= Q(0);
end if;
end if;
end process;
pOut <= Q;
end Behavioral;
In the process, there is clock edge sensitive condition with the expression:
clk'event and clk = '1'
The process thereby implements an additional level of sequential logic (flip
flops), but you probably wanted to create a process for purely combinatorial
design, like:
process (all) is
begin
if (load = '1') then
D <= pIn;
end if;
if shift = '1' then
if (LR = '0') then
D(7 downto 0) <= Q(6 downto 0) & input;
output <= Q(7);
else
D(7 downto 0) <= input & Q(7 downto 1);
output <= Q(0);
end if;
end if;
end process;
Note that VHDL-2008 all is used as sensitivity list above, to automatically
include all signals used in a process for combinatorial design.

Resources