OpenCores
URL https://opencores.org/ocsvn/minimips/minimips/trunk

Subversion Repositories minimips

[/] [minimips/] [trunk/] [miniMIPS/] [src/] [pps_di.vhd] - Blame information for rev 2

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 poppy
------------------------------------------------------------------------------------
2
--                                                                                --
3
--    Copyright (c) 2004, Hangouet Samuel                                         --
4
--                  , Jan Sebastien                                               --
5
--                  , Mouton Louis-Marie                                          --
6
--                  , Schneider Olivier     all rights reserved                   --
7
--                                                                                --
8
--    This file is part of miniMIPS.                                              --
9
--                                                                                --
10
--    miniMIPS is free software; you can redistribute it and/or modify            --
11
--    it under the terms of the GNU General Public License as published by        --
12
--    the Free Software Foundation; either version 2 of the License, or           --
13
--    (at your option) any later version.                                         --
14
--                                                                                --
15
--    miniMIPS is distributed in the hope that it will be useful,                 --
16
--    but WITHOUT ANY WARRANTY; without even the implied warranty of              --
17
--    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the               --
18
--    GNU General Public License for more details.                                --
19
--                                                                                --
20
--    You should have received a copy of the GNU General Public License           --
21
--    along with miniMIPS; if not, write to the Free Software                     --
22
--    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA   --
23
--                                                                                --
24
------------------------------------------------------------------------------------
25
 
26
 
27
-- If you encountered any problem, please contact :
28
--
29
--   lmouton@enserg.fr
30
--   oschneid@enserg.fr
31
--   shangoue@enserg.fr
32
--
33
 
34
 
35
 
36
--------------------------------------------------------------------------
37
--                                                                      --
38
--                                                                      --
39
--        Processor miniMIPS : Instruction decoding stage               --
40
--                                                                      --
41
--                                                                      --
42
--                                                                      --
43
-- Authors : Hangouet  Samuel                                           --
44
--           Jan       Sébastien                                        --
45
--           Mouton    Louis-Marie                                      --
46
--           Schneider Olivier                                          --
47
--                                                                      --
48
--                                                          june 2003   --
49
--------------------------------------------------------------------------
50
 
51
library IEEE;
52
use IEEE.std_logic_1164.all;
53
use IEEE.numeric_std.all;
54
 
55
library work;
56
use work.pack_mips.all;
57
 
58
entity pps_di is
59
port (
60
    clock : in std_logic;
61
    reset : in std_logic;
62
    stop_all : in std_logic;            -- Unconditionnal locking of the outputs
63
    clear : in std_logic;               -- Clear the pipeline stage (nop in the outputs)
64
 
65
    -- Asynchronous outputs
66
    bra_detect : out std_logic;         -- Branch detection in the current instruction
67
 
68
    -- Asynchronous connexion with the register management and data bypass unit
69
    adr_reg1 : out adr_reg_type;        -- Address of the first register operand
70
    adr_reg2 : out adr_reg_type;        -- Address of the second register operand
71
    use1 : out std_logic;               -- Effective use of operand 1
72
    use2 : out std_logic;               -- Effective use of operand 2
73
 
74
    stop_di : in std_logic;             -- Unresolved detected : send nop in the pipeline
75
    data1 : in bus32;                   -- Operand register 1
76
    data2 : in bus32;                   -- Operand register 2
77
 
78
    -- Datas from EI stage
79
    EI_adr : in bus32;                  -- Address of the instruction
80
    EI_instr : in bus32;                -- The instruction to decode
81
    EI_it_ok : in std_logic;            -- Allow hardware interruptions
82
 
83
    -- Synchronous output to EX stage
84
    DI_bra : out std_logic;             -- Branch decoded 
85
    DI_link : out std_logic;            -- A link for that instruction
86
    DI_op1 : out bus32;                 -- operand 1 for alu
87
    DI_op2 : out bus32;                 -- operand 2 for alu
88
    DI_code_ual : out alu_ctrl_type;    -- Alu operation
89
    DI_offset : out bus32;              -- Offset for the address calculation
90
    DI_adr_reg_dest : out adr_reg_type; -- Address of the destination register of the result
91
    DI_ecr_reg : out std_logic;         -- Effective writing of the result
92
    DI_mode : out std_logic;            -- Address mode (relative to pc or indexed to a register)
93
    DI_op_mem : out std_logic;          -- Memory operation request
94
    DI_r_w : out std_logic;             -- Type of memory operation (reading or writing)
95
    DI_adr : out bus32;                 -- Address of the decoded instruction
96
    DI_exc_cause : out bus32;           -- Potential exception detected
97
    DI_level : out level_type;          -- Availability of the result for the data bypass
98
    DI_it_ok : out std_logic            -- Allow hardware interruptions
99
);
100
end entity;
101
 
