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

Subversion Repositories minimips

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

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 5 poppy
--    it under the terms of the GNU Lesser General Public License as published by --
12
--    the Free Software Foundation; either version 2.1 of the License, or         --
13 2 poppy
--    (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 5 poppy
--    GNU Lesser General Public License for more details.                         --
19 2 poppy
--                                                                                --
20 5 poppy
--    You should have received a copy of the GNU Lesser General Public License    --
21 2 poppy
--    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 connexion with the register management and data bypass unit
66
    adr_reg1 : out adr_reg_type;        -- Address of the first register operand
67
    adr_reg2 : out adr_reg_type;        -- Address of the second register operand
68
    use1 : out std_logic;               -- Effective use of operand 1
69
    use2 : out std_logic;               -- Effective use of operand 2
70
 
71
    stop_di : in std_logic;             -- Unresolved detected : send nop in the pipeline
72
    data1 : in bus32;                   -- Operand register 1
73
    data2 : in bus32;                   -- Operand register 2
74
 
75
    -- Datas from EI stage
76
    EI_adr : in bus32;                  -- Address of the instruction
77
    EI_instr : in bus32;                -- The instruction to decode
78
    EI_it_ok : in std_logic;            -- Allow hardware interruptions
79
 
80
    -- Synchronous output to EX stage
81
    DI_bra : out std_logic;             -- Branch decoded 
82
    DI_link : out std_logic;            -- A link for that instruction
83
    DI_op1 : out bus32;                 -- operand 1 for alu
84
    DI_op2 : out bus32;                 -- operand 2 for alu
85
    DI_code_ual : out alu_ctrl_type;    -- Alu operation
86
    DI_offset : out bus32;              -- Offset for the address calculation
87
    DI_adr_reg_dest : out adr_reg_type; -- Address of the destination register of the result
88
    DI_ecr_reg : out std_logic;         -- Effective writing of the result
89
    DI_mode : out std_logic;            -- Address mode (relative to pc or indexed to a register)
90
    DI_op_mem : out std_logic;          -- Memory operation request
91
    DI_r_w : out std_logic;             -- Type of memory operation (reading or writing)
92
    DI_adr : out bus32;                 -- Address of the decoded instruction
93
    DI_exc_cause : out bus32;           -- Potential exception detected
94
    DI_level : out level_type;          -- Availability of the result for the data bypass
95
    DI_it_ok : out std_logic            -- Allow hardware interruptions
96
);
97
end entity;
98
 
99
 
100
architecture rtl of pps_di is
101
 
102
    -- Enumeration type used for the micro-code of the instruction
103
    type op_mode_type is (OP_NORMAL, OP_SPECIAL, OP_REGIMM, OP_COP0);   -- selection du mode de l'instruction
104
    type off_sel_type is (OFS_PCRL, OFS_NULL, OFS_SESH, OFS_SEXT);      -- selection de la valeur de l'offset
105
    type rdest_type is ( D_RT, D_RD, D_31, D_00);                       -- selection du registre destination
106
 
107
    -- Record type containg the micro-code of an instruction
108
    type micro_instr_type is
109
    record
110
        op_mode : op_mode_type;    -- Instruction codop mode
111
        op_code : bus6;            -- Instruction codop
112
        bra : std_logic;           -- Branch instruction
113
        link : std_logic;          -- Branch with link : the return address is saved in a register
114
        code_ual : alu_ctrl_type;  -- Operation code for the alu
115
        op_mem : std_logic;        -- Memory operation needed
116
        r_w : std_logic;           -- Read/Write selection in memory
117
        mode : std_logic;          -- Address calculation from the current pc ('1') or the alu operand 1 ('0')
118
        off_sel : off_sel_type;    -- Offset source : PC(31..28) & Adresse & 00 || 0 || sgn_ext(Imm) & 00 || sgn_ext(Imm)
119
        exc_cause : bus32;         -- Unconditionnal exception cause to generate
120
        cop_org1 : std_logic;      -- Source register 1 : general register if 0, coprocessor register if 1
121
        cop_org2 : std_logic;      -- Source register 2 : general register if 0, coprocessor register if 1
122
        cs_imm1 : std_logic;       -- Use of immediat operand 1 instead of register bank
