3 use IEEE.std_logic_1164.all;
\r
4 use IEEE.numeric_std.all;
\r
6 use work.common_pkg.all;
\r
7 --use work.core_extension.all;
\r
12 type status_rec is record
\r
19 subtype status_t is byte_t;
\r
20 type alu_interal_rec is record
\r
22 end record alu_internal_rec;
\r
24 type alu_result_rec is record
\r
25 result : gp_register_t;
\r
26 result_addr : gp_addr_t;
\r
28 status : status_rec;
\r
29 stackpointer : gp_register_t;
\r
31 alu_jmp : std_logic;
\r
32 brpr_bit : std_logic;
\r
37 byte_op : std_logic;
\r
38 sign_xt : std_logic;
\r
40 end record alu_result_rec;
\r
42 constant SHIFT_WIDTH : integer := log2c(gp_register_t'length);
\r
44 function add_oflo(l_neg, r_neg, res_neg : std_logic) return std_logic;
\r
45 function addsub_op(left_operand, right_operand : gp_register_t; sub : std_logic; alu_result : alu_result_rec) return alu_result_rec;
\r
47 function and_op(left_operand, right_operand : gp_register_t; alu_result : alu_result_rec) return alu_result_rec;
\r
48 function or_op(left_operand, right_operand : gp_register_t; alu_result : alu_result_rec) return alu_result_rec;
\r
49 function xor_op(left_operand, right_operand : gp_register_t; alu_result : alu_result_rec) return alu_result_rec;
\r
51 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
54 end package alu_pkg;
\r
56 package body alu_pkg is
\r
58 function add_oflo(l_neg, r_neg , res_neg: std_logic) return std_logic is
\r
60 return (l_neg AND r_neg AND not(res_neg)) OR
\r
61 (not(l_neg) AND not(r_neg) AND res_neg);
\r
62 end function add_oflo;
\r
64 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
65 variable alu_result_out : alu_result_rec;
\r
66 variable complement : gp_register_t;
\r
67 variable carry_res : unsigned(gp_register_t'length downto 0);
\r
68 variable tmp_right_operand : unsigned(gp_register_t'length downto 0);
\r
69 variable oflo1, oflo2, l_neg, r_neg : std_logic;
\r
70 variable addcarry : unsigned(carry_res'range);
\r
72 alu_result_out := alu_result;
\r
74 addcarry := (others =>'0');
\r
75 addcarry(0) := unsigned(alu_result.status.carry and addc);
\r
77 complement := inc(not(right_operand));
\r
78 l_neg := left_operand(gp_register_t'high);
\r
80 carry_res := unsigned('0' & left_operand)+addcarry;
\r
81 oflo1 := add_oflo(l_neg,'0',std_logic_vector(carry_res)(gp_register_t'high));
\r
84 tmp_right_operand := unsigned('0' & complement);
\r
86 tmp_right_operand := unsigned('0' & right_operand);
\r
89 l_neg := std_logic_vector(carry_res)(gp_register_t'high);
\r
90 r_neg := std_logic_vector(tmp_right_operand)(gp_register_t'high);
\r
92 carry_res := carry_res + tmp_right_operand;
\r
93 oflo2 := add_oflo(l_neg,r_neg,std_logic_vector(carry_res)(gp_register_t'high));
\r
96 alu_result_out.result := std_logic_vector(carry_res)(gp_register_t'range);
\r
97 alu_result_out.status.carry := std_logic_vector(carry_res)(carry_res'high);
\r
100 alu_result_out.status.carry := oflo1 or oflo2;
\r
102 --sign will be set globally.
\r
103 --zero will be set globally.
\r
105 return alu_result_out;
\r
106 end function addsub_op;
\r
108 function and_op(left_operand, right_operand : gp_register_t; alu_result : alu_result_rec) return alu_result_rec is
\r
109 variable alu_result_out : alu_result_rec;
\r
111 alu_result_out := alu_result;
\r
112 alu_result_out.result := left_operand and right_operand;
\r
113 end function and_op;
\r
115 function or_op(left_operand, right_operand : gp_register_t; alu_result : alu_result_rec) return alu_result_rec is
\r
116 variable alu_result_out : alu_result_rec;
\r
118 alu_result_out := alu_result;
\r
119 alu_result_out.result := left_operand or right_operand;
\r
120 end function or_op;
\r
122 function xor_op(left_operand, right_operand : gp_register_t; alu_result : alu_result_rec) return alu_result_rec is
\r
123 variable alu_result_out : alu_result_rec;
\r
125 alu_result_out := alu_result;
\r
126 alu_result_out.result := left_operand xor right_operand;
\r
127 end function xor_op;
\r
129 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
130 variable alu_result_out : alu_result_rec;
\r
131 variable tmp_shift : bit_vector(gp_register_t'length+1 downto 0);
\r
132 variable tmp_sb : std_logic;
\r
134 alu_result_out := alu_result;
\r
137 tmp_sb := (carry and alu_result.status.carry and not(arith)) or (arith and left_operand(gp_register_t'high));
\r
138 tmp_shift := bit_vector(tmp_sb & left_operand & alu_result.status.carry);
\r
139 tmp_shift := tmp_shift sra to_integer(unsigned(right_operand)(SHIFT_WIDTH-1 downto 0));
\r
141 alu_result_out.status.carry := std_logic_vector(tmp_shift)(0);
\r
143 tmp_sb := (carry and alu_result.status.carry and not(arith));
\r
144 tmp_shift := bit_vector(alu_result.status.carry & left_operand & tmp_sb);
\r
145 tmp_shift := tmp_shift sla to_integer(unsigned(right_operand)(SHIFT_WIDTH-1 downto 0));
\r
147 alu_result_out.status.carry := std_logic_vector(tmp_shift)(tmp_shift'high);
\r
150 alu_result_out.result := std_logic_vector(tmp_shift)(gp_register_t'length downto 1);
\r
152 end function shift_op;
\r
154 end package body alu_pkg;
\r