3 use IEEE.std_logic_1164.all;
4 use IEEE.numeric_std.all;
6 use work.common_pkg.all;
7 --use work.core_extension.all;
12 type status_rec is record
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);
23 subtype status_t is byte_t;
24 --type alu_interal_rec is record
26 --end record alu_internal_rec;
28 type alu_result_rec is record
29 result : gp_register_t;
30 result_addr : gp_addr_t;
45 end record alu_result_rec;
47 constant SHIFT_WIDTH : integer := 4; --log2c(gp_register_t'length);
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";
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";
64 constant COND_LEQ : condition_t := "1101";
65 constant COND_ALWAYS : condition_t := "1110";
66 constant COND_NEVER : condition_t := "1111";
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;
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;
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;
78 --some modules won't need all 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;
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
102 package body alu_pkg is
104 function add_oflo(l_neg, r_neg , res_neg: std_logic) return std_logic is
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;
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);
118 -- alu_result_out := alu_result;
120 -- addcarry := (others =>'0');
121 -- addcarry(0) := unsigned(alu_result.status.carry and addc);
123 -- complement := inc(not(right_operand));
124 -- l_neg := left_operand(gp_register_t'high);
126 -- carry_res := unsigned('0' & left_operand)+addcarry;
127 -- oflo1 := add_oflo(l_neg,'0',std_logic_vector(carry_res)(gp_register_t'high));
130 -- tmp_right_operand := unsigned('0' & complement);
132 -- tmp_right_operand := unsigned('0' & right_operand);
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);
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));
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);
146 -- alu_result_out.status.carry := oflo1 or oflo2;
148 -- --sign will be set globally.
149 -- --zero will be set globally.
151 -- return alu_result_out;
152 -- end function addsub_op;
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;
157 -- alu_result_out := alu_result;
158 -- alu_result_out.result := left_operand and right_operand;
159 -- end function and_op;
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;
164 -- alu_result_out := alu_result;
165 -- alu_result_out.result := left_operand or right_operand;
166 -- end function or_op;
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;
171 -- alu_result_out := alu_result;
172 -- alu_result_out.result := left_operand xor right_operand;
173 -- end function xor_op;
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;
180 -- alu_result_out := alu_result;
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));
187 -- alu_result_out.status.carry := std_logic_vector(tmp_shift)(0);
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));
193 -- alu_result_out.status.carry := std_logic_vector(tmp_shift)(tmp_shift'high);
196 -- alu_result_out.result := std_logic_vector(tmp_shift)(gp_register_t'length downto 1);
198 -- end function shift_op;
200 end package body alu_pkg;