123
        cs_imm2 : std_logic;       -- Use of immediat operand 2 instead of register bank
124
        imm1_sel : std_logic;      -- Origine of immediat operand 1
125
        imm2_sel : std_logic;      -- Origine of immediat operand 2
126
        level : level_type;        -- Data availability stage for the bypass
127
        ecr_reg : std_logic;       -- Writing the result in a register
128
        bank_des : std_logic;      -- Register bank selection : GPR if 0, coprocessor system if 1
129
        des_sel : rdest_type ;     -- Destination register address : Rt, Rd, $31, $0
130
    end record;
131
 
132
    type micro_code_type is array (natural range <>) of micro_instr_type;
133
 
134
    constant micro_code : micro_code_type :=
135
( -- Instruction decoding in micro-instructions table
136
(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
137
(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
138
(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
139
(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
140
(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
141
(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
142
(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
143
(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
144
(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
145
(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
146
(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
147
(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
148
(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
149
(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
150
(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
151
(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
152
(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
153
(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
154
(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
155
(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
156
(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
157
(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
158
(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
159
(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
160
(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
161
(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
162
(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
163
(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
164
(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
165
(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
166
(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
167
(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
168
(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
169
(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
170
(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
171
(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
172
(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
173
(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
174
(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
175
(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
176
(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
177
(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
178
(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
179
(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
180
(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
181
(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
182
(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
183
(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
184
(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
185
(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
186
(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
187
);
188
 
189
    -- Preparation of the synchronous outputs
190
    signal PRE_bra : std_logic;             -- Branch operation
191
    signal PRE_link : std_logic;            -- Branch with link
192
    signal PRE_op1 : bus32;                 -- operand 1 of the ual
193
    signal PRE_op2 : bus32;                 -- operand 2 of the ual
194
    signal PRE_code_ual : alu_ctrl_type;    -- Alu operation
195
    signal PRE_offset : bus32;              -- Address offset for calculation
196
    signal PRE_adr_reg_dest : adr_reg_type; -- Destination register adress for result
197
    signal PRE_ecr_reg : std_logic;         -- Writing of result in the bank register
198
    signal PRE_mode : std_logic;            -- Address calculation with current pc
199
    signal PRE_op_mem : std_logic;          -- Memory access operation instruction 
200
    signal PRE_r_w : std_logic;             -- Read/write selection in memory
201
    signal PRE_exc_cause : bus32;           -- Potential exception cause
202
    signal PRE_level : level_type;          -- Result availability stage for bypass
203
 
204
begin
205
 
206
 
207
    -- Instruction decoding
208
    process (EI_instr, EI_adr, data1, data2)
209
        variable op_code : bus6;             -- Effective codop of the instruction
210
        variable op_mode : op_mode_type;     -- Instruction mode
211
        variable flag : boolean;             -- Is true if valid instruction
212
        variable instr : integer;            -- Current micro-instruction adress
213
 
214
        -- Instruction fields
215
        variable rs : bus5;
216
        variable rt : bus5;
217
        variable rd : bus5;
218
        variable shamt : bus5;
219
        variable imm : bus16;
220
        variable address : bus26;
221
    begin
222
 
223
        -- Selection of the instruction codop and its mode
224
        case EI_instr(31 downto 26) is
225
            when "000000" => -- special mode 
226
                op_mode := OP_SPECIAL;
227
                op_code := EI_instr(5 downto 0);
228
            when "000001" => -- regimm mode
229
                op_mode := OP_REGIMM;
230
                op_code := '0' & EI_instr(20 downto 16);
231
            when "010000" => -- cop0 mode
232
                op_mode := OP_COP0;
233
                op_code := '0' & EI_instr(25 downto 21);
234
            when others   => -- normal mode
235
                op_mode := OP_NORMAL;
236
                op_code := EI_instr(31 downto 26);
237
        end case;
238
 
239
 
240
        -- Search the current instruction in the micro-code table
241
        flag := false;
242
        instr := 0;
243
        for i in micro_code'range loop
244
            if micro_code(i).op_mode=op_mode and micro_code(i).op_code=op_code then
245
                flag := true;           -- The instruction exists
246
                instr := i;             -- Index memorisation
247
            end if;
248
        end loop;
249
 
250
        -- Read the instruction field
251
        rs      := EI_instr(25 downto 21);
252
        rt      := EI_instr(20 downto 16);
253
        rd      := EI_instr(15 downto 11);
254
        shamt   := EI_instr(10 downto  6);
255
        imm     := EI_instr(15 downto  0);
256
        address := EI_instr(25 downto  0);
257
 
258
        if not flag then -- Unknown instruction
259
 
260
            -- Synchronous output preparation
261
            PRE_bra          <= '0';              -- Branch operation
262
            PRE_link         <= '0';              -- Branch with link
263
            PRE_op1          <= (others => '0');  -- operand 1 of the ual
264
            PRE_op2          <= (others => '0');  -- operand 2 of the ual
265
            PRE_code_ual     <= OP_OUI;           -- Alu operation
266
            PRE_offset       <= (others => '0');  -- Address offset for calculation
267
            PRE_adr_reg_dest <= (others => '0');  -- Destination register adress for result
268
            PRE_ecr_reg      <= '0';              -- Writing of result in the bank register
269
            PRE_mode         <= '0';              -- Address calculation with current pc
270
            PRE_op_mem       <= '0';              -- Memory access operation instruction 
271
            PRE_r_w          <= '0';              -- Read/write selection in memory
272
            PRE_exc_cause    <= IT_ERINS;         -- Potential exception cause
273
            PRE_level        <= LVL_DI;           -- Result availability stage for bypass
274
 
275
            -- Set asynchronous outputs
276
            adr_reg1 <= (others => '0');    -- First operand register
277
            adr_reg2 <= (others => '0');    -- Second operand register
278
            use1 <= '0';                    -- Effective use of operand 1
279
            use2 <= '0';                    -- Effective use of operand 2
280
 
281
        else -- Valid instruction
282
 
283
            -- Offset signal preparation
284
            case micro_code(instr).off_sel is
285
                when OFS_PCRL => -- PC(31..28) & Adresse & 00
286
                    PRE_offset <= EI_adr(31 downto 28) & address & "00";
287
                when OFS_NULL => -- 0
288
                    PRE_offset <= (others => '0');
289
                when OFS_SESH => -- sgn_ext(Imm) & 00
290
                    if imm(15)='1' then
291
                        PRE_offset <= "11111111111111" & imm & "00";
292
                    else
293
                        PRE_offset <= "00000000000000" & imm & "00";
294
                    end if;
295
                when OFS_SEXT => -- sgn_ext(Imm)
296
                    if imm(15)='1' then
297
                        PRE_offset <= "1111111111111111" & imm;
298
                    else
299
                        PRE_offset <= "0000000000000000" & imm;
300
                    end if;
301
            end case;
302
 
303
 
304
            -- Alu operand preparation
305
            if micro_code(instr).cs_imm1='0' then
306
                -- Datas from register banks
307
                PRE_op1 <= data1;
308
            else
309
                -- Immediate datas
310
                if micro_code(instr).imm1_sel='0' then
311
                    PRE_op1 <= (others => '0');             -- Immediate operand = 0
312
                else
313
                    PRE_op1 <= X"000000" & "000" & shamt;   -- Immediate operand = shamt
314
                end if;
315
            end if;
316
 
317
 
318
            if micro_code(instr).cs_imm2='0' then
319
                -- Datas from register banks
320
                PRE_op2 <= data2;
321
            else
322
                -- Immediate datas
323
                if micro_code(instr).imm2_sel='0' then
324
                    PRE_op2 <= X"0000" & imm;               -- Immediate operand = imm
325
                else
326
                    if imm(15)='1' then                     -- Immediate operand = sgn_ext(imm)
327
                        PRE_op2 <= X"FFFF" & imm;
328
                    else
329
                        PRE_op2 <= X"0000" & imm;
330
                    end if;
331
                end if;
332
            end if;
333
 
334
            -- Selection of destination register address
335
            case micro_code(instr).des_sel is
336
                when D_RT => PRE_adr_reg_dest <= micro_code(instr).bank_des & rt;
337
                when D_RD => PRE_adr_reg_dest <= micro_code(instr).bank_des & rd;
338
                when D_31 => PRE_adr_reg_dest <= micro_code(instr).bank_des & "11111";
339
                when D_00 => PRE_adr_reg_dest <= micro_code(instr).bank_des & "00000";
340
            end case;
341
 
342
            -- Command signal affectation
343
            PRE_bra       <= micro_code(instr).bra;        -- Branch operation
344
            PRE_link      <= micro_code(instr).link;       -- Branch with link
345
            PRE_code_ual  <= micro_code(instr).code_ual;   -- Alu operation
346
            PRE_ecr_reg   <= micro_code(instr).ecr_reg;    -- Writing the result in a bank register
347
            PRE_mode      <= micro_code(instr).mode;       -- Type of calculation for the address with current pc
348
            PRE_op_mem    <= micro_code(instr).op_mem;     -- Memory operation needed
349
            PRE_r_w       <= micro_code(instr).r_w;        -- Read/Write in memory selection
350
            PRE_exc_cause <= micro_code(instr).exc_cause;  -- Potential cause exception
351
            PRE_level     <= micro_code(instr).level;
352
 
353
            -- Set asynchronous outputs
354
            adr_reg1 <= micro_code(instr).cop_org1 & rs; -- First operand register address
355
            adr_reg2 <= micro_code(instr).cop_org2 & rt; -- Second operand register address
356
            use1 <= not micro_code(instr).cs_imm1;       -- Effective use of operande 1
357
            use2 <= not micro_code(instr).cs_imm2;       -- Effective use of operande 2
358
        end if;
359
 
360
    end process;
361
 
362
 
363
 
364
    -- Set the synchronous outputs
365
    process (clock)
366
    begin
367
        if clock='1' and clock'event then
368
            if reset='1' then
369
                DI_bra <= '0';
370
                DI_link <= '0';
371
                DI_op1 <= (others => '0');
372
                DI_op2 <= (others => '0');
373
                DI_code_ual <= OP_OUI;
374
                DI_offset <= (others => '0');
375
                DI_adr_reg_dest <= (others => '0');
376
                DI_ecr_reg <= '0';
377
                DI_mode <= '0';
378
                DI_op_mem <= '0';
379
                DI_r_w <= '0';
380
                DI_adr <= (others => '0');
381
                DI_exc_cause <= IT_NOEXC;
382
                DI_level <= LVL_DI;
383
                DI_it_ok <= '0';
384
            elsif stop_all='0' then
385
                if clear='1' or stop_di='1' then
386
                    -- Nop instruction
387
                    DI_bra <= '0';
388
                    DI_link <= '0';
389
                    DI_op1 <= (others => '0');
390
                    DI_op2 <= (others => '0');
391
                    DI_code_ual <= OP_OUI;
392
                    DI_offset <= (others => '0');
393
                    DI_adr_reg_dest <= (others => '0');
394
                    DI_ecr_reg <= '0';
395
                    DI_mode <= '0';
396
                    DI_op_mem <= '0';
397
                    DI_r_w <= '0';
398
                    DI_adr <= EI_adr;
399
                    DI_exc_cause <= IT_NOEXC;
400
                    DI_level <= LVL_DI;
401
                    if clear='1' then
402
                      DI_it_ok <= '0';
403
                    else
404
                      DI_it_ok <= EI_it_ok;
405
                    end if;
406
                else -- Noraml step
407
                    DI_bra <= PRE_bra;
408
                    DI_link <= PRE_link;
409
                    DI_op1 <= PRE_op1;
410
                    DI_op2 <= PRE_op2;
411
                    DI_code_ual <= PRE_code_ual;
412
                    DI_offset <= PRE_offset;
413
                    DI_adr_reg_dest <= PRE_adr_reg_dest;
414
                    DI_ecr_reg <= PRE_ecr_reg;
415
                    DI_mode <= PRE_mode;
416
                    DI_op_mem <= PRE_op_mem;
417
                    DI_r_w <= PRE_r_w;
418
                    DI_adr <= EI_adr;
419
                    DI_exc_cause <= PRE_exc_cause;
420
                    DI_level <= PRE_level;
421
                    DI_it_ok <= EI_it_ok;
422
                end if;
423
            end if;
424
        end if;
425
    end process;
426
 
427
end rtl;
428
 
429
 

powered by: WebSVN 2.1.0

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