pipeline erste version mit 31bit shifter (kostet 7MHz und viele LEs)
[calu.git] / cpu / src / alu_pkg.vhd
index cc085c76889d6b5ef21bad97cd017c4b4b52c932..99b4655047b699dc4be8a2afad494800359523d5 100755 (executable)
-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_jump : 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 := 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
-       \r
-        component alu is\r
-        --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
-                       cond : 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
-                       alu_result : out alu_result_rec;\r
-                        addr : out gp_register_t;\r
-                        data : out gp_register_t\r
-               );\r
-        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
+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;