102
 
103
architecture rtl of pps_di is
104
 
105
    -- Enumeration type used for the micro-code of the instruction
106
    type op_mode_type is (OP_NORMAL, OP_SPECIAL, OP_REGIMM, OP_COP0);   -- selection du mode de l'instruction
107
    type off_sel_type is (OFS_PCRL, OFS_NULL, OFS_SESH, OFS_SEXT);      -- selection de la valeur de l'offset
108
    type rdest_type is ( D_RT, D_RD, D_31, D_00);                       -- selection du registre destination
109
 
110
    -- Record type containg the micro-code of an instruction
111
    type micro_instr_type is
112
    record
113
        op_mode : op_mode_type;    -- Instruction codop mode
114
        op_code : bus6;            -- Instruction codop
115
        bra : std_logic;           -- Branch instruction
116
        link : std_logic;          -- Branch with link : the return address is saved in a register
117
        code_ual : alu_ctrl_type;  -- Operation code for the alu
118
        op_mem : std_logic;        -- Memory operation needed
119
        r_w : std_logic;           -- Read/Write selection in memory
120
        mode : std_logic;          -- Address calculation from the current pc ('1') or the alu operand 1 ('0')
121
        off_sel : off_sel_type;    -- Offset source : PC(31..28) & Adresse & 00 || 0 || sgn_ext(Imm) & 00 || sgn_ext(Imm)
122
        exc_cause : bus32;         -- Unconditionnal exception cause to generate
123
        cop_org1 : std_logic;      -- Source register 1 : general register if 0, coprocessor register if 1
124
        cop_org2 : std_logic;      -- Source register 2 : general register if 0, coprocessor register if 1
125
        cs_imm1 : std_logic;       -- Use of immediat operand 1 instead of register bank
126
        cs_imm2 : std_logic;       -- Use of immediat operand 2 instead of register bank
127
        imm1_sel : std_logic;      -- Origine of immediat operand 1
128
        imm2_sel : std_logic;      -- Origine of immediat operand 2
129
        level : level_type;        -- Data availability stage for the bypass
130
        ecr_reg : std_logic;       -- Writing the result in a register
131
        bank_des : std_logic;      -- Register bank selection : GPR if 0, coprocessor system if 1
132
        des_sel : rdest_type ;     -- Destination register address : Rt, Rd, $31, $0
133
    end record;
134
 
135
    type micro_code_type is array (natural range <>) of micro_instr_type;
136
 
137
    constant micro_code : micro_code_type :=
