-library IEEE;\r
-\r
-use IEEE.std_logic_1164.all;\r
-use IEEE.numeric_std.all;\r
-\r
-use work.common_pkg.all;\r
---use work.core_extension.all;\r
-\r
-\r
-package alu_pkg is\r
- \r
- type status_rec is record\r
- zero : std_logic;\r
- oflo : std_logic;\r
- sign : std_logic;\r
- carry : std_logic;\r
- end record;\r
- \r
- subtype status_t is byte_t;\r
- --type alu_interal_rec is record\r
- -- \r
- --end record alu_internal_rec;\r
- \r
- type alu_result_rec is record\r
- result : gp_register_t;\r
- result_addr : gp_addr_t;\r
- \r
- status : status_rec;\r
- --stackpointer : gp_register_t;\r
-\r
- alu_jmp : std_logic;\r
- brpr : std_logic;\r
- reg_op : std_logic;\r
- mem_op : std_logic;\r
- \r
- --new_val : std_logic;\r
- mem_en : std_logic;\r
- \r
- hw_op : std_logic;\r
- byte_op : std_logic;\r
- sign_xt : std_logic;\r
- \r
- end record alu_result_rec;\r
- \r
- constant SHIFT_WIDTH : integer := 1;--log2c(gp_register_t'length);\r
- \r
- constant COND_ZERO : condition_t := "0001";\r
- constant COND_NZERO : condition_t := "0000";\r
- constant COND_NOFLO : condition_t := "0010";\r
- constant COND_OFLO : condition_t := "0011";\r
- constant COND_NCARRY : condition_t := "0100";\r
- constant COND_CARRY : condition_t := "0101";\r
- constant COND_NSIGN : condition_t := "0110";\r
- constant COND_SIGN : condition_t := "0111";\r
- \r
- constant COND_ABOVE : condition_t := "1000";\r
- constant COND_BEQ: condition_t := "1001";\r
- constant COND_GEQ : condition_t := "1010";\r
- constant COND_LT : condition_t := "1011";\r
- constant COND_GT : condition_t := "1100";\r
- \r
- constant COND_LEQ : condition_t := "1101";\r
- constant COND_ALWAYS : condition_t := "1110";\r
- constant COND_NEVER : condition_t := "1111";\r
- \r
- function add_oflo(l_neg, r_neg, res_neg : std_logic) return std_logic;\r
- -- function addsub_op(left_operand, right_operand : gp_register_t; sub, addc : std_logic; alu_result : alu_result_rec) return alu_result_rec;\r
- \r
- -- function and_op(left_operand, right_operand : gp_register_t; alu_result : alu_result_rec) return alu_result_rec;\r
- -- function or_op(left_operand, right_operand : gp_register_t; alu_result : alu_result_rec) return alu_result_rec;\r
- -- function xor_op(left_operand, right_operand : gp_register_t; alu_result : alu_result_rec) return alu_result_rec;\r
- \r
- -- 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
+library IEEE;
+
+use IEEE.std_logic_1164.all;
+use IEEE.numeric_std.all;
+
+use work.common_pkg.all;
+use work.extension_pkg.all;
+--use work.core_extension.all;
+
+
+package alu_pkg is
+
+ --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;
+
+ alu_jump : std_logic;
+ brpr : std_logic;
+ reg_op : std_logic;
+ mem_op : 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 := 5; --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\r
- port(\r
- --System inputs\r
- \r
- clk : in std_logic;\r
- reset : in std_logic;\r
- --operation inputs\r
- condition : in condition_t;\r
- op_group : in op_info_t;\r
- left_operand : in gp_register_t;\r
- right_operand : in gp_register_t;\r
- op_detail : in op_opt_t;\r
- alu_state : in alu_result_rec;\r
+ --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;
+
+ displacement : in gp_register_t;
+ prog_cnt : in instr_addr_t;
+ brpr : in std_logic;
+
+ op_detail : in op_opt_t;
+
+ alu_state : in alu_result_rec;
+ pval : in gp_register_t;
+ pval_nxt : in gp_register_t;
+
alu_result : out alu_result_rec;
- addr : out gp_register_t;
- data : out gp_register_t\r
+ addr : out word_t; --memaddr
+ data : out gp_register_t; --mem data --ureg
+
+ pinc : out std_logic;
+ pwr_en : out std_logic;
+ paddr : out paddr_t
);
- end component alu;\r
- \r
-end package alu_pkg;\r
-\r
-package body alu_pkg is\r
-\r
- function add_oflo(l_neg, r_neg , res_neg: std_logic) return std_logic is\r
- begin\r
- return (l_neg AND r_neg AND not(res_neg)) OR \r
- (not(l_neg) AND not(r_neg) AND res_neg);\r
- end function add_oflo;\r
- \r
- -- 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
- -- variable alu_result_out : alu_result_rec;\r
- -- variable complement : gp_register_t;\r
- -- variable carry_res : unsigned(gp_register_t'length downto 0);\r
- -- variable tmp_right_operand : unsigned(gp_register_t'length downto 0);\r
- -- variable oflo1, oflo2, l_neg, r_neg : std_logic;\r
- -- variable addcarry : unsigned(carry_res'range);\r
- -- begin\r
- -- alu_result_out := alu_result;\r
- \r
- -- addcarry := (others =>'0');\r
- -- addcarry(0) := unsigned(alu_result.status.carry and addc);\r
- \r
- -- complement := inc(not(right_operand));\r
- -- l_neg := left_operand(gp_register_t'high);\r
- \r
- -- carry_res := unsigned('0' & left_operand)+addcarry;\r
- -- oflo1 := add_oflo(l_neg,'0',std_logic_vector(carry_res)(gp_register_t'high));\r
- \r
- -- if sub = '1' then\r
- -- tmp_right_operand := unsigned('0' & complement);\r
- -- else\r
- -- tmp_right_operand := unsigned('0' & right_operand);\r
- -- end if;\r
- \r
- -- l_neg := std_logic_vector(carry_res)(gp_register_t'high);\r
- -- r_neg := std_logic_vector(tmp_right_operand)(gp_register_t'high);\r
- \r
- -- carry_res := carry_res + tmp_right_operand;\r
- -- oflo2 := add_oflo(l_neg,r_neg,std_logic_vector(carry_res)(gp_register_t'high));\r
- \r
-\r
- -- alu_result_out.result := std_logic_vector(carry_res)(gp_register_t'range);\r
- -- alu_result_out.status.carry := std_logic_vector(carry_res)(carry_res'high);\r
- \r
- \r
- -- alu_result_out.status.carry := oflo1 or oflo2;\r
- \r
- -- --sign will be set globally.\r
- -- --zero will be set globally.\r
- \r
- -- return alu_result_out;\r
- -- end function addsub_op;\r
- \r
- -- function and_op(left_operand, right_operand : gp_register_t; alu_result : alu_result_rec) return alu_result_rec is\r
- -- variable alu_result_out : alu_result_rec;\r
- -- begin\r
- -- alu_result_out := alu_result;\r
- -- alu_result_out.result := left_operand and right_operand;\r
- -- end function and_op;\r
- \r
- -- function or_op(left_operand, right_operand : gp_register_t; alu_result : alu_result_rec) return alu_result_rec is\r
- -- variable alu_result_out : alu_result_rec;\r
- -- begin\r
- -- alu_result_out := alu_result;\r
- -- alu_result_out.result := left_operand or right_operand;\r
- -- end function or_op;\r
- \r
- -- function xor_op(left_operand, right_operand : gp_register_t; alu_result : alu_result_rec) return alu_result_rec is\r
- -- variable alu_result_out : alu_result_rec;\r
- -- begin\r
- -- alu_result_out := alu_result;\r
- -- alu_result_out.result := left_operand xor right_operand;\r
- -- end function xor_op;\r
- \r
- -- 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
- -- variable alu_result_out : alu_result_rec;\r
- -- variable tmp_shift : bit_vector(gp_register_t'length+1 downto 0);\r
- -- variable tmp_sb : std_logic;\r
- -- begin\r
- -- alu_result_out := alu_result;\r
- \r
- -- if rs = '1' then\r
- -- tmp_sb := (carry and alu_result.status.carry and not(arith)) or (arith and left_operand(gp_register_t'high));\r
- -- tmp_shift := bit_vector(tmp_sb & left_operand & alu_result.status.carry);\r
- -- tmp_shift := tmp_shift sra to_integer(unsigned(right_operand)(SHIFT_WIDTH-1 downto 0));\r
- \r
- -- alu_result_out.status.carry := std_logic_vector(tmp_shift)(0);\r
- -- else\r
- -- tmp_sb := (carry and alu_result.status.carry and not(arith));\r
- -- tmp_shift := bit_vector(alu_result.status.carry & left_operand & tmp_sb);\r
- -- tmp_shift := tmp_shift sla to_integer(unsigned(right_operand)(SHIFT_WIDTH-1 downto 0));\r
- \r
- -- alu_result_out.status.carry := std_logic_vector(tmp_shift)(tmp_shift'high);\r
- -- end if;\r
- \r
- -- alu_result_out.result := std_logic_vector(tmp_shift)(gp_register_t'length downto 1);\r
- \r
- -- end function shift_op;\r
-\r
-end package body alu_pkg;\r
+ 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;