Ok. Another one example. If I make my adder synchronus. Will be my code suitable for real application?
LIBRARY IEEE;
USE IEEE.std_logic_1164.ALL;
USE IEEE.numeric_std.ALL;
ENTITY full_adder_Nbit IS
GENERIC (
N : POSITIVE := 4
);
PORT (
clk : IN STD_LOGIC := '0';
ci : IN STD_LOGIC := '0';
a : IN UNSIGNED (N-1 DOWNTO 0) := X"0";
b : IN UNSIGNED (N-1 DOWNTO 0) := X"0";
s : OUT UNSIGNED (N-1 DOWNTO 0) := X"0";
co : OUT STD_LOGIC := '0'
);
END full_adder_Nbit;
ARCHITECTURE b OF full_adder_Nbit IS
SIGNAL
reg_a,
reg_b,
out_s : UNSIGNED (N-1 DOWNTO 0);
SIGNAL
reg_ci,
out_co : STD_LOGIC;
BEGIN
p0 : PROCESS (clk)
BEGIN
IF rising_edge(clk) THEN
reg_a <= a;
reg_b <= b;
reg_ci <= ci;
END IF;
END PROCESS p0;
p1 : PROCESS(reg_ci, reg_a, reg_b)
VARIABLE
result_v : UNSIGNED (N DOWNTO 0);
BEGIN
result_v := ('0' & reg_a) + ('0' & reg_b) + ('0' & reg_ci);
out_co <= result_v(N);
out_s <= result_v(N-1 DOWNTO 0);
END PROCESS p1;
p2 : PROCESS (clk)
BEGIN
IF falling_edge(clk) THEN
co <= out_co;
s <= out_s;
END IF;
ENd PROCESS p2;
END b;
I am very unsure does it really need to store output value in register and at the falling edge. I can drive it directly but what i get?! I'm also unsure about storing input values in registry/ Perhaps I need only do addtion when clock arrive. So as result I can write down FOUR different solutions:
1) no register at input and output, do result when clock transition from 0 to 1 arrive.
2) register at inputs and no register at output.
3) no register at input but at the output.
4) inputs and outputs have register. (as shown in code above).
question 1. What will be the best solution, how it depends on application?
question 2. Do I make transition to synchronus right?