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