added pipe 2 reg, testbench, top_level_entity, ...
[calu.git] / cpu / src / exec_op / add_op_b.vhd
1 library IEEE;
2 use IEEE.std_logic_1164.all;
3 use IEEE.numeric_std.all;
4
5 use work.common_pkg.all;
6 use work.alu_pkg.all;
7
8 architecture add_op of exec_op is
9
10 signal sub, addc : std_logic;
11
12 begin
13
14 sub <= op_detail(SUB_OPT);
15 addc <= op_detail(CARRY_OPT);
16
17 calc: process(left_operand, right_operand, alu_state, sub, addc)
18         variable alu_result_v : alu_result_rec;
19         variable complement             : gp_register_t;
20         variable carry_res              : unsigned(gp_register_t'length downto 0);
21         variable tmp_right_operand : unsigned(gp_register_t'length downto 0);
22         variable oflo1, oflo2, l_neg, r_neg : std_logic;
23         variable addcarry               : unsigned(carry_res'range);
24 begin
25                 alu_result_v := alu_state;
26                 
27                 addcarry := (others =>'0');
28                 addcarry(0) := alu_state.status.carry and addc;
29                 
30                 complement := inc(not(right_operand));
31                 l_neg := left_operand(gp_register_t'high);
32                 
33                 carry_res := unsigned('0' & left_operand)+addcarry;
34                 oflo1 := add_oflo(l_neg,'0',std_logic_vector(carry_res)(gp_register_t'high));
35                 
36                 if sub = '1' then
37                         tmp_right_operand := unsigned('0' & complement);
38                 else
39                         tmp_right_operand := unsigned('0' & right_operand);
40                 end if;
41                 
42                 l_neg := std_logic_vector(carry_res)(gp_register_t'high);
43                 r_neg := std_logic_vector(tmp_right_operand)(gp_register_t'high);
44                 
45                 carry_res := carry_res + tmp_right_operand;
46                 oflo2 := add_oflo(l_neg,r_neg,std_logic_vector(carry_res)(gp_register_t'high));
47                 
48
49                 alu_result_v.result := std_logic_vector(carry_res)(gp_register_t'range);
50                 alu_result_v.status.carry := std_logic_vector(carry_res)(carry_res'high);
51                 
52                 
53                 alu_result_v.status.carry := oflo1 or oflo2;
54                 
55                 --sign will be set globally.
56                 --zero will be set globally.
57                 
58                 alu_result <= alu_result_v;
59 end process; 
60
61 end architecture add_op;