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