138
( -- Instruction decoding in micro-instructions table
139
(OP_SPECIAL, "100000", '0', '0', OP_ADD  , '0', '0', '0', OFS_PCRL, IT_NOEXC, '0', '0', '0', '0', '0', '0', LVL_EX , '1', '0', D_RD), -- ADD
140
(OP_NORMAL , "001000", '0', '0', OP_ADD  , '0', '0', '0', OFS_PCRL, IT_NOEXC, '0', '0', '0', '1', '0', '1', LVL_EX , '1', '0', D_RT), -- ADDI
141
(OP_NORMAL , "001001", '0', '0', OP_ADDU , '0', '0', '0', OFS_PCRL, IT_NOEXC, '0', '0', '0', '1', '0', '0', LVL_EX , '1', '0', D_RT), -- ADDIU
142
(OP_SPECIAL, "100001", '0', '0', OP_ADDU , '0', '0', '0', OFS_PCRL, IT_NOEXC, '0', '0', '0', '0', '0', '0', LVL_EX , '1', '0', D_RD), -- ADDU
143
(OP_SPECIAL, "100100", '0', '0', OP_AND  , '0', '0', '0', OFS_PCRL, IT_NOEXC, '0', '0', '0', '0', '0', '0', LVL_EX , '1', '0', D_RD), -- AND
144
(OP_NORMAL , "001100", '0', '0', OP_AND  , '0', '0', '0', OFS_PCRL, IT_NOEXC, '0', '0', '0', '1', '0', '0', LVL_EX , '1', '0', D_RT), -- ANDI
145
(OP_NORMAL , "000100", '1', '0', OP_EQU  , '0', '0', '1', OFS_SESH, IT_NOEXC, '0', '0', '0', '0', '0', '0', LVL_DI , '0', '0', D_RT), -- BEQ
146
(OP_REGIMM , "000001", '1', '0', OP_LPOS , '0', '0', '1', OFS_SESH, IT_NOEXC, '0', '0', '0', '1', '0', '0', LVL_DI , '0', '0', D_RT), -- BGEZ
147
(OP_REGIMM , "010001", '1', '1', OP_LPOS , '0', '0', '1', OFS_SESH, IT_NOEXC, '0', '0', '0', '1', '0', '0', LVL_EX , '1', '0', D_31), -- BGEZAL
148
(OP_NORMAL , "000111", '1', '0', OP_SPOS , '0', '0', '1', OFS_SESH, IT_NOEXC, '0', '0', '0', '1', '0', '0', LVL_DI , '0', '0', D_RT), -- BGTZ
149
(OP_NORMAL , "000110", '1', '0', OP_LNEG , '0', '0', '1', OFS_SESH, IT_NOEXC, '0', '0', '0', '1', '0', '0', LVL_DI , '0', '0', D_RT), -- BLEZ
150
(OP_REGIMM , "000000", '1', '0', OP_SNEG , '0', '0', '1', OFS_SESH, IT_NOEXC, '0', '0', '0', '1', '0', '0', LVL_DI , '0', '0', D_RT), -- BLTZ
151
(OP_REGIMM , "010000", '1', '1', OP_SNEG , '0', '0', '1', OFS_SESH, IT_NOEXC, '0', '0', '0', '1', '0', '0', LVL_EX , '1', '0', D_31), -- BLTZAL
152
(OP_NORMAL , "000101", '1', '0', OP_NEQU , '0', '0', '1', OFS_SESH, IT_NOEXC, '0', '0', '0', '0', '0', '0', LVL_DI , '0', '0', D_RT), -- BNE
153
(OP_SPECIAL, "001101", '0', '0', OP_OUI  , '0', '0', '0', OFS_PCRL, IT_BREAK, '0', '0', '1', '1', '0', '0', LVL_DI , '0', '0', D_RT), -- BREAK
154
(OP_COP0   , "000001", '0', '0', OP_OP2  , '0', '0', '0', OFS_PCRL, IT_NOEXC, '0', '0', '1', '1', '0', '0', LVL_DI , '1', '1', D_00), -- COP0
155
(OP_NORMAL , "000010", '1', '0', OP_OUI  , '0', '0', '0', OFS_PCRL, IT_NOEXC, '0', '0', '1', '1', '0', '0', LVL_DI , '0', '0', D_RT), -- J
156
(OP_NORMAL , "000011", '1', '1', OP_OUI  , '0', '0', '0', OFS_PCRL, IT_NOEXC, '0', '0', '1', '1', '0', '0', LVL_EX , '1', '0', D_31), -- JAL
157
(OP_SPECIAL, "001001", '1', '1', OP_OUI  , '0', '0', '0', OFS_NULL, IT_NOEXC, '0', '0', '0', '1', '0', '0', LVL_EX , '1', '0', D_RD), -- JALR
158
(OP_SPECIAL, "001000", '1', '0', OP_OUI  , '0', '0', '0', OFS_NULL, IT_NOEXC, '0', '0', '0', '1', '0', '0', LVL_DI , '0', '0', D_RT), -- JR
159
(OP_NORMAL , "001111", '0', '0', OP_LUI  , '0', '0', '0', OFS_PCRL, IT_NOEXC, '0', '0', '1', '1', '0', '0', LVL_EX , '1', '0', D_RT), -- LUI
160
(OP_NORMAL , "100011", '0', '0', OP_OUI  , '1', '0', '0', OFS_SEXT, IT_NOEXC, '0', '0', '0', '1', '0', '0', LVL_MEM, '1', '0', D_RT), -- LW
161
(OP_NORMAL , "110000", '0', '0', OP_OUI  , '1', '0', '0', OFS_SEXT, IT_NOEXC, '0', '0', '0', '1', '0', '0', LVL_MEM, '1', '1', D_RT), -- LWC0
162
(OP_COP0   , "000000", '0', '0', OP_OP2    , '0', '0', '0', OFS_PCRL, IT_NOEXC, '0', '1', '1', '0', '0', '0', LVL_DI , '1', '0', D_RD), -- MFC0
163
(OP_SPECIAL, "010000", '0', '0', OP_MFHI , '0', '0', '0', OFS_PCRL, IT_NOEXC, '0', '0', '1', '1', '0', '0', LVL_EX , '1', '0', D_RD), -- MFHI
164
(OP_SPECIAL, "010010", '0', '0', OP_MFLO , '0', '0', '0', OFS_PCRL, IT_NOEXC, '0', '0', '1', '1', '0', '0', LVL_EX , '1', '0', D_RD), -- MFLO
165
(OP_COP0   , "000100", '0', '0', OP_OP2  , '0', '0', '0', OFS_PCRL, IT_NOEXC, '0', '0', '1', '0', '0', '0', LVL_DI , '1', '1', D_RD), -- MTC0
166
(OP_SPECIAL, "010001", '0', '0', OP_MTHI , '0', '0', '0', OFS_PCRL, IT_NOEXC, '0', '0', '0', '1', '0', '0', LVL_DI , '0', '0', D_RT), -- MTHI
167
(OP_SPECIAL, "010011", '0', '0', OP_MTLO , '0', '0', '0', OFS_PCRL, IT_NOEXC, '0', '0', '0', '1', '0', '0', LVL_DI , '0', '0', D_RT), -- MTLO
168
(OP_SPECIAL, "011000", '0', '0', OP_MULT , '0', '0', '0', OFS_PCRL, IT_NOEXC, '0', '0', '0', '0', '0', '0', LVL_EX , '0', '0', D_RT), -- MULT
169
(OP_SPECIAL, "011001", '0', '0', OP_MULTU, '0', '0', '0', OFS_PCRL, IT_NOEXC, '0', '0', '0', '0', '0', '0', LVL_EX , '0', '0', D_RT), -- MULT
170
(OP_SPECIAL, "100111", '0', '0', OP_NOR  , '0', '0', '0', OFS_PCRL, IT_NOEXC, '0', '0', '0', '0', '0', '0', LVL_EX , '1', '0', D_RD), -- NOR
171
(OP_SPECIAL, "100101", '0', '0', OP_OR   , '0', '0', '0', OFS_PCRL, IT_NOEXC, '0', '0', '0', '0', '0', '0', LVL_EX , '1', '0', D_RD), -- OR
172
(OP_NORMAL , "001101", '0', '0', OP_OR   , '0', '0', '0', OFS_PCRL, IT_NOEXC, '0', '0', '0', '1', '0', '0', LVL_EX , '1', '0', D_RT), -- ORI
173
(OP_SPECIAL, "000000", '0', '0', OP_SLL  , '0', '0', '0', OFS_PCRL, IT_NOEXC, '0', '0', '1', '0', '1', '0', LVL_EX , '1', '0', D_RD), -- SLL
174
(OP_SPECIAL, "000100", '0', '0', OP_SLL  , '0', '0', '0', OFS_PCRL, IT_NOEXC, '0', '0', '0', '0', '0', '0', LVL_EX , '1', '0', D_RD), -- SLLV
175
(OP_SPECIAL, "101010", '0', '0', OP_SLT  , '0', '0', '0', OFS_PCRL, IT_NOEXC, '0', '0', '0', '0', '0', '0', LVL_EX , '1', '0', D_RD), -- SLT
176
(OP_NORMAL , "001010", '0', '0', OP_SLT  , '0', '0', '0', OFS_PCRL, IT_NOEXC, '0', '0', '0', '1', '0', '1', LVL_EX , '1', '0', D_RT), -- SLTI
177
(OP_NORMAL , "001011", '0', '0', OP_SLTU , '0', '0', '0', OFS_PCRL, IT_NOEXC, '0', '0', '0', '1', '0', '1', LVL_EX , '1', '0', D_RT), -- SLTIU
178
(OP_SPECIAL, "101011", '0', '0', OP_SLTU , '0', '0', '0', OFS_PCRL, IT_NOEXC, '0', '0', '0', '0', '0', '0', LVL_EX , '1', '0', D_RD), -- SLTU
179
(OP_SPECIAL, "000011", '0', '0', OP_SRA  , '0', '0', '0', OFS_PCRL, IT_NOEXC, '0', '0', '1', '0', '1', '0', LVL_EX , '1', '0', D_RD), -- SRA
180
(OP_SPECIAL, "000111", '0', '0', OP_SRA  , '0', '0', '0', OFS_PCRL, IT_NOEXC, '0', '0', '0', '0', '0', '0', LVL_EX , '1', '0', D_RD), -- SRAV
181
(OP_SPECIAL, "000010", '0', '0', OP_SRL  , '0', '0', '0', OFS_PCRL, IT_NOEXC, '0', '0', '1', '0', '1', '0', LVL_EX , '1', '0', D_RD), -- SRL
182
(OP_SPECIAL, "000110", '0', '0', OP_SRL  , '0', '0', '0', OFS_PCRL, IT_NOEXC, '0', '0', '0', '0', '0', '0', LVL_EX , '1', '0', D_RD), -- SRLV
183
(OP_SPECIAL, "100010", '0', '0', OP_SUB  , '0', '0', '0', OFS_PCRL, IT_NOEXC, '0', '0', '0', '0', '0', '0', LVL_EX , '1', '0', D_RD), -- SUB
184
(OP_SPECIAL, "100011", '0', '0', OP_SUBU , '0', '0', '0', OFS_PCRL, IT_NOEXC, '0', '0', '0', '0', '0', '0', LVL_EX , '1', '0', D_RD), -- SUBU
185
(OP_NORMAL , "101011", '0', '0', OP_OP2  , '1', '1', '0', OFS_SEXT, IT_NOEXC, '0', '0', '0', '0', '0', '0', LVL_DI , '0', '0', D_RT), -- SW
186
(OP_NORMAL , "111000", '0', '0', OP_OP2  , '1', '1', '0', OFS_SEXT, IT_NOEXC, '0', '1', '0', '0', '0', '0', LVL_DI , '0', '0', D_RT), -- SWC0
187
(OP_SPECIAL, "001100", '0', '0', OP_OUI  , '0', '0', '0', OFS_PCRL, IT_SCALL, '0', '0', '1', '1', '0', '0', LVL_DI , '0', '0', D_RT), -- SYSC
188
(OP_SPECIAL, "100110", '0', '0', OP_XOR  , '0', '0', '0', OFS_PCRL, IT_NOEXC, '0', '0', '0', '0', '0', '0', LVL_EX , '1', '0', D_RD), -- XOR
189
(OP_NORMAL , "001110", '0', '0', OP_XOR  , '0', '0', '0', OFS_PCRL, IT_NOEXC, '0', '0', '0', '1', '0', '0', LVL_EX , '1', '0', D_RT)  -- XORI
190
);
191
 
