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

Subversion Repositories minimips_superscalar

[/] [minimips_superscalar/] [tags/] [P1/] [sources/] [pps_di.vhd] - Blame information for rev 21

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

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