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