192
    -- Preparation of the synchronous outputs
193
    signal PRE_bra : std_logic;             -- Branch operation
194
    signal PRE_link : std_logic;            -- Branch with link
195
    signal PRE_op1 : bus32;                 -- operand 1 of the ual
196
    signal PRE_op2 : bus32;                 -- operand 2 of the ual
197
    signal PRE_code_ual : alu_ctrl_type;    -- Alu operation
198
    signal PRE_offset : bus32;              -- Address offset for calculation
199
    signal PRE_adr_reg_dest : adr_reg_type; -- Destination register adress for result
200
    signal PRE_ecr_reg : std_logic;         -- Writing of result in the bank register
201
    signal PRE_mode : std_logic;            -- Address calculation with current pc
202
    signal PRE_op_mem : std_logic;          -- Memory access operation instruction 
203
    signal PRE_r_w : std_logic;             -- Read/write selection in memory
204
    signal PRE_exc_cause : bus32;           -- Potential exception cause
205
    signal PRE_level : level_type;          -- Result availability stage for bypass
206
 
207
begin
208
 
209
 
210
    -- Instruction decoding
211
    process (EI_instr, EI_adr, data1, data2)
212
        variable op_code : bus6;             -- Effective codop of the instruction
213
        variable op_mode : op_mode_type;     -- Instruction mode
