copyleft: gplv3 added and set repo to public
[calu.git] / cpu / src / common_pkg.vhd
old mode 100644 (file)
new mode 100755 (executable)
index 0bd0be7..fd61464
+--   `Deep Thought', a softcore CPU implemented on a FPGA
+--
+--  Copyright (C) 2010 Markus Hofstaetter <markus.manrow@gmx.at>
+--  Copyright (C) 2010 Martin Perner <e0725782@student.tuwien.ac.at>
+--  Copyright (C) 2010 Stefan Rebernig <stefan.rebernig@gmail.com>
+--  Copyright (C) 2010 Manfred Schwarz <e0725898@student.tuwien.ac.at>
+--  Copyright (C) 2010 Bernhard Urban <lewurm@gmail.com>
+--
+--  This program is free software: you can redistribute it and/or modify
+--  it under the terms of the GNU General Public License as published by
+--  the Free Software Foundation, either version 3 of the License, or
+--  (at your option) any later version.
+--
+--  This program is distributed in the hope that it will be useful,
+--  but WITHOUT ANY WARRANTY; without even the implied warranty of
+--  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+--  GNU General Public License for more details.
+--
+--  You should have received a copy of the GNU General Public License
+--  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
 library IEEE;
 
 use IEEE.std_logic_1164.all;
 use IEEE.numeric_std.all;
 
 package common_pkg is
+
+
        
-       constant WORD_WIDTH  : INTEGER := 32;
-       constant BYTE_WIDTH  : INTEGER :=  8;
+       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;
+
+       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 gp_register_t is word_t;
+       
+       subtype byte_en_t is std_logic_vector((gp_register_t'length/byte_t'length-1) downto 0); 
+       
+       constant REG_ZERO : gp_register_t := (others => '0');
 
        constant INSTR_ADDR_WIDTH       : INTEGER := 32;
-       constant PHYS_INSTR_ADDR_WIDTH  : INTEGER := 11;
+       constant PHYS_INSTR_ADDR_WIDTH  : INTEGER := 10;
+       constant ROM_INSTR_ADDR_WIDTH : INTEGER := 7;
        constant REG_ADDR_WIDTH         : INTEGER := 4;
-       constant DATA_ADDR_WIDTH        : INTEGER := 32;
+       constant DATA_ADDR_WIDTH        : INTEGER := 10;
        constant PHYS_DATA_ADDR_WIDTH   : INTEGER := 32;
+       
+       constant NUM_OP_OPT_WIDTH       : INTEGER := 6;
+       constant COND_WIDTH : INTEGER := 4;
+       constant DATA_END_ADDR          : integer := ((2**DATA_ADDR_WIDTH)-1);
 
+       constant ROM_USE : std_logic := '1';
+       constant RAM_USE : std_logic := '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 instr_addr_t is instruction_addr_t;
        
-       subtype gp_register_t is std_logic_vector(WORD_WIDTH-1 downto 0);
-
+       subtype gp_addr_t       is std_logic_vector(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_vecotr(DATA_ADDR_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);
+       subtype condition_t is std_logic_vector(COND_WIDTH-1 downto 0);
+       
+       --Opcode consits of decoded group information type and option bits
+       --currently not complete, might need option increase too.
+       --IMMEDIATE always in right_operand (src2)
+       
+       constant IMM_OPT : integer := 0; -- no sharing
+       
+       constant SUB_OPT : integer := 1;
+       constant ARITH_OPT : integer := 1;
+       constant HWORD_OPT : integer := 1;
+       constant PUSH_OPT : integer := 1;
+       constant LOW_HIGH_OPT : integer := 1;
+       constant DIRECT_JUMP_OPT : integer := 1;
+       
+       constant CARRY_OPT : integer := 2;
+       constant BYTE_OPT : integer := 2;
+       constant LDI_REPLACE_OPT : integer := 2;
+       constant PWREN_OPT : integer := 2;
+
+       constant RIGHT_OPT : integer := 3;
+       constant JMP_REG_OPT : integer := 3;
+       constant ST_OPT  : integer := 3; -- store opt
+       constant RET_OPT : integer := 3;
+       
+       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, LDST_OP, JMP_OP, JMP_ST_OP, STACK_OP);
+       subtype op_opt_t is std_logic_vector(NUM_OP_OPT_WIDTH-1 downto 0);
+
+       type interrupt_t is (IDLE, UART);       
+       
+       constant UART_INT_EN_BIT : integer := 1;
+       constant GLOBAL_INT_EN_BIT : integer := 0;
+
+       constant UART_INT_VECTOR : std_logic_vector(PHYS_INSTR_ADDR_WIDTH-1 downto 0) := (0 => '1', others => '0');
+
+       type instruction_rec is record
+
+               predicates : std_logic_vector(3 downto 0);
+
+               opcode : opcode_t;
+
+               reg_dest_addr : std_logic_vector(REG_ADDR_WIDTH-1 downto 0);
+               reg_src1_addr : std_logic_vector(REG_ADDR_WIDTH-1 downto 0);
+               reg_src2_addr : std_logic_vector(REG_ADDR_WIDTH-1 downto 0);
+
+               immediate : std_logic_vector(WORD_WIDTH-1 downto 0);
+
+               displacement : gp_register_t;
+
+               jmptype : std_logic_vector(1 downto 0);
+
+               high_low, fill, signext, bp, int: std_logic;
+
+               op_detail : op_opt_t;
+               op_group : op_info_t;
+
+       end record;
+
+
        
+       type read_through_write_rec is record
+
+               rtw_reg : gp_register_t;
+               rtw_reg1 : std_logic;
+               rtw_reg2 : std_logic;
+               immediate : gp_register_t;
+               imm_set : std_logic;
+               reg1_addr : gp_addr_t;
+               reg2_addr : gp_addr_t;
+
+       end record;
+
+       type dec_op is record
+               condition : condition_t;
+               op_group : op_info_t;
+               op_detail : op_opt_t;
+               brpr : std_logic;
+
+               displacement : gp_register_t;
+               prog_cnt     : instr_addr_t;
+               
+               src1 : gp_register_t;
+               src2 : gp_register_t;
+               
+               saddr1 : gp_addr_t;
+               saddr2 : gp_addr_t;
+               
+               daddr   : gp_addr_t;
+               
+       end record;
+
+       type writeback_rec is record
+--             result : in gp_register_t;      --reg  (alu result or jumpaddr)
+--             result_addr : in gp_addr_t;     --reg
+               address : word_t;               --ureg 
+--             alu_jmp : in std_logic;         --reg
+--             br_pred : in std_logic;         --reg
+--             write_en : in std_logic;        --reg  (register file)
+               dmem_en : std_logic;            --ureg (jump addr in mem or in address)
+               dmem_write_en : std_logic;      --ureg
+               hword : std_logic;              --ureg
+               byte_s : std_logic;
+               byte_en : byte_en_t;
+               data : gp_register_t;
+       end record;
+       
+       type exec2wb_rec is record
+                       result : gp_register_t; --reg  (alu result or jumpaddr)
+                       result_addr : gp_addr_t;        --reg
+                       address : word_t;               --ureg 
+                       ram_data : word_t;              --ureg
+                       alu_jmp : std_logic;            --reg
+                       br_pred : std_logic;            --reg
+                       write_en : std_logic;   --reg  (register file) bei jump 1 wenn addr in result
+                       dmem_en : std_logic;            --ureg (jump addr in mem or in address)
+                       dmem_write_en : std_logic;      --ureg
+                       hword : std_logic;              --ureg
+                       byte_s : std_logic;             --ureg  
+       end record;
+       
+       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 is
+
+       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;