My code for logical-right shift is as follows:
ENTITY Ror32 IS
PORT(
a_in : IN STD_LOGIC_VECTOR(31 DOWNTO 0);
result : OUT STD_LOGIC_VECTOR(31 DOWNTO 0)
);
END Ror32;
ARCHITECTURE ror_inAction OF Ror32 IS begin
result(30 downto 0) <= a_in(31 downto 1);
result(31) <= '0';
end ror_inAction;
My code for left shift is as follows:
ENTITY rol32 IS
PORT(
a_in : IN STD_LOGIC_VECTOR(31 DOWNTO 0);
result : OUT STD_LOGIC_VECTOR(31 DOWNTO 0)
);
END rol32;
ARCHITECTURE rol_inAction OF rol32 IS begin
result(31 downto 1) <= a_in(30 downto 0);
result(0) <= '0';
end rol_inAction;
This is the circuit I wanted to program:
My program for the diagram above is as follows:
ENTITY ALU IS
PORT(
a : IN STD_LOGIC_VECTOR(31 DOWNTO 0);
b : IN STD_LOGIC_VECTOR(31 DOWNTO 0);
op : IN STD_LOGIC_VECTOR( 2 DOWNTO 0);
result : OUT STD_LOGIC_VECTOR(31 DOWNTO 0);
cout : OUT STD_LOGIC;
zero : OUT STD_LOGIC);
END ALU;
ARCHITECTURE description OF ALU IS
-- 2-to-1 MUX
COMPONENT mux2_1
PORT(
A,B : in STD_LOGIC_VECTOR(31 DOWNTO 0);
S: in STD_LOGIC;
Z: out STD_LOGIC_VECTOR(31 DOWNTO 0));
END COMPONENT;
-- NOT
COMPONENT not32
PORT(
x: IN STD_LOGIC_VECTOR(31 DOWNTO 0);
y: OUT STD_LOGIC_VECTOR(31 DOWNTO 0)
);
END COMPONENT;
-- AND
COMPONENT and32
PORT(
a : IN STD_LOGIC_VECTOR(31 DOWNTO 0);
b : IN STD_LOGIC_VECTOR(31 DOWNTO 0);
cout : OUT STD_LOGIC_VECTOR(31 DOWNTO 0)
);
END COMPONENT;
-- OR
COMPONENT or32
PORT(
a : IN STD_LOGIC_VECTOR(31 DOWNTO 0);
b : IN STD_LOGIC_VECTOR(31 DOWNTO 0);
cout : OUT STD_LOGIC_VECTOR(31 DOWNTO 0)
);
END COMPONENT;
-- ADDER
COMPONENT add32
PORT(
a_in : IN STD_LOGIC_VECTOR(31 DOWNTO 0);
b_in : IN STD_LOGIC_VECTOR(31 DOWNTO 0);
c_in: IN STD_LOGIC;
result : OUT STD_LOGIC_VECTOR(31 DOWNTO 0);
c_out : OUT STD_LOGIC
);
END COMPONENT;
-- LEFT-SHIFT
COMPONENT rol32
PORT(
a_in : IN STD_LOGIC_VECTOR(31 DOWNTO 0);
result : OUT STD_LOGIC_VECTOR(31 DOWNTO 0)
);
END COMPONENT;
-- RIGHT-SHIFT
COMPONENT Ror32
PORT(
a_in : IN STD_LOGIC_VECTOR(31 DOWNTO 0);
result : OUT STD_LOGIC_VECTOR(31 DOWNTO 0)
);
END COMPONENT;
-- 6-to-1 MUX
COMPONENT mux6to1
PORT(
A,B,C,D,E,F: in STD_logic_vector (31 downto 0);
S: in std_logic_vector(2 downto 0);
O: out std_logic_vector(31 downto 0)
);
END COMPONENT;
--Check result
COMPONENT zeroChecker
PORT(
Out_ALU: IN STD_LOGIC_VECTOR(31 downto 0);
Out_Zero: OUT STD_LOGIC
);
END COMPONENT;
--1-bit NOT-gate
COMPONENT notGate
PORT(
ain: in std_logic;
aout: out std_logic
);
END COMPONENT;
------- Intermediate Signals
--signals going to 2-to-1 mux
signal B_inv: STD_LOGIC_VECTOR(31 DOWNTO 0);
--signal coming out of 2-to-1 mux
signal B_res: STD_LOGIC_VECTOR(31 DOWNTO 0);
--signal coming out of AND
signal AND_result: STD_LOGIC_VECTOR(31 DOWNTO 0);
--signal coming out of OR
signal OR_result: STD_LOGIC_VECTOR(31 DOWNTO 0);
--signal coming out of ADD
signal ADD_result: STD_LOGIC_VECTOR(31 DOWNTO 0);
--signal coming out of SUB
--signal SUB_result: STD_LOGIC_VECTOR(31 DOWNTO 0);
--signal coming out of ROL
signal ROL_result: STD_LOGIC_VECTOR(31 DOWNTO 0);
--signal coming out of ROR
signal ROR_result: STD_LOGIC_VECTOR(31 DOWNTO 0);
--signal passing into OR gate
signal Zero_check: STD_LOGIC;
--signal to store the Result
signal Res_intermediate: STD_LOGIC_VECTOR(31 DOWNTO 0);
----Mapping signals and ports
BEGIN
MuxNo1: mux2_1 port map (A=>b, B=> B_inv, S=> op(2), Z=> B_res);
NotForB: not32 port map (x=> B, y=> B_inv);
And_Block: and32 port map (a=> A, b=> B_res, cout=> AND_result);
Or_Block: or32 port map (a=> A, b=> B_res, cout=> OR_result);
Add_Block: add32 port map (a_in=> A, b_in=> B_res, c_in=> op(2), result=> ADD_result, c_out=> cout);
Right_Block: Ror32 port map (a_in=> A, result=> ROR_result);
Left_Block: rol32 port map (a_in=> A, result=> ROL_result);
Final_Mux: mux6to1 port map (A=> AND_result, B=> OR_result, C=> ADD_result, D=> ADD_result, E=> Ror_result,
F=> rol_result, S=> op, O=> Res_intermediate);
Zero_OR: zeroChecker port map (Res_intermediate, Zero_check);
FinalNot: notGate port map (ain=> Zero_check, aout=> zero);
result <= Res_intermediate;
END description;
Strangely enough, the Carry-out signal changes as the value of B (the input that has no connection with the logical shift operations) changes.
When the value of B is low, Carry-out becomes active high:
Carry-out becomes active low when the value of B is higher:
The 32-bit adder is the only entity that explicity deals with Carry-Out:
ENTITY add32 IS
PORT(
a_in : IN STD_LOGIC_VECTOR(31 DOWNTO 0);
b_in : IN STD_LOGIC_VECTOR(31 DOWNTO 0);
c_in: IN STD_LOGIC;
result : OUT STD_LOGIC_VECTOR(31 DOWNTO 0);
c_out : OUT STD_LOGIC
);
END add32;
ARCHITECTURE add32_inAction OF add32 IS
component fulladd is
port(
a: IN STD_LOGIC;
b: IN STD_LOGIC;
cin: IN STD_LOGIC;
sum: OUT STD_LOGIC;
cout: OUT STD_LOGIC
);
end component;
-- signal wire:STD_LOGIC_VECTOR(30 DOWNTO 0);
signal wire: STD_LOGIC_VECTOR(32 DOWNTO 0);
begin
wire(0) <= c_in;
FA_f: for i in 0 to 31 generate
FA_i: fulladd PORT MAP
(a_in(i), b_in(i), wire(i), result(i), wire(i+1));
end generate FA_f;
c_out <= wire(32);
end add32_inAction;
I don't understand the cause of this behavior. Firstly, I don't understand how Carry-out is being influenced by my shift operations. In addition to that, I find it even more puzzling that changes in B are changing the state of the Carry-Out signal. I did not write the code for such a behavior to occur.
EDIT:
Thanks to the answer given by Dave Tweed, I now know that I connected the carry-out bit of the Adder/Subtractor unit with the carry-out bit of the ALU in my top-level file. I shall look into it more closely now.
EDIT 2:
As Dave Tweed pointed out, op(2)
is connected to Carrry-In and the Carry-Out of my adder is connected to the cout
of my ALU. So, when I select any operation where op(2)
is 1 (SUB, ROL and ROR), the carry-out, IF generated, will appear in my wave-forms window. This is because SUB (which generates the carry-out in most cases) is occurring in parallel (as are all the other operations) and it's carry-out is connected to the ALU's carry-out so it will appear in the wave-forms window.
cout
, you might want to look at how thatcout
port is driven in your top level ALU file. \$\endgroup\$