214
        variable flag : boolean;             -- Is true if valid instruction
215
        variable instr : integer;            -- Current micro-instruction adress
216
 
217
        -- Instruction fields
218
        variable rs : bus5;
219
        variable rt : bus5;
220
        variable rd : bus5;
221
        variable shamt : bus5;
222
        variable imm : bus16;
223
        variable address : bus26;
224
    begin
225
 
226
        -- Selection of the instruction codop and its mode
227
        case EI_instr(31 downto 26) is
228
            when "000000" => -- special mode 
229
                op_mode := OP_SPECIAL;
230
                op_code := EI_instr(5 downto 0);
231
            when "000001" => -- regimm mode
232
                op_mode := OP_REGIMM;
233
                op_code := '0' & EI_instr(20 downto 16);
234
            when "010000" => -- cop0 mode
235
                op_mode := OP_COP0;
236
                op_code := '0' & EI_instr(25 downto 21);
237
            when others   => -- normal mode
238
                op_mode := OP_NORMAL;
239
                op_code := EI_instr(31 downto 26);
240
        end case;
241
 
242
 
243
        -- Search the current instruction in the micro-code table
244
        flag := false;
245
        instr := 0;
246
        for i in micro_code'range loop
247
            if micro_code(i).op_mode=op_mode and micro_code(i).op_code=op_code then
