exec impl.
[calu.git] / cpu / src / alu_pkg.vhd
1 library IEEE;\r
2 \r
3 use IEEE.std_logic_1164.all;\r
4 use IEEE.numeric_std.all;\r
5 \r
6 use work.common_pkg.all;\r
7 --use work.core_extension.all;\r
8 \r
9 \r
10 package alu_pkg is\r
11         \r
12         type status_rec is record\r
13                 zero : std_logic;\r
14                 oflo : std_logic;\r
15                 sign : std_logic;\r
16                 carry : std_logic;\r
17         end record;\r
18         \r
19         subtype status_t is byte_t;\r
20         --type alu_interal_rec is record\r
21         --      \r
22         --end record alu_internal_rec;\r
23         \r
24         type alu_result_rec is record\r
25                 result : gp_register_t;\r
26                 result_addr : gp_addr_t;\r
27                 \r
28                 status : status_rec;\r
29                 --stackpointer : gp_register_t;\r
30 \r
31                 alu_jmp : std_logic;\r
32                 brpr : std_logic;\r
33                 reg_op : std_logic;\r
34                 mem_op  : std_logic;\r
35                 \r
36                 --new_val : std_logic;\r
37                 mem_en : std_logic;\r
38                 \r
39                 hw_op   : std_logic;\r
40                 byte_op : std_logic;\r
41                 sign_xt : std_logic;\r
42                 \r
43         end record alu_result_rec;\r
44         \r
45         constant SHIFT_WIDTH : integer := 1;--log2c(gp_register_t'length);\r
46         \r
47         constant COND_ZERO : condition_t := "0001";\r
48         constant COND_NZERO : condition_t := "0000";\r
49         constant COND_NOFLO : condition_t := "0010";\r
50         constant COND_OFLO : condition_t := "0011";\r
51         constant COND_NCARRY : condition_t := "0100";\r
52         constant COND_CARRY : condition_t := "0101";\r
53         constant COND_NSIGN : condition_t := "0110";\r
54         constant COND_SIGN : condition_t := "0111";\r
55         \r
56         constant COND_ABOVE : condition_t := "1000";\r
57         constant COND_BEQ: condition_t := "1001";\r
58         constant COND_GEQ : condition_t := "1010";\r
59         constant COND_LT : condition_t := "1011";\r
60         constant COND_GT : condition_t := "1100";\r
61         \r
62         constant COND_LEQ : condition_t := "1101";\r
63         constant COND_ALWAYS : condition_t := "1110";\r
64         constant COND_NEVER : condition_t := "1111";\r
65         \r
66         function add_oflo(l_neg, r_neg, res_neg : std_logic) return std_logic;\r
67         -- function addsub_op(left_operand, right_operand : gp_register_t; sub, addc : std_logic; alu_result : alu_result_rec) return alu_result_rec;\r
68         \r
69         -- function and_op(left_operand, right_operand : gp_register_t; alu_result : alu_result_rec) return alu_result_rec;\r
70         -- function or_op(left_operand, right_operand : gp_register_t; alu_result : alu_result_rec) return alu_result_rec;\r
71         -- function xor_op(left_operand, right_operand : gp_register_t; alu_result : alu_result_rec) return alu_result_rec;\r
72         \r
73         -- function shift_op(left_operand, right_operand : gp_register_t; arith,sleft,carry : std_logic ;alu_result : alu_result_rec) return alu_result_rec;\r
74         
75         component alu is
76         --some modules won't need all inputs\r
77         port(\r
78         --System inputs\r
79         \r
80                         clk : in std_logic;\r
81                         reset : in std_logic;\r
82         --operation inputs\r
83                         condition : in condition_t;\r
84                         op_group : in op_info_t;\r
85                         left_operand : in gp_register_t;\r
86                         right_operand : in gp_register_t;\r
87                         op_detail : in op_opt_t;\r
88                         alu_state  : in alu_result_rec;\r
89                         alu_result : out alu_result_rec\r
90                 );
91         end component alu;\r
92         \r
93 end package alu_pkg;\r
94 \r
95 package body alu_pkg is\r
96 \r
97         function add_oflo(l_neg, r_neg , res_neg: std_logic) return std_logic is\r
98         begin\r
99                 return (l_neg AND r_neg AND not(res_neg)) OR \r
100                                 (not(l_neg) AND not(r_neg) AND res_neg);\r
101         end function add_oflo;\r
102         \r
103         -- function addsub_op(left_operand, right_operand : gp_register_t; sub, addc : std_logic; alu_result : alu_result_rec) return alu_result_rec is\r
104                 -- variable alu_result_out : alu_result_rec;\r
105                 -- variable complement          : gp_register_t;\r
106                 -- variable carry_res           : unsigned(gp_register_t'length downto 0);\r
107                 -- variable tmp_right_operand : unsigned(gp_register_t'length downto 0);\r
108                 -- variable oflo1, oflo2, l_neg, r_neg : std_logic;\r
109                 -- variable addcarry            : unsigned(carry_res'range);\r
110         -- begin\r
111                 -- alu_result_out := alu_result;\r
112                 \r
113                 -- addcarry := (others =>'0');\r
114                 -- addcarry(0) := unsigned(alu_result.status.carry and addc);\r
115                 \r
116                 -- complement := inc(not(right_operand));\r
117                 -- l_neg := left_operand(gp_register_t'high);\r
118                 \r
119                 -- carry_res := unsigned('0' & left_operand)+addcarry;\r
120                 -- oflo1 := add_oflo(l_neg,'0',std_logic_vector(carry_res)(gp_register_t'high));\r
121                 \r
122                 -- if sub = '1' then\r
123                         -- tmp_right_operand := unsigned('0' & complement);\r
124                 -- else\r
125                         -- tmp_right_operand := unsigned('0' & right_operand);\r
126                 -- end if;\r
127                 \r
128                 -- l_neg := std_logic_vector(carry_res)(gp_register_t'high);\r
129                 -- r_neg := std_logic_vector(tmp_right_operand)(gp_register_t'high);\r
130                 \r
131                 -- carry_res := carry_res + tmp_right_operand;\r
132                 -- oflo2 := add_oflo(l_neg,r_neg,std_logic_vector(carry_res)(gp_register_t'high));\r
133                 \r
134 \r
135                 -- alu_result_out.result := std_logic_vector(carry_res)(gp_register_t'range);\r
136                 -- alu_result_out.status.carry := std_logic_vector(carry_res)(carry_res'high);\r
137                 \r
138                 \r
139                 -- alu_result_out.status.carry := oflo1 or oflo2;\r
140                 \r
141                 -- --sign will be set globally.\r
142                 -- --zero will be set globally.\r
143                 \r
144                 -- return alu_result_out;\r
145         -- end function addsub_op;\r
146         \r
147         -- function and_op(left_operand, right_operand : gp_register_t; alu_result : alu_result_rec) return alu_result_rec is\r
148                 -- variable alu_result_out : alu_result_rec;\r
149         -- begin\r
150                 -- alu_result_out := alu_result;\r
151                 -- alu_result_out.result := left_operand and right_operand;\r
152         -- end function and_op;\r
153         \r
154         -- function or_op(left_operand, right_operand : gp_register_t; alu_result : alu_result_rec) return alu_result_rec is\r
155                 -- variable alu_result_out : alu_result_rec;\r
156         -- begin\r
157                 -- alu_result_out := alu_result;\r
158                 -- alu_result_out.result := left_operand or right_operand;\r
159         -- end function or_op;\r
160         \r
161         -- function xor_op(left_operand, right_operand : gp_register_t; alu_result : alu_result_rec) return alu_result_rec is\r
162                 -- variable alu_result_out : alu_result_rec;\r
163         -- begin\r
164                 -- alu_result_out := alu_result;\r
165                 -- alu_result_out.result := left_operand xor right_operand;\r
166         -- end function xor_op;\r
167         \r
168         -- function shift_op(left_operand, right_operand : gp_register_t; arith,rs,carry : std_logic ;alu_result : alu_result_rec) return alu_result_rec is\r
169                 -- variable alu_result_out : alu_result_rec;\r
170                 -- variable tmp_shift : bit_vector(gp_register_t'length+1 downto 0);\r
171                 -- variable tmp_sb : std_logic;\r
172         -- begin\r
173                 -- alu_result_out := alu_result;\r
174                 \r
175                 -- if rs = '1' then\r
176                         -- tmp_sb := (carry and alu_result.status.carry and not(arith)) or (arith and left_operand(gp_register_t'high));\r
177                         -- tmp_shift := bit_vector(tmp_sb & left_operand & alu_result.status.carry);\r
178                         -- tmp_shift := tmp_shift sra to_integer(unsigned(right_operand)(SHIFT_WIDTH-1 downto 0));\r
179                         \r
180                         -- alu_result_out.status.carry := std_logic_vector(tmp_shift)(0);\r
181                 -- else\r
182                         -- tmp_sb := (carry and alu_result.status.carry and not(arith));\r
183                         -- tmp_shift :=  bit_vector(alu_result.status.carry & left_operand & tmp_sb);\r
184                         -- tmp_shift :=  tmp_shift sla to_integer(unsigned(right_operand)(SHIFT_WIDTH-1 downto 0));\r
185                         \r
186                         -- alu_result_out.status.carry := std_logic_vector(tmp_shift)(tmp_shift'high);\r
187                 -- end if;\r
188                 \r
189                 -- alu_result_out.result := std_logic_vector(tmp_shift)(gp_register_t'length downto 1);\r
190                 \r
191         -- end function shift_op;\r
192 \r
193 end package body alu_pkg;\r