copyleft: gplv3 added and set repo to public
[calu.git] / cpu / src / common_pkg.vhd
1 --   `Deep Thought', a softcore CPU implemented on a FPGA
2 --
3 --  Copyright (C) 2010 Markus Hofstaetter <markus.manrow@gmx.at>
4 --  Copyright (C) 2010 Martin Perner <e0725782@student.tuwien.ac.at>
5 --  Copyright (C) 2010 Stefan Rebernig <stefan.rebernig@gmail.com>
6 --  Copyright (C) 2010 Manfred Schwarz <e0725898@student.tuwien.ac.at>
7 --  Copyright (C) 2010 Bernhard Urban <lewurm@gmail.com>
8 --
9 --  This program is free software: you can redistribute it and/or modify
10 --  it under the terms of the GNU General Public License as published by
11 --  the Free Software Foundation, either version 3 of the License, or
12 --  (at your option) any later version.
13 --
14 --  This program is distributed in the hope that it will be useful,
15 --  but WITHOUT ANY WARRANTY; without even the implied warranty of
16 --  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17 --  GNU General Public License for more details.
18 --
19 --  You should have received a copy of the GNU General Public License
20 --  along with this program.  If not, see <http://www.gnu.org/licenses/>.
21
22 library IEEE;
23
24 use IEEE.std_logic_1164.all;
25 use IEEE.numeric_std.all;
26
27 package common_pkg is
28
29
30         
31         constant WORD_WIDTH   : INTEGER := 32;
32         constant HWORD_WIDTH  : INTEGER := 16;
33         constant BYTE_WIDTH   : INTEGER :=  8;
34         constant OPCODE_WIDTH : INTEGER :=  5;
35         constant DISPL_WIDTH  : INTEGER := 15;
36
37         subtype byte_t is std_logic_vector(BYTE_WIDTH-1 downto 0);
38         subtype hword_t is std_logic_vector(HWORD_WIDTH-1 downto 0);
39         subtype word_t  is std_logic_vector(WORD_WIDTH-1 downto 0);
40
41         subtype gp_register_t is word_t;
42         
43         subtype byte_en_t is std_logic_vector((gp_register_t'length/byte_t'length-1) downto 0); 
44         
45         constant REG_ZERO : gp_register_t := (others => '0');
46
47         constant INSTR_ADDR_WIDTH       : INTEGER := 32;
48         constant PHYS_INSTR_ADDR_WIDTH  : INTEGER := 10;
49         constant ROM_INSTR_ADDR_WIDTH : INTEGER := 7;
50         constant REG_ADDR_WIDTH         : INTEGER := 4;
51         constant DATA_ADDR_WIDTH        : INTEGER := 10;
52         constant PHYS_DATA_ADDR_WIDTH   : INTEGER := 32;
53         
54         constant NUM_OP_OPT_WIDTH       : INTEGER := 6;
55         constant COND_WIDTH : INTEGER := 4;
56         constant DATA_END_ADDR          : integer := ((2**DATA_ADDR_WIDTH)-1);
57
58         constant ROM_USE : std_logic := '1';
59         constant RAM_USE : std_logic := '0';
60         
61         subtype instruction_word_t is std_logic_vector(WORD_WIDTH-1 downto 0);
62         subtype instruction_addr_t is std_logic_vector(INSTR_ADDR_WIDTH-1 downto 0);
63         subtype instr_addr_t is instruction_addr_t;
64         
65         subtype gp_addr_t       is std_logic_vector(REG_ADDR_WIDTH-1 downto 0);
66         subtype data_ram_word_t is std_logic_vector(WORD_WIDTH-1 downto 0);
67         subtype data_ram_addr_t is std_logic_vector(DATA_ADDR_WIDTH-1 downto 0);
68
69         subtype opcode_t is std_logic_vector(OPCODE_WIDTH-1 downto 0);
70         subtype condition_t is std_logic_vector(COND_WIDTH-1 downto 0);
71         
72         --Opcode consits of decoded group information type and option bits
73         --currently not complete, might need option increase too.
74         --IMMEDIATE always in right_operand (src2)
75         
76         constant IMM_OPT : integer := 0; -- no sharing
77         
78         constant SUB_OPT : integer := 1;
79         constant ARITH_OPT : integer := 1;
80         constant HWORD_OPT : integer := 1;
81         constant PUSH_OPT : integer := 1;
82         constant LOW_HIGH_OPT : integer := 1;
83         constant DIRECT_JUMP_OPT : integer := 1;
84         
85         constant CARRY_OPT : integer := 2;
86         constant BYTE_OPT : integer := 2;
87         constant LDI_REPLACE_OPT : integer := 2;
88         constant PWREN_OPT : integer := 2;
89
90         constant RIGHT_OPT : integer := 3;
91         constant JMP_REG_OPT : integer := 3;
92         constant ST_OPT  : integer := 3; -- store opt
93         constant RET_OPT : integer := 3;
94         
95         constant NO_PSW_OPT : integer := 4;--no sharing
96         constant NO_DST_OPT : integer := 5; --no sharing
97         
98         type op_info_t is (ADDSUB_OP,AND_OP,OR_OP, XOR_OP,SHIFT_OP, LDST_OP, JMP_OP, JMP_ST_OP, STACK_OP);
99         subtype op_opt_t is std_logic_vector(NUM_OP_OPT_WIDTH-1 downto 0);
100
101         type interrupt_t is (IDLE, UART);       
102         
103         constant UART_INT_EN_BIT : integer := 1;
104         constant GLOBAL_INT_EN_BIT : integer := 0;
105
106         constant UART_INT_VECTOR : std_logic_vector(PHYS_INSTR_ADDR_WIDTH-1 downto 0) := (0 => '1', others => '0');
107
108         type instruction_rec is record
109
110                 predicates : std_logic_vector(3 downto 0);
111
112                 opcode : opcode_t;
113
114                 reg_dest_addr : std_logic_vector(REG_ADDR_WIDTH-1 downto 0);
115                 reg_src1_addr : std_logic_vector(REG_ADDR_WIDTH-1 downto 0);
116                 reg_src2_addr : std_logic_vector(REG_ADDR_WIDTH-1 downto 0);
117
118                 immediate : std_logic_vector(WORD_WIDTH-1 downto 0);
119
120                 displacement : gp_register_t;
121
122                 jmptype : std_logic_vector(1 downto 0);
123
124                 high_low, fill, signext, bp, int: std_logic;
125
126                 op_detail : op_opt_t;
127                 op_group : op_info_t;
128
129         end record;
130
131
132         
133         type read_through_write_rec is record
134
135                 rtw_reg : gp_register_t;
136                 rtw_reg1 : std_logic;
137                 rtw_reg2 : std_logic;
138                 immediate : gp_register_t;
139                 imm_set : std_logic;
140                 reg1_addr : gp_addr_t;
141                 reg2_addr : gp_addr_t;
142
143         end record;
144
145         type dec_op is record
146                 condition : condition_t;
147                 op_group : op_info_t;
148                 op_detail : op_opt_t;
149                 brpr : std_logic;
150
151                 displacement : gp_register_t;
152                 prog_cnt     : instr_addr_t;
153                 
154                 src1 : gp_register_t;
155                 src2 : gp_register_t;
156                 
157                 saddr1 : gp_addr_t;
158                 saddr2 : gp_addr_t;
159                 
160                 daddr   : gp_addr_t;
161                 
162         end record;
163
164         type writeback_rec is record
165 --              result : in gp_register_t;      --reg  (alu result or jumpaddr)
166 --              result_addr : in gp_addr_t;     --reg
167                 address : word_t;               --ureg 
168 --              alu_jmp : in std_logic;         --reg
169 --              br_pred : in std_logic;         --reg
170 --              write_en : in std_logic;        --reg  (register file)
171                 dmem_en : std_logic;            --ureg (jump addr in mem or in address)
172                 dmem_write_en : std_logic;      --ureg
173                 hword : std_logic;              --ureg
174                 byte_s : std_logic;
175                 byte_en : byte_en_t;
176                 data : gp_register_t;
177         end record;
178         
179         type exec2wb_rec is record
180                         result : gp_register_t; --reg  (alu result or jumpaddr)
181                         result_addr : gp_addr_t;        --reg
182                         address : word_t;               --ureg 
183                         ram_data : word_t;              --ureg
184                         alu_jmp : std_logic;            --reg
185                         br_pred : std_logic;            --reg
186                         write_en : std_logic;   --reg  (register file) bei jump 1 wenn addr in result
187                         dmem_en : std_logic;            --ureg (jump addr in mem or in address)
188                         dmem_write_en : std_logic;      --ureg
189                         hword : std_logic;              --ureg
190                         byte_s : std_logic;             --ureg  
191         end record;
192         
193         function inc(value : in std_logic_vector; constant by : in integer := 1) return std_logic_vector;
194         function log2c(constant value : in integer range 0 to integer'high) return integer;
195 end package common_pkg;
196
197 package body common_pkg is
198
199         function inc(value : in std_logic_vector; constant by : in integer := 1) return std_logic_vector is
200         begin
201                 return std_logic_vector(UNSIGNED(value)+by);
202         end function inc;
203         
204         function log2c(constant value : in integer range 0 to integer'high) return integer is
205                 variable ret_value : integer;
206                 variable cur_value : integer;
207         begin
208                 ret_value := 0;
209                 cur_value := 1;
210                 
211                 while cur_value < value loop
212                         ret_value := ret_value + 1;
213                         cur_value := cur_value * 2;
214                 end loop;
215                 return ret_value;
216         end function log2c;
217         
218 end package body common_pkg;