248
                flag := true;           -- The instruction exists
249
                instr := i;             -- Index memorisation
250
            end if;
251
        end loop;
252
 
253
        -- Read the instruction field
254
        rs      := EI_instr(25 downto 21);
255
        rt      := EI_instr(20 downto 16);
256
        rd      := EI_instr(15 downto 11);
257
        shamt   := EI_instr(10 downto  6);
258
        imm     := EI_instr(15 downto  0);
259
        address := EI_instr(25 downto  0);
260
 
261
        if not flag then -- Unknown instruction
262
 
263
            -- Synchronous output preparation
264
            PRE_bra          <= '0';              -- Branch operation
265
            PRE_link         <= '0';              -- Branch with link
266
            PRE_op1          <= (others => '0');  -- operand 1 of the ual
267
            PRE_op2          <= (others => '0');  -- operand 2 of the ual
268
            PRE_code_ual     <= OP_OUI;           -- Alu operation
269
            PRE_offset       <= (others => '0');  -- Address offset for calculation
270
            PRE_adr_reg_dest <= (others => '0');  -- Destination register adress for result
271
            PRE_ecr_reg      <= '0';              -- Writing of result in the bank register
272
            PRE_mode         <= '0';              -- Address calculation with current pc
273
            PRE_op_mem       <= '0';              -- Memory access operation instruction 
