--- /dev/null
+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_bit : std_logic;\r
+ reg_op : std_logic;\r
+ mem_op : 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 := log2c(gp_register_t'length);\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 : 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
+ \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
use IEEE.numeric_std.all;
package common_pkg is
+
constant WORD_WIDTH : INTEGER := 32;
constant HWORD_WIDTH : INTEGER := 16;
constant BYTE_WIDTH : INTEGER := 8;
constant OPCODE_WIDTH : INTEGER := 5;
constant DISPL_WIDTH : INTEGER := 15;
+
+ constant REG_ZERO : gp_register_t := (others => '0');
constant INSTR_ADDR_WIDTH : INTEGER := 32;
constant PHYS_INSTR_ADDR_WIDTH : INTEGER := 11;
constant DATA_ADDR_WIDTH : INTEGER := 32;
constant PHYS_DATA_ADDR_WIDTH : INTEGER := 32;
+ subtype byte_t is std_logic_vector(BYTE_WIDTH-1 downto 0);
+ subtype hword_t is std_logic_vector(HWORD_WIDTH-1 downto 0);
+ subtype word_t is std_logic_vector(WORD_WIDTH-1 downto 0);
+
subtype instruction_word_t is std_logic_vector(WORD_WIDTH-1 downto 0);
subtype instruction_addr_t is std_logic_vector(INSTR_ADDR_WIDTH-1 downto 0);
- subtype gp_register_t is std_logic_vector(WORD_WIDTH-1 downto 0);
-
+ subtype gp_register_t is word_t;
+ subtype gp_addr_t is unsigned(REG_ADDR_WIDTH-1 downto 0);
subtype data_ram_word_t is std_logic_vector(WORD_WIDTH-1 downto 0);
subtype data_ram_addr_t is std_logic_vector(DATA_ADDR_WIDTH-1 downto 0);
subtype opcode_t is std_logic_vector(OPCODE_WIDTH-1 downto 0);
+ function inc(value : in std_logic_vector; constant by : in integer := 1) return std_logic_vector;
+ function log2c(constant value : in integer range 0 to integer'high) return integer;
end package common_pkg;
+
+package body common_pkg;
+
+ function inc(value : in std_logic_vector; constant by : in integer := 1) return std_logic_vector is
+ begin
+ return std_logic_vector(UNSIGNED(value)+by);
+ end function inc;
+
+ function log2c(constant value : in integer range 0 to integer'high) return integer is
+ variable ret_value : integer;
+ variable cur_value : integer;
+ begin
+ ret_value := 0;
+ cur_value := 1;
+
+ while cur_value < value loop
+ ret_value := ret_value + 1;
+ cur_value := cur_value * 2;
+ end loop;
+ return ret_value;
+ end function log2c;
+
+end package body common_pkg;