-- `Deep Thought', a softcore CPU implemented on a FPGA -- -- Copyright (C) 2010 Markus Hofstaetter -- Copyright (C) 2010 Martin Perner -- Copyright (C) 2010 Stefan Rebernig -- Copyright (C) 2010 Manfred Schwarz -- Copyright (C) 2010 Bernhard Urban -- -- 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 . library IEEE; use IEEE.std_logic_1164.all; 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; 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 := 10; constant ROM_INSTR_ADDR_WIDTH : INTEGER := 7; constant REG_ADDR_WIDTH : INTEGER := 4; 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_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_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;