274
            PRE_r_w          <= '0';              -- Read/write selection in memory
275
            PRE_exc_cause    <= IT_ERINS;         -- Potential exception cause
276
            PRE_level        <= LVL_DI;           -- Result availability stage for bypass
277
 
278
            -- Set asynchronous outputs
279
            adr_reg1 <= (others => '0');    -- First operand register
280
            adr_reg2 <= (others => '0');    -- Second operand register
281
            bra_detect <= '0';              -- Detection of a branch in current instruction
282
            use1 <= '0';                    -- Effective use of operand 1
283
            use2 <= '0';                    -- Effective use of operand 2
284
 
285
        else -- Valid instruction
286
 
287
            -- Offset signal preparation
288
            case micro_code(instr).off_sel is
289
                when OFS_PCRL => -- PC(31..28) & Adresse & 00
290
                    PRE_offset <= EI_adr(31 downto 28) & address & "00";
291
                when OFS_NULL => -- 0
292
                    PRE_offset <= (others => '0');
293
                when OFS_SESH => -- sgn_ext(Imm) & 00
294
                    if imm(15)='1' then
295
                        PRE_offset <= "11111111111111" & imm & "00";
296
                    else
297
                        PRE_offset <= "00000000000000" & imm & "00";
298
                    end if;
299
                when OFS_SEXT => -- sgn_ext(Imm)
300
                    if imm(15)='1' then
301
                        PRE_offset <= "1111111111111111" & imm;
302
                    else
303
                        PRE_offset <= "0000000000000000" & imm;
304
                    end if;
305
            end case;
306
 
307
 
308
            -- Alu operand preparation
309
            if micro_code(instr).cs_imm1='0' then
310
                -- Datas from register banks
311
                PRE_op1 <= data1;
312
            else
313
                -- Immediate datas
314
                if micro_code(instr).imm1_sel='0' then
315
                    PRE_op1 <= (others => '0');             -- Immediate operand = 0
316
                else
317
                    PRE_op1 <= X"000000" & "000" & shamt;   -- Immediate operand = shamt
318
                end if;
319
            end if;
320
 
321
 
322
            if micro_code(instr).cs_imm2='0' then
323
                -- Datas from register banks
324
                PRE_op2 <= data2;
325
            else
326
                -- Immediate datas
327
                if micro_code(instr).imm2_sel='0' then
328
                    PRE_op2 <= X"0000" & imm;               -- Immediate operand = imm
329
                else
330
                    if imm(15)='1' then                     -- Immediate operand = sgn_ext(imm)
331
                        PRE_op2 <= X"FFFF" & imm;
332
                    else
333
                        PRE_op2 <= X"0000" & imm;
334
                    end if;
335
                end if;
336
            end if;
337
 
338
            -- Selection of destination register address
339
            case micro_code(instr).des_sel is
340
                when D_RT => PRE_adr_reg_dest <= micro_code(instr).bank_des & rt;
341
                when D_RD => PRE_adr_reg_dest <= micro_code(instr).bank_des & rd;
342
                when D_31 => PRE_adr_reg_dest <= micro_code(instr).bank_des & "11111";
343
                when D_00 => PRE_adr_reg_dest <= micro_code(instr).bank_des & "00000";
344
            end case;
345
 
346
            -- Command signal affectation
347
            PRE_bra       <= micro_code(instr).bra;        -- Branch operation
348
            PRE_link      <= micro_code(instr).link;       -- Branch with link
349
            PRE_code_ual  <= micro_code(instr).code_ual;   -- Alu operation
