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

Subversion Repositories minimips_superscalar

[/] [minimips_superscalar/] [trunk/] [sources/] [pps_di.vhd] - Blame information for rev 2

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

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