X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=cpu%2Fsrc%2Falu_pkg.vhd;fp=cpu%2Fsrc%2Falu_pkg.vhd;h=99b4655047b699dc4be8a2afad494800359523d5;hb=b930136793b80b6a3a79a9b97864ab9ff3957472;hp=cc085c76889d6b5ef21bad97cd017c4b4b52c932;hpb=6878fe10bd720f714760a7e446c5a415828a1c2b;p=calu.git diff --git a/cpu/src/alu_pkg.vhd b/cpu/src/alu_pkg.vhd index cc085c7..99b4655 100755 --- a/cpu/src/alu_pkg.vhd +++ b/cpu/src/alu_pkg.vhd @@ -1,195 +1,195 @@ -library IEEE; - -use IEEE.std_logic_1164.all; -use IEEE.numeric_std.all; - -use work.common_pkg.all; ---use work.core_extension.all; - - -package alu_pkg is - - type status_rec is record - zero : std_logic; - oflo : std_logic; - sign : std_logic; - carry : std_logic; - end record; - - subtype status_t is byte_t; - --type alu_interal_rec is record - -- - --end record alu_internal_rec; - - type alu_result_rec is record - result : gp_register_t; - result_addr : gp_addr_t; - - status : status_rec; - --stackpointer : gp_register_t; - - alu_jump : std_logic; - brpr : std_logic; - reg_op : std_logic; - mem_op : std_logic; - - --new_val : std_logic; - mem_en : std_logic; - - hw_op : std_logic; - byte_op : std_logic; - sign_xt : std_logic; - - end record alu_result_rec; - - constant SHIFT_WIDTH : integer := log2c(gp_register_t'length); - - constant COND_ZERO : condition_t := "0001"; - constant COND_NZERO : condition_t := "0000"; - constant COND_NOFLO : condition_t := "0010"; - constant COND_OFLO : condition_t := "0011"; - constant COND_NCARRY : condition_t := "0100"; - constant COND_CARRY : condition_t := "0101"; - constant COND_NSIGN : condition_t := "0110"; - constant COND_SIGN : condition_t := "0111"; - - constant COND_ABOVE : condition_t := "1000"; - constant COND_BEQ: condition_t := "1001"; - constant COND_GEQ : condition_t := "1010"; - constant COND_LT : condition_t := "1011"; - constant COND_GT : condition_t := "1100"; - - constant COND_LEQ : condition_t := "1101"; - constant COND_ALWAYS : condition_t := "1110"; - constant COND_NEVER : condition_t := "1111"; - - function add_oflo(l_neg, r_neg, res_neg : std_logic) return std_logic; - -- function addsub_op(left_operand, right_operand : gp_register_t; sub, addc : std_logic; alu_result : alu_result_rec) return alu_result_rec; - - -- function and_op(left_operand, right_operand : gp_register_t; alu_result : alu_result_rec) return alu_result_rec; - -- function or_op(left_operand, right_operand : gp_register_t; alu_result : alu_result_rec) return alu_result_rec; - -- function xor_op(left_operand, right_operand : gp_register_t; alu_result : alu_result_rec) return alu_result_rec; - - -- function shift_op(left_operand, right_operand : gp_register_t; arith,sleft,carry : std_logic ;alu_result : alu_result_rec) return alu_result_rec; - - component alu is - --some modules won't need all inputs - port( - --System inputs - - clk : in std_logic; - reset : in std_logic; - --operation inputs - cond : in condition_t; - op_group : in op_info_t; - left_operand : in gp_register_t; - right_operand : in gp_register_t; - op_detail : in op_opt_t; - alu_state : in alu_result_rec; - alu_result : out alu_result_rec; - addr : out gp_register_t; - data : out gp_register_t - ); - end component alu; - -end package alu_pkg; - -package body alu_pkg is - - function add_oflo(l_neg, r_neg , res_neg: std_logic) return std_logic is - begin - return (l_neg AND r_neg AND not(res_neg)) OR - (not(l_neg) AND not(r_neg) AND res_neg); - end function add_oflo; - - -- function addsub_op(left_operand, right_operand : gp_register_t; sub, addc : std_logic; alu_result : alu_result_rec) return alu_result_rec is - -- variable alu_result_out : alu_result_rec; - -- variable complement : gp_register_t; - -- variable carry_res : unsigned(gp_register_t'length downto 0); - -- variable tmp_right_operand : unsigned(gp_register_t'length downto 0); - -- variable oflo1, oflo2, l_neg, r_neg : std_logic; - -- variable addcarry : unsigned(carry_res'range); - -- begin - -- alu_result_out := alu_result; - - -- addcarry := (others =>'0'); - -- addcarry(0) := unsigned(alu_result.status.carry and addc); - - -- complement := inc(not(right_operand)); - -- l_neg := left_operand(gp_register_t'high); - - -- carry_res := unsigned('0' & left_operand)+addcarry; - -- oflo1 := add_oflo(l_neg,'0',std_logic_vector(carry_res)(gp_register_t'high)); - - -- if sub = '1' then - -- tmp_right_operand := unsigned('0' & complement); - -- else - -- tmp_right_operand := unsigned('0' & right_operand); - -- end if; - - -- l_neg := std_logic_vector(carry_res)(gp_register_t'high); - -- r_neg := std_logic_vector(tmp_right_operand)(gp_register_t'high); - - -- carry_res := carry_res + tmp_right_operand; - -- oflo2 := add_oflo(l_neg,r_neg,std_logic_vector(carry_res)(gp_register_t'high)); - - - -- alu_result_out.result := std_logic_vector(carry_res)(gp_register_t'range); - -- alu_result_out.status.carry := std_logic_vector(carry_res)(carry_res'high); - - - -- alu_result_out.status.carry := oflo1 or oflo2; - - -- --sign will be set globally. - -- --zero will be set globally. - - -- return alu_result_out; - -- end function addsub_op; - - -- function and_op(left_operand, right_operand : gp_register_t; alu_result : alu_result_rec) return alu_result_rec is - -- variable alu_result_out : alu_result_rec; - -- begin - -- alu_result_out := alu_result; - -- alu_result_out.result := left_operand and right_operand; - -- end function and_op; - - -- function or_op(left_operand, right_operand : gp_register_t; alu_result : alu_result_rec) return alu_result_rec is - -- variable alu_result_out : alu_result_rec; - -- begin - -- alu_result_out := alu_result; - -- alu_result_out.result := left_operand or right_operand; - -- end function or_op; - - -- function xor_op(left_operand, right_operand : gp_register_t; alu_result : alu_result_rec) return alu_result_rec is - -- variable alu_result_out : alu_result_rec; - -- begin - -- alu_result_out := alu_result; - -- alu_result_out.result := left_operand xor right_operand; - -- end function xor_op; - - -- 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 - -- variable alu_result_out : alu_result_rec; - -- variable tmp_shift : bit_vector(gp_register_t'length+1 downto 0); - -- variable tmp_sb : std_logic; - -- begin - -- alu_result_out := alu_result; - - -- if rs = '1' then - -- tmp_sb := (carry and alu_result.status.carry and not(arith)) or (arith and left_operand(gp_register_t'high)); - -- tmp_shift := bit_vector(tmp_sb & left_operand & alu_result.status.carry); - -- tmp_shift := tmp_shift sra to_integer(unsigned(right_operand)(SHIFT_WIDTH-1 downto 0)); - - -- alu_result_out.status.carry := std_logic_vector(tmp_shift)(0); - -- else - -- tmp_sb := (carry and alu_result.status.carry and not(arith)); - -- tmp_shift := bit_vector(alu_result.status.carry & left_operand & tmp_sb); - -- tmp_shift := tmp_shift sla to_integer(unsigned(right_operand)(SHIFT_WIDTH-1 downto 0)); - - -- alu_result_out.status.carry := std_logic_vector(tmp_shift)(tmp_shift'high); - -- end if; - - -- alu_result_out.result := std_logic_vector(tmp_shift)(gp_register_t'length downto 1); - - -- end function shift_op; - -end package body alu_pkg; +library IEEE; + +use IEEE.std_logic_1164.all; +use IEEE.numeric_std.all; + +use work.common_pkg.all; +--use work.core_extension.all; + + +package alu_pkg is + + type status_rec is record + zero : std_logic; + oflo : std_logic; + sign : std_logic; + carry : std_logic; + end record; + + subtype status_t is byte_t; + --type alu_interal_rec is record + -- + --end record alu_internal_rec; + + type alu_result_rec is record + result : gp_register_t; + result_addr : gp_addr_t; + + status : status_rec; + --stackpointer : gp_register_t; + + alu_jump : std_logic; + brpr : std_logic; + reg_op : std_logic; + mem_op : std_logic; + + --new_val : std_logic; + mem_en : std_logic; + + hw_op : std_logic; + byte_op : std_logic; + sign_xt : std_logic; + + end record alu_result_rec; + + constant SHIFT_WIDTH : integer := log2c(gp_register_t'length); + + constant COND_ZERO : condition_t := "0001"; + constant COND_NZERO : condition_t := "0000"; + constant COND_NOFLO : condition_t := "0010"; + constant COND_OFLO : condition_t := "0011"; + constant COND_NCARRY : condition_t := "0100"; + constant COND_CARRY : condition_t := "0101"; + constant COND_NSIGN : condition_t := "0110"; + constant COND_SIGN : condition_t := "0111"; + + constant COND_ABOVE : condition_t := "1000"; + constant COND_BEQ: condition_t := "1001"; + constant COND_GEQ : condition_t := "1010"; + constant COND_LT : condition_t := "1011"; + constant COND_GT : condition_t := "1100"; + + constant COND_LEQ : condition_t := "1101"; + constant COND_ALWAYS : condition_t := "1110"; + constant COND_NEVER : condition_t := "1111"; + + function add_oflo(l_neg, r_neg, res_neg : std_logic) return std_logic; + -- function addsub_op(left_operand, right_operand : gp_register_t; sub, addc : std_logic; alu_result : alu_result_rec) return alu_result_rec; + + -- function and_op(left_operand, right_operand : gp_register_t; alu_result : alu_result_rec) return alu_result_rec; + -- function or_op(left_operand, right_operand : gp_register_t; alu_result : alu_result_rec) return alu_result_rec; + -- function xor_op(left_operand, right_operand : gp_register_t; alu_result : alu_result_rec) return alu_result_rec; + + -- function shift_op(left_operand, right_operand : gp_register_t; arith,sleft,carry : std_logic ;alu_result : alu_result_rec) return alu_result_rec; + + component alu is + --some modules won't need all inputs + port( + --System inputs + + clk : in std_logic; + reset : in std_logic; + --operation inputs + cond : in condition_t; + op_group : in op_info_t; + left_operand : in gp_register_t; + right_operand : in gp_register_t; + op_detail : in op_opt_t; + alu_state : in alu_result_rec; + alu_result : out alu_result_rec; + addr : out gp_register_t; + data : out gp_register_t + ); + end component alu; + +end package alu_pkg; + +package body alu_pkg is + + function add_oflo(l_neg, r_neg , res_neg: std_logic) return std_logic is + begin + return (l_neg AND r_neg AND not(res_neg)) OR + (not(l_neg) AND not(r_neg) AND res_neg); + end function add_oflo; + + -- function addsub_op(left_operand, right_operand : gp_register_t; sub, addc : std_logic; alu_result : alu_result_rec) return alu_result_rec is + -- variable alu_result_out : alu_result_rec; + -- variable complement : gp_register_t; + -- variable carry_res : unsigned(gp_register_t'length downto 0); + -- variable tmp_right_operand : unsigned(gp_register_t'length downto 0); + -- variable oflo1, oflo2, l_neg, r_neg : std_logic; + -- variable addcarry : unsigned(carry_res'range); + -- begin + -- alu_result_out := alu_result; + + -- addcarry := (others =>'0'); + -- addcarry(0) := unsigned(alu_result.status.carry and addc); + + -- complement := inc(not(right_operand)); + -- l_neg := left_operand(gp_register_t'high); + + -- carry_res := unsigned('0' & left_operand)+addcarry; + -- oflo1 := add_oflo(l_neg,'0',std_logic_vector(carry_res)(gp_register_t'high)); + + -- if sub = '1' then + -- tmp_right_operand := unsigned('0' & complement); + -- else + -- tmp_right_operand := unsigned('0' & right_operand); + -- end if; + + -- l_neg := std_logic_vector(carry_res)(gp_register_t'high); + -- r_neg := std_logic_vector(tmp_right_operand)(gp_register_t'high); + + -- carry_res := carry_res + tmp_right_operand; + -- oflo2 := add_oflo(l_neg,r_neg,std_logic_vector(carry_res)(gp_register_t'high)); + + + -- alu_result_out.result := std_logic_vector(carry_res)(gp_register_t'range); + -- alu_result_out.status.carry := std_logic_vector(carry_res)(carry_res'high); + + + -- alu_result_out.status.carry := oflo1 or oflo2; + + -- --sign will be set globally. + -- --zero will be set globally. + + -- return alu_result_out; + -- end function addsub_op; + + -- function and_op(left_operand, right_operand : gp_register_t; alu_result : alu_result_rec) return alu_result_rec is + -- variable alu_result_out : alu_result_rec; + -- begin + -- alu_result_out := alu_result; + -- alu_result_out.result := left_operand and right_operand; + -- end function and_op; + + -- function or_op(left_operand, right_operand : gp_register_t; alu_result : alu_result_rec) return alu_result_rec is + -- variable alu_result_out : alu_result_rec; + -- begin + -- alu_result_out := alu_result; + -- alu_result_out.result := left_operand or right_operand; + -- end function or_op; + + -- function xor_op(left_operand, right_operand : gp_register_t; alu_result : alu_result_rec) return alu_result_rec is + -- variable alu_result_out : alu_result_rec; + -- begin + -- alu_result_out := alu_result; + -- alu_result_out.result := left_operand xor right_operand; + -- end function xor_op; + + -- 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 + -- variable alu_result_out : alu_result_rec; + -- variable tmp_shift : bit_vector(gp_register_t'length+1 downto 0); + -- variable tmp_sb : std_logic; + -- begin + -- alu_result_out := alu_result; + + -- if rs = '1' then + -- tmp_sb := (carry and alu_result.status.carry and not(arith)) or (arith and left_operand(gp_register_t'high)); + -- tmp_shift := bit_vector(tmp_sb & left_operand & alu_result.status.carry); + -- tmp_shift := tmp_shift sra to_integer(unsigned(right_operand)(SHIFT_WIDTH-1 downto 0)); + + -- alu_result_out.status.carry := std_logic_vector(tmp_shift)(0); + -- else + -- tmp_sb := (carry and alu_result.status.carry and not(arith)); + -- tmp_shift := bit_vector(alu_result.status.carry & left_operand & tmp_sb); + -- tmp_shift := tmp_shift sla to_integer(unsigned(right_operand)(SHIFT_WIDTH-1 downto 0)); + + -- alu_result_out.status.carry := std_logic_vector(tmp_shift)(tmp_shift'high); + -- end if; + + -- alu_result_out.result := std_logic_vector(tmp_shift)(gp_register_t'length downto 1); + + -- end function shift_op; + +end package body alu_pkg;