350
            PRE_ecr_reg   <= micro_code(instr).ecr_reg;    -- Writing the result in a bank register
351
            PRE_mode      <= micro_code(instr).mode;       -- Type of calculation for the address with current pc
352
            PRE_op_mem    <= micro_code(instr).op_mem;     -- Memory operation needed
353
            PRE_r_w       <= micro_code(instr).r_w;        -- Read/Write in memory selection
354
            PRE_exc_cause <= micro_code(instr).exc_cause;  -- Potential cause exception
355
            PRE_level     <= micro_code(instr).level;
356
 
357
            -- Set asynchronous outputs
358
            adr_reg1 <= micro_code(instr).cop_org1 & rs; -- First operand register address
359
            adr_reg2 <= micro_code(instr).cop_org2 & rt; -- Second operand register address
360
            bra_detect <= micro_code(instr).bra;         -- Branch detection in current instruction
361
            use1 <= not micro_code(instr).cs_imm1;       -- Effective use of operande 1
362
            use2 <= not micro_code(instr).cs_imm2;       -- Effective use of operande 2
363
        end if;
364
 
365
    end process;
366
 
367
 
368
 
369
    -- Set the synchronous outputs
370
    process (clock)
371
    begin
372
        if clock='1' and clock'event then
373
            if reset='1' then
374
                DI_bra <= '0';
375
                DI_link <= '0';
376
                DI_op1 <= (others => '0');
377
                DI_op2 <= (others => '0');
378
                DI_code_ual <= OP_OUI;
379
                DI_offset <= (others => '0');
380
                DI_adr_reg_dest <= (others => '0');
381
                DI_ecr_reg <= '0';
382
                DI_mode <= '0';
383
                DI_op_mem <= '0';
384
                DI_r_w <= '0';
385
                DI_adr <= (others => '0');
386
                DI_exc_cause <= IT_NOEXC;
387
                DI_level <= LVL_DI;
388
                DI_it_ok <= '0';
389
            elsif stop_all='0' then
390
                if clear='1' or stop_di='1' then
391
                    -- Nop instruction
392
                    DI_bra <= '0';
393
                    DI_link <= '0';
394
                    DI_op1 <= (others => '0');
395
                    DI_op2 <= (others => '0');
396
                    DI_code_ual <= OP_OUI;
397
                    DI_offset <= (others => '0');
398
                    DI_adr_reg_dest <= (others => '0');
399
                    DI_ecr_reg <= '0';
400
                    DI_mode <= '0';
401
                    DI_op_mem <= '0';
402
                    DI_r_w <= '0';
403
                    DI_adr <= EI_adr;
404
                    DI_exc_cause <= IT_NOEXC;
405
                    DI_level <= LVL_DI;
406
                    if clear='1' then
407
                      DI_it_ok <= '0';
408
                    else
409
                      DI_it_ok <= EI_it_ok;
410
                    end if;
411
                else -- Noraml step
412
                    DI_bra <= PRE_bra;
413
                    DI_link <= PRE_link;
414
                    DI_op1 <= PRE_op1;
415
                    DI_op2 <= PRE_op2;
416
                    DI_code_ual <= PRE_code_ual;
417
                    DI_offset <= PRE_offset;
418
                    DI_adr_reg_dest <= PRE_adr_reg_dest;
419
                    DI_ecr_reg <= PRE_ecr_reg;
420
                    DI_mode <= PRE_mode;
421
                    DI_op_mem <= PRE_op_mem;
422
                    DI_r_w <= PRE_r_w;
423
                    DI_adr <= EI_adr;
424
                    DI_exc_cause <= PRE_exc_cause;
425
                    DI_level <= PRE_level;
426
                    DI_it_ok <= EI_it_ok;
427
                end if;
428
            end if;
429
        end if;
430
    end process;
431
 
432
end rtl;
433
 
434
 

powered by: WebSVN 2.1.0

© copyright 1999-2025 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.