From b9d8ef6cdcd9cacadb75193ad9a44d1d821320ce Mon Sep 17 00:00:00 2001 From: =?utf8?q?Markus=20Hofst=C3=A4tter?= Date: Sun, 14 Nov 2010 15:14:20 +0100 Subject: [PATCH] Seperation to differen execute operations. --- cpu/src/alu.vhd | 26 +++++ cpu/src/alu_b.vhd | 142 ++++++++++++++++++++++---- cpu/src/alu_pkg.vhd | 180 ++++++++++++++++++--------------- cpu/src/common_pkg.vhd | 15 +-- cpu/src/exec_op.vhd | 28 +++-- cpu/src/exec_op/add_op_b.vhd | 61 +++++++++++ cpu/src/exec_op/and_op_b.vhd | 22 ++++ cpu/src/exec_op/or_op_b.vhd | 22 ++++ cpu/src/exec_op/shift_op_b.vhd | 46 +++++++++ cpu/src/exec_op/xor_op_b.vhd | 22 ++++ 10 files changed, 443 insertions(+), 121 deletions(-) create mode 100755 cpu/src/alu.vhd mode change 100644 => 100755 cpu/src/common_pkg.vhd create mode 100755 cpu/src/exec_op/add_op_b.vhd create mode 100755 cpu/src/exec_op/and_op_b.vhd create mode 100755 cpu/src/exec_op/or_op_b.vhd create mode 100755 cpu/src/exec_op/shift_op_b.vhd create mode 100755 cpu/src/exec_op/xor_op_b.vhd diff --git a/cpu/src/alu.vhd b/cpu/src/alu.vhd new file mode 100755 index 0000000..b94421a --- /dev/null +++ b/cpu/src/alu.vhd @@ -0,0 +1,26 @@ +library IEEE; +use IEEE.std_logic_1164.all; +use IEEE.numeric_std.all; + +use work.common_pkg.all; +use work.alu_pkg.all; + +entity alu is + --some modules won't need all inputs + port( + --System inputs + + clk : in std_logic; + reset : in std_logic; + --operation inputs + condition : 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 + ); + +end alu; + diff --git a/cpu/src/alu_b.vhd b/cpu/src/alu_b.vhd index 533ed7f..511b154 100755 --- a/cpu/src/alu_b.vhd +++ b/cpu/src/alu_b.vhd @@ -2,37 +2,139 @@ library IEEE; use IEEE.std_logic_1164.all; use IEEE.numeric_std.all; -use work.core_pkg.all; use work.alu_pkg.all; -architecture behaviour of alu is +architecture behaviour of alu is + component exec_op is + port( + --System inputs + + clk : in std_logic; + reset : in std_logic; + --operation inputs + 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 + ); + end component exec_op; + + signal add_result, and_result, or_result, xor_result, shift_result : alu_result_rec; + begin -syn: process(sys_clk, reset) + add_inst : exec_op + port map(clk,reset,left_operand, right_operand, op_detail, alu_state, add_result); + + and_inst : exec_op + port map(clk,reset,left_operand, right_operand, op_detail, alu_state, and_result); + or_inst : exec_op + port map(clk,reset,left_operand, right_operand, op_detail, alu_state, or_result); + xor_inst : exec_op + port map(clk,reset,left_operand, right_operand, op_detail, alu_state, xor_result); + + shift_inst : exec_op + port map(clk,reset,left_operand, right_operand, op_detail, alu_state, shift_result); +calc: process(condition, op_group, op_detail ,alu_state,and_result,add_result,or_result,xor_result,shift_result) + variable result_v : alu_result_rec; + variable res_prod : std_logic; + variable cond_met : std_logic; + variable mem_en : std_logic; begin - - if (reset = RESET_VALUE) then - - elsif rising_edge(sys_clk) then - + result_v := alu_state; + + result_v.result := add_result.result; + res_prod := '1'; + mem_en := '0'; + + case condition is + when COND_NZERO => + cond_met := not(alu_state.status.zero); + when COND_ZERO => + cond_met := alu_state.status.zero; + when COND_NOFLO => + cond_met := not(alu_state.status.oflo); + when COND_OFLO => + cond_met := alu_state.status.oflo; + when COND_NCARRY => + cond_met := not(alu_state.status.carry); + when COND_CARRY => + cond_met := alu_state.status.carry; + when COND_NSIGN => + cond_met := not(alu_state.status.sign); + when COND_SIGN => + cond_met := alu_state.status.sign; + when COND_ABOVE => + cond_met := not(alu_state.status.carry) and not(alu_state.status.zero); + when COND_BEQ => + cond_met := alu_state.status.carry or alu_state.status.zero; + when COND_GEQ => + cond_met := not(alu_state.status.sign xor alu_state.status.oflo); + when COND_LT => + cond_met := alu_state.status.sign xor alu_state.status.oflo; + when COND_GT => + cond_met := not(alu_state.status.zero) and not(alu_state.status.sign xor alu_state.status.oflo); + when COND_LEQ => + cond_met := alu_state.status.zero or (alu_state.status.sign xor alu_state.status.oflo); + when COND_ALWAYS => + cond_met := '1'; + when COND_NEVER => + cond_met := '0'; + end case; + + case op_group is + when ADDSUB_OP => + result_v := add_result; + when AND_OP => + result_v := and_result; + when OR_OP => + result_v := or_result; + when XOR_OP => + result_v := xor_result; + when SHIFT_OP => + result_v := shift_result; + end case; + + if result_v.result = REG_ZERO then + result_v.status.zero := '1'; end if; -end process syn; - - -nxt_calc: process(sys_clk, reset) - -begin + result_v.status.sign := result_v.result(gp_register_t'high); + if (op_detail(NO_PSW_OPT) = '1') or (cond_met = '0') then + result_v.status := alu_state.status; + end if; - case new_op is - when ADD_SUB => - - when others => null; - end case; + result_v.new_val := not(op_detail(NO_DST_OPT)) and res_prod and cond_met; + result_v.mem_en := mem_en and cond_met; + + alu_result <= result_v; -end process nxt_calc; +end process calc; end architecture behaviour; + +configuration alu_cfg of alu is + + for behaviour + for add_inst : exec_op + use entity work.exec_op(add_op); + end for; + for and_inst : exec_op + use entity work.exec_op(and_op); + end for; + for or_inst : exec_op + use entity work.exec_op(or_op); + end for; + for xor_inst : exec_op + use entity work.exec_op(xor_op); + end for; + for shift_inst : exec_op + use entity work.exec_op(shift_op); + end for; + end for; + +end configuration alu_cfg; diff --git a/cpu/src/alu_pkg.vhd b/cpu/src/alu_pkg.vhd index 9ab2384..05e040d 100755 --- a/cpu/src/alu_pkg.vhd +++ b/cpu/src/alu_pkg.vhd @@ -17,9 +17,9 @@ package alu_pkg is end record; subtype status_t is byte_t; - type alu_interal_rec is record - - end record alu_internal_rec; + --type alu_interal_rec is record + -- + --end record alu_internal_rec; type alu_result_rec is record result : gp_register_t; @@ -33,22 +33,44 @@ package alu_pkg is 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 SHIFT_WIDTH : integer := 1;--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 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 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; + -- function shift_op(left_operand, right_operand : gp_register_t; arith,sleft,carry : std_logic ;alu_result : alu_result_rec) return alu_result_rec; end package alu_pkg; @@ -61,94 +83,94 @@ package body alu_pkg is (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; + -- 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); + -- 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); + -- 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)); + -- 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; + -- 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); + -- 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)); + -- 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.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; + -- alu_result_out.status.carry := oflo1 or oflo2; - --sign will be set globally. - --zero will be set globally. + -- --sign will be set globally. + -- --zero will be set globally. - return alu_result_out; - end function addsub_op; + -- 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 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 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)); + -- 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)(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.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); + -- alu_result_out.result := std_logic_vector(tmp_shift)(gp_register_t'length downto 1); - end function shift_op; + -- end function shift_op; end package body alu_pkg; diff --git a/cpu/src/common_pkg.vhd b/cpu/src/common_pkg.vhd old mode 100644 new mode 100755 index c54829b..9398fb2 --- a/cpu/src/common_pkg.vhd +++ b/cpu/src/common_pkg.vhd @@ -28,7 +28,7 @@ package common_pkg is constant DATA_ADDR_WIDTH : INTEGER := 32; constant PHYS_DATA_ADDR_WIDTH : INTEGER := 32; - constant NUM_OP_OPT_WIDTH : INTEGER := 5; + constant NUM_OP_OPT_WIDTH : INTEGER := 6; constant COND_WIDTH : INTEGER := 4; @@ -46,19 +46,20 @@ package common_pkg is --currently not complete, might need option increase too. --IMMEDIATE always in right_operand (src2) - constant IMM_OPT : integer := 0; + constant IMM_OPT : integer := 0; -- no sharing constant SUB_OPT : integer := 1; - constant LOG_SHIFT : integer := 1; + constant LOG_OPT : integer := 1; constant CARRY_OPT : integer := 2; - constant LEFT_SHIFT : integer := 3; + constant LEFT_OPT : integer := 3; - constant PSW_DISABLE : integer := 4; + constant NO_PSW_OPT : integer := 4;--no sharing + constant NO_DST_OPT : integer := 5; --no sharing type op_info_t is (ADDSUB_OP,AND_OP,OR_OP, XOR_OP,SHIFT_OP); - subtype op_opt_rec is std_logic_vector(NUM_OP_OPT_WIDTH-1 downto 0); + subtype op_opt_t is std_logic_vector(NUM_OP_OPT_WIDTH-1 downto 0); type instruction_rec is record @@ -92,7 +93,7 @@ package common_pkg is type dec_op is record condition : condition_t; op_group : op_info_t; - op_detail : op_opt_rec; + op_detail : op_opt_t; brpr : std_logic; src1 : gp_register_t; diff --git a/cpu/src/exec_op.vhd b/cpu/src/exec_op.vhd index b3ef75b..0c2b8bd 100755 --- a/cpu/src/exec_op.vhd +++ b/cpu/src/exec_op.vhd @@ -2,24 +2,22 @@ library IEEE; use IEEE.std_logic_1164.all; use IEEE.numeric_std.all; -entity exec_op is +use work.common_pkg.all; +use work.alu_pkg.all; - generic ( - -- active reset value - RESET_VALUE : std_logic; - -- active logic value - LOGIC_ACT : std_logic - - ); +entity exec_op is + --some modules won't need all inputs port( - --System inputs + --System inputs + clk : in std_logic; reset : in std_logic; - -- - - - alu_state : in alu_result_rec; - alu_state_out : out alu_result_rec + --operation inputs + 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 ); -end execute_stage; +end exec_op; diff --git a/cpu/src/exec_op/add_op_b.vhd b/cpu/src/exec_op/add_op_b.vhd new file mode 100755 index 0000000..e3d62c6 --- /dev/null +++ b/cpu/src/exec_op/add_op_b.vhd @@ -0,0 +1,61 @@ +library IEEE; +use IEEE.std_logic_1164.all; +use IEEE.numeric_std.all; + +use work.common_pkg.all; +use work.alu_pkg.all; + +architecture add_op of exec_op is + +signal sub, addc : std_logic; + +begin + +sub <= op_detail(SUB_OPT); +addc <= op_detail(CARRY_OPT); + +calc: process(left_operand, right_operand, alu_state, sub, addc) + variable alu_result_v : 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_v := alu_state; + + addcarry := (others =>'0'); + addcarry(0) := alu_state.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_v.result := std_logic_vector(carry_res)(gp_register_t'range); + alu_result_v.status.carry := std_logic_vector(carry_res)(carry_res'high); + + + alu_result_v.status.carry := oflo1 or oflo2; + + --sign will be set globally. + --zero will be set globally. + + alu_result <= alu_result_v; +end process; + +end architecture add_op; diff --git a/cpu/src/exec_op/and_op_b.vhd b/cpu/src/exec_op/and_op_b.vhd new file mode 100755 index 0000000..05c8f3e --- /dev/null +++ b/cpu/src/exec_op/and_op_b.vhd @@ -0,0 +1,22 @@ +library IEEE; +use IEEE.std_logic_1164.all; +use IEEE.numeric_std.all; + +use work.common_pkg.all; +use work.alu_pkg.all; + +architecture and_op of exec_op is +begin + +calc: process(left_operand, right_operand, alu_state) + variable alu_result_v : alu_result_rec; + +begin + alu_result_v := alu_state; + + alu_result_v.result := left_operand and right_operand; + + alu_result <= alu_result_v; +end process; + +end architecture and_op; diff --git a/cpu/src/exec_op/or_op_b.vhd b/cpu/src/exec_op/or_op_b.vhd new file mode 100755 index 0000000..fbe1ec8 --- /dev/null +++ b/cpu/src/exec_op/or_op_b.vhd @@ -0,0 +1,22 @@ +library IEEE; +use IEEE.std_logic_1164.all; +use IEEE.numeric_std.all; + +use work.common_pkg.all; +use work.alu_pkg.all; + +architecture or_op of exec_op is +begin + +calc: process(left_operand, right_operand, alu_state) + variable alu_result_v : alu_result_rec; + +begin + alu_result_v := alu_state; + + alu_result_v.result := left_operand or right_operand; + + alu_result <= alu_result_v; +end process; + +end architecture or_op; diff --git a/cpu/src/exec_op/shift_op_b.vhd b/cpu/src/exec_op/shift_op_b.vhd new file mode 100755 index 0000000..291b590 --- /dev/null +++ b/cpu/src/exec_op/shift_op_b.vhd @@ -0,0 +1,46 @@ +library IEEE; +use IEEE.std_logic_1164.all; +use IEEE.numeric_std.all; + +use work.common_pkg.all; +use work.alu_pkg.all; + +architecture shift_op of exec_op is + + signal logic, ls, carry : std_logic; + +begin + + logic <= op_detail(LOG_OPT); + ls <= op_detail(LEFT_OPT); + carry <= op_detail(CARRY_OPT); + +calc: process(left_operand, right_operand, logic,ls, carry, alu_state) + variable alu_result_v : alu_result_rec; + variable tmp_shift : bit_vector(gp_register_t'length+1 downto 0); + variable tmp_sb : std_logic; + begin + alu_result_v := alu_state; + + if ls = '1' then + tmp_sb := (carry and alu_state.status.carry and logic); + tmp_shift := to_bitvector(alu_state.status.carry & left_operand & tmp_sb); + tmp_shift := tmp_shift sla to_integer(unsigned(right_operand)(SHIFT_WIDTH-1 downto 0)); + + alu_result_v.status.carry := to_stdlogicvector(tmp_shift)(tmp_shift'high); + + else + tmp_sb := (carry and alu_state.status.carry and logic) or (not(logic) and left_operand(gp_register_t'high)); + tmp_shift := to_bitvector(tmp_sb & left_operand & alu_state.status.carry); + tmp_shift := tmp_shift sra to_integer(unsigned(right_operand)(SHIFT_WIDTH-1 downto 0)); + + alu_result_v.status.carry := to_stdlogicvector(tmp_shift)(0); + end if; + + alu_result_v.result := to_stdlogicvector(tmp_shift)(gp_register_t'length downto 1); + + alu_result <= alu_result_v; + +end process; + +end architecture shift_op; diff --git a/cpu/src/exec_op/xor_op_b.vhd b/cpu/src/exec_op/xor_op_b.vhd new file mode 100755 index 0000000..62c7db8 --- /dev/null +++ b/cpu/src/exec_op/xor_op_b.vhd @@ -0,0 +1,22 @@ +library IEEE; +use IEEE.std_logic_1164.all; +use IEEE.numeric_std.all; + +use work.common_pkg.all; +use work.alu_pkg.all; + +architecture xor_op of exec_op is +begin + +calc: process(left_operand, right_operand, alu_state) + variable alu_result_v : alu_result_rec; + +begin + alu_result_v := alu_state; + + alu_result_v.result := left_operand xor right_operand; + + alu_result <= alu_result_v; +end process; + +end architecture xor_op; -- 2.25.1