1 -- `Deep Thought', a softcore CPU implemented on a FPGA
3 -- Copyright (C) 2010 Markus Hofstaetter <markus.manrow@gmx.at>
4 -- Copyright (C) 2010 Martin Perner <e0725782@student.tuwien.ac.at>
5 -- Copyright (C) 2010 Stefan Rebernig <stefan.rebernig@gmail.com>
6 -- Copyright (C) 2010 Manfred Schwarz <e0725898@student.tuwien.ac.at>
7 -- Copyright (C) 2010 Bernhard Urban <lewurm@gmail.com>
9 -- This program is free software: you can redistribute it and/or modify
10 -- it under the terms of the GNU General Public License as published by
11 -- the Free Software Foundation, either version 3 of the License, or
12 -- (at your option) any later version.
14 -- This program is distributed in the hope that it will be useful,
15 -- but WITHOUT ANY WARRANTY; without even the implied warranty of
16 -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 -- GNU General Public License for more details.
19 -- You should have received a copy of the GNU General Public License
20 -- along with this program. If not, see <http://www.gnu.org/licenses/>.
24 use IEEE.std_logic_1164.all;
25 use IEEE.numeric_std.all;
27 use work.common_pkg.all;
28 use work.extension_pkg.all;
29 --use work.core_extension.all;
34 --type alu_interal_rec is record
36 --end record alu_internal_rec;
38 type alu_result_rec is record
39 result : gp_register_t;
40 result_addr : gp_addr_t;
55 end record alu_result_rec;
57 constant SHIFT_WIDTH : integer := 5; --log2c(gp_register_t'length);
59 constant COND_ZERO : condition_t := "0001";
60 constant COND_NZERO : condition_t := "0000";
61 constant COND_NOFLO : condition_t := "0010";
62 constant COND_OFLO : condition_t := "0011";
63 constant COND_NCARRY : condition_t := "0100";
64 constant COND_CARRY : condition_t := "0101";
65 constant COND_NSIGN : condition_t := "0110";
66 constant COND_SIGN : condition_t := "0111";
68 constant COND_ABOVE : condition_t := "1000";
69 constant COND_BEQ: condition_t := "1001";
70 constant COND_GEQ : condition_t := "1010";
71 constant COND_LT : condition_t := "1011";
72 constant COND_GT : condition_t := "1100";
74 constant COND_LEQ : condition_t := "1101";
75 constant COND_ALWAYS : condition_t := "1110";
76 constant COND_NEVER : condition_t := "1111";
78 function add_oflo(l_neg, r_neg, res_neg : std_logic) return std_logic;
79 -- function addsub_op(left_operand, right_operand : gp_register_t; sub, addc : std_logic; alu_result : alu_result_rec) return alu_result_rec;
81 -- function and_op(left_operand, right_operand : gp_register_t; alu_result : alu_result_rec) return alu_result_rec;
82 -- function or_op(left_operand, right_operand : gp_register_t; alu_result : alu_result_rec) return alu_result_rec;
83 -- function xor_op(left_operand, right_operand : gp_register_t; alu_result : alu_result_rec) return alu_result_rec;
85 -- function shift_op(left_operand, right_operand : gp_register_t; arith,sleft,carry : std_logic ;alu_result : alu_result_rec) return alu_result_rec;
88 --some modules won't need all inputs
95 cond : in condition_t;
96 op_group : in op_info_t;
97 left_operand : in gp_register_t;
98 right_operand : in gp_register_t;
100 displacement : in gp_register_t;
101 prog_cnt : in instr_addr_t;
104 op_detail : in op_opt_t;
106 alu_state : in alu_result_rec;
107 pval : in gp_register_t;
108 pval_nxt : in gp_register_t;
110 alu_result : out alu_result_rec;
111 addr : out word_t; --memaddr
112 data : out gp_register_t; --mem data --ureg
114 pinc : out std_logic;
115 pwr_en : out std_logic;
122 package body alu_pkg is
124 function add_oflo(l_neg, r_neg , res_neg: std_logic) return std_logic is
126 return (l_neg AND r_neg AND not(res_neg)) OR
127 (not(l_neg) AND not(r_neg) AND res_neg);
128 end function add_oflo;
130 -- function addsub_op(left_operand, right_operand : gp_register_t; sub, addc : std_logic; alu_result : alu_result_rec) return alu_result_rec is
131 -- variable alu_result_out : alu_result_rec;
132 -- variable complement : gp_register_t;
133 -- variable carry_res : unsigned(gp_register_t'length downto 0);
134 -- variable tmp_right_operand : unsigned(gp_register_t'length downto 0);
135 -- variable oflo1, oflo2, l_neg, r_neg : std_logic;
136 -- variable addcarry : unsigned(carry_res'range);
138 -- alu_result_out := alu_result;
140 -- addcarry := (others =>'0');
141 -- addcarry(0) := unsigned(alu_result.status.carry and addc);
143 -- complement := inc(not(right_operand));
144 -- l_neg := left_operand(gp_register_t'high);
146 -- carry_res := unsigned('0' & left_operand)+addcarry;
147 -- oflo1 := add_oflo(l_neg,'0',std_logic_vector(carry_res)(gp_register_t'high));
150 -- tmp_right_operand := unsigned('0' & complement);
152 -- tmp_right_operand := unsigned('0' & right_operand);
155 -- l_neg := std_logic_vector(carry_res)(gp_register_t'high);
156 -- r_neg := std_logic_vector(tmp_right_operand)(gp_register_t'high);
158 -- carry_res := carry_res + tmp_right_operand;
159 -- oflo2 := add_oflo(l_neg,r_neg,std_logic_vector(carry_res)(gp_register_t'high));
162 -- alu_result_out.result := std_logic_vector(carry_res)(gp_register_t'range);
163 -- alu_result_out.status.carry := std_logic_vector(carry_res)(carry_res'high);
166 -- alu_result_out.status.carry := oflo1 or oflo2;
168 -- --sign will be set globally.
169 -- --zero will be set globally.
171 -- return alu_result_out;
172 -- end function addsub_op;
174 -- function and_op(left_operand, right_operand : gp_register_t; alu_result : alu_result_rec) return alu_result_rec is
175 -- variable alu_result_out : alu_result_rec;
177 -- alu_result_out := alu_result;
178 -- alu_result_out.result := left_operand and right_operand;
179 -- end function and_op;
181 -- function or_op(left_operand, right_operand : gp_register_t; alu_result : alu_result_rec) return alu_result_rec is
182 -- variable alu_result_out : alu_result_rec;
184 -- alu_result_out := alu_result;
185 -- alu_result_out.result := left_operand or right_operand;
186 -- end function or_op;
188 -- function xor_op(left_operand, right_operand : gp_register_t; alu_result : alu_result_rec) return alu_result_rec is
189 -- variable alu_result_out : alu_result_rec;
191 -- alu_result_out := alu_result;
192 -- alu_result_out.result := left_operand xor right_operand;
193 -- end function xor_op;
195 -- 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
196 -- variable alu_result_out : alu_result_rec;
197 -- variable tmp_shift : bit_vector(gp_register_t'length+1 downto 0);
198 -- variable tmp_sb : std_logic;
200 -- alu_result_out := alu_result;
203 -- tmp_sb := (carry and alu_result.status.carry and not(arith)) or (arith and left_operand(gp_register_t'high));
204 -- tmp_shift := bit_vector(tmp_sb & left_operand & alu_result.status.carry);
205 -- tmp_shift := tmp_shift sra to_integer(unsigned(right_operand)(SHIFT_WIDTH-1 downto 0));
207 -- alu_result_out.status.carry := std_logic_vector(tmp_shift)(0);
209 -- tmp_sb := (carry and alu_result.status.carry and not(arith));
210 -- tmp_shift := bit_vector(alu_result.status.carry & left_operand & tmp_sb);
211 -- tmp_shift := tmp_shift sla to_integer(unsigned(right_operand)(SHIFT_WIDTH-1 downto 0));
213 -- alu_result_out.status.carry := std_logic_vector(tmp_shift)(tmp_shift'high);
216 -- alu_result_out.result := std_logic_vector(tmp_shift)(gp_register_t'length downto 1);
218 -- end function shift_op;
220 end package body alu_pkg;