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

Subversion Repositories riscv_vhdl

[/] [riscv_vhdl/] [trunk/] [rtl/] [riverlib/] [core/] [decoder.vhd] - Blame information for rev 5

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 5 sergeykhbr
-----------------------------------------------------------------------------
2
--! @file
3
--! @copyright Copyright 2016 GNSS Sensor Ltd. All right reserved.
4
--! @author    Sergey Khabarov - sergeykhbr@gmail.com
5
--! @brief     CPU Instruction Decoder stage.
6
------------------------------------------------------------------------------
7
 
8
library ieee;
9
use ieee.std_logic_1164.all;
10
library commonlib;
11
use commonlib.types_common.all;
12
--! RIVER CPU specific library.
13
library riverlib;
14
--! RIVER CPU configuration constants.
15
use riverlib.river_cfg.all;
16
 
17
 
18
entity InstrDecoder is
19
  port (
20
    i_clk  : in std_logic;
21
    i_nrst : in std_logic;
22
    i_any_hold : in std_logic;                               -- Hold pipeline by any reason
23
    i_f_valid : in std_logic;                                -- Fetch input valid
24
    i_f_pc : in std_logic_vector(BUS_ADDR_WIDTH-1 downto 0); -- Fetched pc
25
    i_f_instr : in std_logic_vector(31 downto 0);            -- Fetched instruction value
26
 
27
    o_valid : out std_logic;                                 -- Current output values are valid
28
    o_pc : out std_logic_vector(BUS_ADDR_WIDTH-1 downto 0);  -- Current instruction pointer value
29
    o_instr : out std_logic_vector(31 downto 0);             -- Current instruction value
30
    o_memop_store : out std_logic;                           -- Store to memory operation
31
    o_memop_load : out std_logic;                            -- Load from memoru operation
32
    o_memop_sign_ext : out std_logic;                        -- Load memory value with sign extending
33
    o_memop_size : out std_logic_vector(1 downto 0);         -- Memory transaction size
34
    o_rv32 : out std_logic;                                  -- 32-bits instruction
35
    o_compressed : out std_logic;                            -- 16-bits opcode (C-extension)
36
    o_unsigned_op : out std_logic;                           -- Unsigned operands
37
    o_isa_type : out std_logic_vector(ISA_Total-1 downto 0); -- Instruction format accordingly with ISA
38
    o_instr_vec : out std_logic_vector(Instr_Total-1 downto 0); -- One bit per decoded instruction bus
39
    o_exception : out std_logic                              -- Unimplemented instruction
40
  );
41
end;
42
 
43
architecture arch_InstrDecoder of InstrDecoder is
44
 
45
  -- LB, LH, LW, LD, LBU, LHU, LWU
46
  constant OPCODE_LB     : std_logic_vector(4 downto 0) := "00000";
47
  -- FENCE, FENCE_I
48
  constant OPCODE_FENCE  : std_logic_vector(4 downto 0) := "00011";
49
  --  ADDI, ANDI, ORI, SLLI, SLTI, SLTIU, SRAI, SRLI, XORI
50
  constant OPCODE_ADDI   : std_logic_vector(4 downto 0) := "00100";
51
  -- AUIPC
52
  constant OPCODE_AUIPC  : std_logic_vector(4 downto 0) := "00101";
53
  -- ADDIW, SLLIW, SRAIW, SRLIW
54
  constant OPCODE_ADDIW  : std_logic_vector(4 downto 0) := "00110";
55
  -- SB, SH, SW, SD
56
  constant OPCODE_SB     : std_logic_vector(4 downto 0) := "01000";
57
  -- ADD, AND, OR, SLT, SLTU, SLL, SRA, SRL, SUB, XOR, DIV, DIVU, MUL, REM, REMU
58
  constant OPCODE_ADD    : std_logic_vector(4 downto 0) := "01100";
59
  -- LUI
60
  constant OPCODE_LUI    : std_logic_vector(4 downto 0) := "01101";
61
  -- ADDW, SLLW, SRAW, SRLW, SUBW, DIVW, DIVUW, MULW, REMW, REMUW
62
  constant OPCODE_ADDW   : std_logic_vector(4 downto 0) := "01110";
63
  -- BEQ, BNE, BLT, BGE, BLTU, BGEU
64
  constant OPCODE_BEQ    : std_logic_vector(4 downto 0) := "11000";
65
  -- JALR
66
  constant OPCODE_JALR   : std_logic_vector(4 downto 0) := "11001";
67
  -- JAL
68
  constant OPCODE_JAL    : std_logic_vector(4 downto 0) := "11011";
69
  -- CSRRC, CSRRCI, CSRRS, CSRRSI, CSRRW, CSRRWI, URET, SRET, HRET, MRET
70
  constant OPCODE_CSRR   : std_logic_vector(4 downto 0) := "11100";
71
  -- Compressed instruction set
72
  constant OPCODE_C_ADDI4SPN : std_logic_vector(4 downto 0) := "00000";
73
  constant OPCODE_C_NOP_ADDI : std_logic_vector(4 downto 0) := "00001";
74
  constant OPCODE_C_SLLI     : std_logic_vector(4 downto 0) := "00010";
75
  constant OPCODE_C_JAL_ADDIW : std_logic_vector(4 downto 0) := "00101";
76
  constant OPCODE_C_LW       : std_logic_vector(4 downto 0) := "01000";
77
  constant OPCODE_C_LI       : std_logic_vector(4 downto 0) := "01001";
78
  constant OPCODE_C_LWSP     : std_logic_vector(4 downto 0) := "01010";
79
  constant OPCODE_C_LD       : std_logic_vector(4 downto 0) := "01100";
80
  constant OPCODE_C_ADDI16SP_LUI : std_logic_vector(4 downto 0) := "01101";
81
  constant OPCODE_C_LDSP     : std_logic_vector(4 downto 0) := "01110";
82
  constant OPCODE_C_MATH     : std_logic_vector(4 downto 0) := "10001";
83
  constant OPCODE_C_JR_MV_EBREAK_JALR_ADD : std_logic_vector(4 downto 0) := "10010";
84
  constant OPCODE_C_J        : std_logic_vector(4 downto 0) := "10101";
85
  constant OPCODE_C_SW       : std_logic_vector(4 downto 0) := "11000";
86
  constant OPCODE_C_BEQZ     : std_logic_vector(4 downto 0) := "11001";
87
  constant OPCODE_C_SWSP     : std_logic_vector(4 downto 0) := "11010";
88
  constant OPCODE_C_SD       : std_logic_vector(4 downto 0) := "11100";
89
  constant OPCODE_C_BNEZ     : std_logic_vector(4 downto 0) := "11101";
90
  constant OPCODE_C_SDSP     : std_logic_vector(4 downto 0) := "11110";
91
 
92
 
93
  constant INSTR_NONE : std_logic_vector(Instr_Total-1 downto 0) := (others => '0');
94
 
95
  type RegistersType is record
96
      valid : std_logic;
97
      pc : std_logic_vector(BUS_ADDR_WIDTH-1 downto 0);
98
      isa_type : std_logic_vector(ISA_Total-1 downto 0);
99
      instr_vec : std_logic_vector(Instr_Total-1 downto 0);
100
      instr : std_logic_vector(31 downto 0);
101
      memop_store : std_logic;
102
      memop_load : std_logic;
103
      memop_sign_ext : std_logic;
104
      memop_size : std_logic_vector(1 downto 0);
105
      unsigned_op : std_logic;
106
      rv32 : std_logic;
107
      compressed : std_logic;
108
      instr_unimplemented : std_logic;
109
  end record;
110
 
111
  signal r, rin : RegistersType;
112
 
113
begin
114
 
115
 
116
  comb : process(i_nrst, i_any_hold, i_f_valid, i_f_pc, i_f_instr, r)
117
    variable v : RegistersType;
118
    variable w_o_valid : std_logic;
119
    variable w_error : std_logic;
120
    variable w_compressed : std_logic;
121
    variable wb_instr : std_logic_vector(31 downto 0);
122
    variable wb_instr_out : std_logic_vector(31 downto 0);
123
    variable wb_opcode1 : std_logic_vector(4 downto 0);
124
    variable wb_opcode2 : std_logic_vector(2 downto 0);
125
    variable wb_dec : std_logic_vector(Instr_Total-1 downto 0);
126
    variable wb_isa_type : std_logic_vector(ISA_Total-1 downto 0);
127
  begin
128
 
129
    v := r;
130
    w_error := '0';
131
    w_compressed := '0';
132
    wb_instr := i_f_instr;
133
    wb_opcode1 := wb_instr(6 downto 2);
134
    wb_opcode2 := wb_instr(14 downto 12);
135
    wb_dec := (others => '0');
136
    wb_isa_type := (others => '0');
137
 
138
    if wb_instr(1 downto 0) /= "11" then
139
        w_compressed := '1';
140
        wb_opcode1 := wb_instr(15 downto 13) & wb_instr(1 downto 0);
141
        wb_instr_out := X"00000003";
142
        case wb_opcode1 is
143
        when OPCODE_C_ADDI4SPN =>
144
            wb_isa_type(ISA_I_type) := '1';
145
            wb_dec(Instr_ADDI) := '1';
146
            wb_instr_out(11 downto 7) := "01" & wb_instr(4 downto 2);   -- rd
147
            wb_instr_out(19 downto 15) := "00010";                     -- rs1 = sp
148
            wb_instr_out(29 downto 22) :=
149
                wb_instr(10 downto 7) & wb_instr(12 downto 11) & wb_instr(5) & wb_instr(6);
150
        when OPCODE_C_NOP_ADDI =>
151
            wb_isa_type(ISA_I_type) := '1';
152
            wb_dec(Instr_ADDI) := '1';
153
            wb_instr_out(11 downto 7) := wb_instr(11 downto 7);   -- rd
154
            wb_instr_out(19 downto 15) := wb_instr(11 downto 7);  -- rs1
155
            wb_instr_out(24 downto 20) := wb_instr(6 downto 2);   -- imm
156
            if wb_instr(12) = '1' then
157
                wb_instr_out(31 downto 25) := (others => '1');
158
            end if;
159
        when OPCODE_C_SLLI =>
160
            wb_isa_type(ISA_I_type) := '1';
161
            wb_dec(Instr_SLLI) := '1';
162
            wb_instr_out(11 downto 7) := wb_instr(11 downto 7);      -- rd
163
            wb_instr_out(19 downto 15) := wb_instr(11 downto 7);     -- rs1
164
            wb_instr_out(25 downto 20) := wb_instr(12) & wb_instr(6 downto 2);  -- shamt
165
        when OPCODE_C_JAL_ADDIW =>
166
            -- JAL is the RV32C only instruction
167
            wb_isa_type(ISA_I_type) := '1';
168
            wb_dec(Instr_ADDIW) := '1';
169
            wb_instr_out(11 downto 7) := wb_instr(11 downto 7);      -- rd
170
            wb_instr_out(19 downto 15) := wb_instr(11 downto 7);     -- rs1
171
            wb_instr_out(24 downto 20) := wb_instr(6 downto 2);      -- imm
172
            if wb_instr(12) = '1' then
173
                wb_instr_out(31 downto 25) := (others => '1');
174
            end if;
175
        when OPCODE_C_LW =>
176
            wb_isa_type(ISA_I_type) := '1';
177
            wb_dec(Instr_LW) := '1';
178
            wb_instr_out(11 downto 7) := "01" & wb_instr(4 downto 2);   -- rd
179
            wb_instr_out(19 downto 15) := "01" & wb_instr(9 downto 7);  -- rs1
180
            wb_instr_out(26 downto 22) :=
181
                wb_instr(5) & wb_instr(12 downto 10) & wb_instr(6);
182
        when OPCODE_C_LI =>  -- ADDI rd = r0 + imm
183
            wb_isa_type(ISA_I_type) := '1';
184
            wb_dec(Instr_ADDI) := '1';
185
            wb_instr_out(11 downto 7) := wb_instr(11 downto 7);      -- rd
186
            wb_instr_out(24 downto 20) := wb_instr(6 downto 2);      -- imm
187
            if wb_instr(12) = '1' then
188
                wb_instr_out(31 downto 25) := (others => '1');
189
            end if;
190
        when OPCODE_C_LWSP =>
191
            wb_isa_type(ISA_I_type) := '1';
192
            wb_dec(Instr_LW) := '1';
193
            wb_instr_out(11 downto 7) := wb_instr(11 downto 7);    -- rd
194
            wb_instr_out(19 downto 15) := "00010";                 -- rs1 = sp
195
            wb_instr_out(27 downto 22) :=
196
                wb_instr(3 downto 2) & wb_instr(12) & wb_instr(6 downto 4);
197
        when OPCODE_C_LD =>
198
            wb_isa_type(ISA_I_type) := '1';
199
            wb_dec(Instr_LD) := '1';
200
            wb_instr_out(11 downto 7) := "01" & wb_instr(4 downto 2);   -- rd
201
            wb_instr_out(19 downto 15) := "01" & wb_instr(9 downto 7);  -- rs1
202
            wb_instr_out(27 downto 23) :=
203
                wb_instr(6) & wb_instr(5) & wb_instr(12 downto 10);
204
        when OPCODE_C_ADDI16SP_LUI =>
205
            if wb_instr(11 downto 7) = "00010" then
206
                wb_isa_type(ISA_I_type) := '1';
207
                wb_dec(Instr_ADDI) := '1';
208
                wb_instr_out(11 downto 7) := "00010";     -- rd = sp
209
                wb_instr_out(19 downto 15) := "00010";    -- rs1 = sp
210
                wb_instr_out(28 downto 24) :=
211
                    wb_instr(4 downto 3) & wb_instr(5) & wb_instr(2) & wb_instr(6);
212
                if wb_instr(12) = '1' then
213
                    wb_instr_out(31 downto 29) := (others => '1');
214
                end if;
215
            else
216
                wb_isa_type(ISA_U_type) := '1';
217
                wb_dec(Instr_LUI) := '1';
218
                wb_instr_out(11 downto 7) := wb_instr(11 downto 7);  -- rd
219
                wb_instr_out(16 downto 12) := wb_instr(6 downto 2);
220
                if wb_instr(12) = '1' then
221
                    wb_instr_out(31 downto 17) := (others => '1');
222
                end if;
223
            end if;
224
        when OPCODE_C_LDSP =>
225
            wb_isa_type(ISA_I_type) := '1';
226
            wb_dec(Instr_LD) := '1';
227
            wb_instr_out(11 downto 7) := wb_instr(11 downto 7);  -- rd
228
            wb_instr_out(19 downto 15) := "00010";               -- rs1 = sp
229
            wb_instr_out(28 downto 23) :=
230
                wb_instr(4 downto 2) & wb_instr(12) & wb_instr(6 downto 5);
231
        when OPCODE_C_MATH =>
232
            if wb_instr(11 downto 10) = "00" then
233
                wb_isa_type(ISA_I_type) := '1';
234
                wb_dec(Instr_SRLI) := '1';
235
                wb_instr_out(11 downto 7) := "01" & wb_instr(9 downto 7);   -- rd
236
                wb_instr_out(19 downto 15) := "01" & wb_instr(9 downto 7);  -- rs1
237
                wb_instr_out(25 downto 20) := wb_instr(12) & wb_instr(6 downto 2);  -- shamt
238
            elsif wb_instr(11 downto 10) = "01" then
239
                wb_isa_type(ISA_I_type) := '1';
240
                wb_dec(Instr_SRAI) := '1';
241
                wb_instr_out(11 downto 7) := "01" & wb_instr(9 downto 7);   -- rd
242
                wb_instr_out(19 downto 15) := "01" & wb_instr(9 downto 7);  -- rs1
243
                wb_instr_out(25 downto 20) := wb_instr(12) & wb_instr(6 downto 2);  -- shamt
244
            elsif wb_instr(11 downto 10) = "10" then
245
                wb_isa_type(ISA_I_type) := '1';
246
                wb_dec(Instr_ANDI) := '1';
247
                wb_instr_out(11 downto 7) := "01" & wb_instr(9 downto 7);   -- rd
248
                wb_instr_out(19 downto 15) := "01" & wb_instr(9 downto 7);  -- rs1
249
                wb_instr_out(24 downto 20) := wb_instr(6 downto 2);        -- imm
250
                if wb_instr(12) = '1' then
251
                    wb_instr_out(31 downto 25) := (others => '1');
252
                end if;
253
            elsif wb_instr(12) = '0' then
254
                wb_isa_type(ISA_R_type) := '1';
255
                wb_instr_out(11 downto 7) := "01" & wb_instr(9 downto 7);   -- rd
256
                wb_instr_out(19 downto 15) := "01" & wb_instr(9 downto 7);  -- rs1
257
                wb_instr_out(24 downto 20) := "01" & wb_instr(4 downto 2);  -- rs2
258
                case wb_instr(6 downto 5) is
259
                when "00" =>
260
                    wb_dec(Instr_SUB) := '1';
261
                when "01" =>
262
                    wb_dec(Instr_XOR) := '1';
263
                when "10" =>
264
                    wb_dec(Instr_OR) := '1';
265
                when others =>
266
                    wb_dec(Instr_AND) := '1';
267
                end case;
268
            else
269
                wb_isa_type(ISA_R_type) := '1';
270
                wb_instr_out(11 downto 7) := "01" & wb_instr(9 downto 7);   -- rd
271
                wb_instr_out(19 downto 15) := "01" & wb_instr(9 downto 7);  -- rs1
272
                wb_instr_out(24 downto 20) := "01" & wb_instr(4 downto 2);  -- rs2
273
                case wb_instr(6 downto 5) is
274
                when "00" =>
275
                    wb_dec(Instr_SUBW) := '1';
276
                when "01" =>
277
                    wb_dec(Instr_ADDW) := '1';
278
                when others =>
279
                    w_error := '1';
280
                end case;
281
            end if;
282
        when OPCODE_C_JR_MV_EBREAK_JALR_ADD =>
283
            wb_isa_type(ISA_I_type) := '1';
284
            if wb_instr(12) = '0' then
285
                if wb_instr(6 downto 2) = "00000" then
286
                    wb_dec(Instr_JALR) := '1';
287
                    wb_instr_out(19 downto 15) := wb_instr(11 downto 7);  -- rs1
288
                else
289
                    wb_dec(Instr_ADDI) := '1';
290
                    wb_instr_out(11 downto 7) := wb_instr(11 downto 7);   -- rd
291
                    wb_instr_out(19 downto 15) := wb_instr(6 downto 2);   -- rs1
292
                end if;
293
            else
294
                if wb_instr(11 downto 7) = "00000" and wb_instr(6 downto 2) = "00000" then
295
                    wb_dec(Instr_EBREAK) := '1';
296
                elsif wb_instr(6 downto 2) = "00000" then
297
                    wb_dec(Instr_JALR) := '1';
298
                    wb_instr_out(11 downto 7) := "00001";                 -- rd = ra
299
                    wb_instr_out(19 downto 15) := wb_instr(11 downto 7);  -- rs1
300
                else
301
                    wb_dec(Instr_ADD) := '1';
302
                    wb_isa_type(ISA_R_type) := '1';
303
                    wb_instr_out(11 downto 7) := wb_instr(11 downto 7);   -- rd
304
                    wb_instr_out(19 downto 15) := wb_instr(11 downto 7);  -- rs1
305
                    wb_instr_out(24 downto 20) := wb_instr(6 downto 2);   -- rs2
306
                end if;
307
            end if;
308
        when OPCODE_C_J =>   -- JAL with rd = 0
309
            wb_isa_type(ISA_UJ_type) := '1';
310
            wb_dec(Instr_JAL) := '1';
311
            wb_instr_out(20) := wb_instr(12);            -- imm11
312
            wb_instr_out(23 downto 21) := wb_instr(5 downto 3);      -- imm10_1(3:1)
313
            wb_instr_out(24) := wb_instr(11);            -- imm10_1(4)
314
            wb_instr_out(25) := wb_instr(2);             -- imm10_1(5)
315
            wb_instr_out(26) := wb_instr(7);             -- imm10_1(6)
316
            wb_instr_out(27) := wb_instr(6);             -- imm10_1(7)
317
            wb_instr_out(29 downto 28) := wb_instr(10 downto 9);     -- imm10_1(9:8)
318
            wb_instr_out(30) := wb_instr(8);             -- imm10_1(10)
319
            if wb_instr(12) = '1' then
320
                wb_instr_out(19 downto 12) := (others => '1'); -- imm19_12
321
                wb_instr_out(31) := '1';                 -- imm20
322
            end if;
323
        when OPCODE_C_SW =>
324
            wb_isa_type(ISA_S_type) := '1';
325
            wb_dec(Instr_SW) := '1';
326
            wb_instr_out(24 downto 20) := "01" & wb_instr(4 downto 2);    -- rs2
327
            wb_instr_out(19 downto 15) := "01" & wb_instr(9 downto 7);    -- rs1
328
            wb_instr_out(11 downto 9) := wb_instr(11 downto 10) & wb_instr(6);
329
            wb_instr_out(26 downto 25) := wb_instr(5) & wb_instr(12);
330
        when OPCODE_C_BEQZ =>
331
            wb_isa_type(ISA_SB_type) := '1';
332
            wb_dec(Instr_BEQ) := '1';
333
            wb_instr_out(19 downto 15) := "01" & wb_instr(9 downto 7);    -- rs1
334
            wb_instr_out(11 downto 8) := wb_instr(11 downto 10) & wb_instr(4 downto 3);
335
            wb_instr_out(27 downto 25) := wb_instr(6 downto 5) & wb_instr(2);
336
            if wb_instr(12) = '1' then
337
                wb_instr_out(30 downto 28) := (others => '1');
338
                wb_instr_out(7) := '1';
339
                wb_instr_out(31) := '1';
340
            end if;
341
        when OPCODE_C_SWSP =>
342
            wb_isa_type(ISA_S_type) := '1';
343
            wb_dec(Instr_SW) := '1';
344
            wb_instr_out(24 downto 20) := wb_instr(6 downto 2);  -- rs2
345
            wb_instr_out(19 downto 15) := "00010";             -- rs1 = sp
346
            wb_instr_out(11 downto 9) := wb_instr(11 downto 9);
347
            wb_instr_out(27 downto 25) := wb_instr(8 downto 7) & wb_instr(12);
348
        when OPCODE_C_SD =>
349
            wb_isa_type(ISA_S_type) := '1';
350
            wb_dec(Instr_SD) := '1';
351
            wb_instr_out(24 downto 20) := "01" & wb_instr(4 downto 2);  -- rs2
352
            wb_instr_out(19 downto 15) := "01" & wb_instr(9 downto 7);  -- rs1
353
            wb_instr_out(11 downto 10) := wb_instr(11 downto 10);
354
            wb_instr_out(27 downto 25) := wb_instr(6 downto 5) & wb_instr(12);
355
        when OPCODE_C_BNEZ =>
356
            wb_isa_type(ISA_SB_type) := '1';
357
            wb_dec(Instr_BNE) := '1';
358
            wb_instr_out(19 downto 15) := "01" & wb_instr(9 downto 7);    -- rs1
359
            wb_instr_out(11 downto 8) := wb_instr(11 downto 10) & wb_instr(4 downto 3);
360
            wb_instr_out(27 downto 25) := wb_instr(6 downto 5) & wb_instr(2);
361
            if wb_instr(12) = '1' then
362
                wb_instr_out(30 downto 28) := (others => '1');
363
                wb_instr_out(7) := '1';
364
                wb_instr_out(31) := '1';
365
            end if;
366
        when OPCODE_C_SDSP =>
367
            wb_isa_type(ISA_S_type) := '1';
368
            wb_dec(Instr_SD) := '1';
369
            wb_instr_out(24 downto 20) := wb_instr(6 downto 2);  -- rs2
370
            wb_instr_out(19 downto 15) := "00010";               -- rs1 = sp
371
            wb_instr_out(11 downto 10) := wb_instr(11 downto 10);
372
            wb_instr_out(28 downto 25) := wb_instr(9 downto 7) & wb_instr(12);
373
        when others =>
374
            w_error := '1';
375
        end case;
376
    else -- compressed/!not compressed
377
        case wb_opcode1 is
378
        when OPCODE_ADD =>
379
            wb_isa_type(ISA_R_type) := '1';
380
            case wb_opcode2 is
381
            when "000" =>
382
                if wb_instr(31 downto 25) = "0000000" then
383
                    wb_dec(Instr_ADD) := '1';
384
                elsif wb_instr(31 downto 25) = "0000001" then
385
                    wb_dec(Instr_MUL) := '1';
386
                elsif wb_instr(31 downto 25) = "0100000" then
387
                    wb_dec(Instr_SUB) := '1';
388
                else
389
                    w_error := '1';
390
                end if;
391
            when "001" =>
392
                wb_dec(Instr_SLL) := '1';
393
            when "010" =>
394
                wb_dec(Instr_SLT) := '1';
395
            when "011" =>
396
                wb_dec(Instr_SLTU) := '1';
397
            when "100" =>
398
                if wb_instr(31 downto 25) = "0000000" then
399
                    wb_dec(Instr_XOR) := '1';
400
                elsif wb_instr(31 downto 25) = "0000001" then
401
                    wb_dec(Instr_DIV) := '1';
402
                else
403
                    w_error := '1';
404
                end if;
405
            when "101" =>
406
                if wb_instr(31 downto 25) = "0000000" then
407
                    wb_dec(Instr_SRL) := '1';
408
                elsif wb_instr(31 downto 25) = "0000001" then
409
                    wb_dec(Instr_DIVU) := '1';
410
                elsif wb_instr(31 downto 25) = "0100000" then
411
                    wb_dec(Instr_SRA) := '1';
412
                else
413
                    w_error := '1';
414
                end if;
415
            when "110" =>
416
                if wb_instr(31 downto 25) = "0000000" then
417
                    wb_dec(Instr_OR) := '1';
418
                elsif wb_instr(31 downto 25) = "0000001" then
419
                    wb_dec(Instr_REM) := '1';
420
                else
421
                    w_error := '1';
422
                end if;
423
            when "111" =>
424
                if wb_instr(31 downto 25) = "0000000" then
425
                    wb_dec(Instr_AND) := '1';
426
                elsif wb_instr(31 downto 25) = "0000001" then
427
                    wb_dec(Instr_REMU) := '1';
428
                else
429
                    w_error := '1';
430
                end if;
431
            when others =>
432
                w_error := '1';
433
            end case;
434
        when OPCODE_ADDI =>
435
            wb_isa_type(ISA_I_type) := '1';
436
            case wb_opcode2 is
437
            when "000" =>
438
                wb_dec(Instr_ADDI) := '1';
439
            when "001" =>
440
                wb_dec(Instr_SLLI) := '1';
441
            when "010" =>
442
                wb_dec(Instr_SLTI) := '1';
443
            when "011" =>
444
                wb_dec(Instr_SLTIU) := '1';
445
            when "100" =>
446
                wb_dec(Instr_XORI) := '1';
447
            when "101" =>
448
                if wb_instr(31 downto 26) = "000000" then
449
                    wb_dec(Instr_SRLI) := '1';
450
                elsif wb_instr(31 downto 26) = "010000" then
451
                    wb_dec(Instr_SRAI) := '1';
452
                else
453
                    w_error := '1';
454
                end if;
455
            when "110" =>
456
                wb_dec(Instr_ORI) := '1';
457
            when "111" =>
458
                wb_dec(Instr_ANDI) := '1';
459
            when others =>
460
                w_error := '1';
461
            end case;
462
        when OPCODE_ADDIW =>
463
            wb_isa_type(ISA_I_type) := '1';
464
            case wb_opcode2 is
465
            when "000" =>
466
                wb_dec(Instr_ADDIW) := '1';
467
            when "001" =>
468
                wb_dec(Instr_SLLIW) := '1';
469
            when "101" =>
470
                if wb_instr(31 downto 25) = "0000000" then
471
                    wb_dec(Instr_SRLIW) := '1';
472
                elsif wb_instr(31 downto 25) = "0100000" then
473
                    wb_dec(Instr_SRAIW) := '1';
474
                else
475
                    w_error := '1';
476
                end if;
477
            when others =>
478
                w_error := '1';
479
            end case;
480
        when OPCODE_ADDW =>
481
            wb_isa_type(ISA_R_type) := '1';
482
            case wb_opcode2 is
483
            when "000" =>
484
                if wb_instr(31 downto 25) = "0000000" then
485
                    wb_dec(Instr_ADDW) := '1';
486
                elsif wb_instr(31 downto 25) = "0000001" then
487
                    wb_dec(Instr_MULW) := '1';
488
                elsif wb_instr(31 downto 25) = "0100000" then
489
                    wb_dec(Instr_SUBW) := '1';
490
                else
491
                    w_error := '1';
492
                end if;
493
            when "001" =>
494
                wb_dec(Instr_SLLW) := '1';
495
            when "100" =>
496
                if wb_instr(31 downto 25) = "0000001" then
497
                    wb_dec(Instr_DIVW) := '1';
498
                else
499
                    w_error := '1';
500
                end if;
501
            when "101" =>
502
                if wb_instr(31 downto 25) = "0000000" then
503
                    wb_dec(Instr_SRLW) := '1';
504
                elsif wb_instr(31 downto 25) = "0000001" then
505
                    wb_dec(Instr_DIVUW) := '1';
506
                elsif wb_instr(31 downto 25) = "0100000" then
507
                    wb_dec(Instr_SRAW) := '1';
508
                else
509
                    w_error := '1';
510
                end if;
511
            when "110" =>
512
                if wb_instr(31 downto 25) = "0000001" then
513
                    wb_dec(Instr_REMW) := '1';
514
                else
515
                    w_error := '1';
516
                end if;
517
            when "111" =>
518
                if wb_instr(31 downto 25) = "0000001" then
519
                    wb_dec(Instr_REMUW) := '1';
520
                else
521
                    w_error := '1';
522
                end if;
523
            when others =>
524
                w_error := '1';
525
            end case;
526
        when OPCODE_AUIPC =>
527
            wb_isa_type(ISA_U_type) := '1';
528
            wb_dec(Instr_AUIPC) := '1';
529
        when OPCODE_BEQ =>
530
            wb_isa_type(ISA_SB_type) := '1';
531
            case wb_opcode2 is
532
            when "000" =>
533
                wb_dec(Instr_BEQ) := '1';
534
            when "001" =>
535
                wb_dec(Instr_BNE) := '1';
536
            when "100" =>
537
                wb_dec(Instr_BLT) := '1';
538
            when "101" =>
539
                wb_dec(Instr_BGE) := '1';
540
            when "110" =>
541
                wb_dec(Instr_BLTU) := '1';
542
            when "111" =>
543
                wb_dec(Instr_BGEU) := '1';
544
            when others =>
545
                w_error := '1';
546
            end case;
547
        when OPCODE_JAL =>
548
            wb_isa_type(ISA_UJ_type) := '1';
549
            wb_dec(Instr_JAL) := '1';
550
        when OPCODE_JALR =>
551
            wb_isa_type(ISA_I_type) := '1';
552
            case wb_opcode2 is
553
            when "000" =>
554
                wb_dec(Instr_JALR) := '1';
555
            when others =>
556
                w_error := '1';
557
            end case;
558
        when OPCODE_LB =>
559
            wb_isa_type(ISA_I_type) := '1';
560
            case wb_opcode2 is
561
            when "000" =>
562
                wb_dec(Instr_LB) := '1';
563
            when "001" =>
564
                wb_dec(Instr_LH) := '1';
565
            when "010" =>
566
                wb_dec(Instr_LW) := '1';
567
            when "011" =>
568
                wb_dec(Instr_LD) := '1';
569
            when "100" =>
570
                wb_dec(Instr_LBU) := '1';
571
            when "101" =>
572
                wb_dec(Instr_LHU) := '1';
573
            when "110" =>
574
                wb_dec(Instr_LWU) := '1';
575
            when others =>
576
                w_error := '1';
577
            end case;
578
        when OPCODE_LUI =>
579
            wb_isa_type(ISA_U_type) := '1';
580
            wb_dec(Instr_LUI) := '1';
581
        when OPCODE_SB =>
582
            wb_isa_type(ISA_S_type) := '1';
583
            case wb_opcode2 is
584
            when "000" =>
585
                wb_dec(Instr_SB) := '1';
586
            when "001" =>
587
                wb_dec(Instr_SH) := '1';
588
            when "010" =>
589
                wb_dec(Instr_SW) := '1';
590
            when "011" =>
591
                wb_dec(Instr_SD) := '1';
592
            when others =>
593
                w_error := '1';
594
            end case;
595
        when OPCODE_CSRR =>
596
            wb_isa_type(ISA_I_type) := '1';
597
            case wb_opcode2 is
598
            when "000" =>
599
                if wb_instr = X"00000073" then
600
                    wb_dec(Instr_ECALL) := '1';
601
                elsif wb_instr = X"00100073" then
602
                    wb_dec(Instr_EBREAK) := '1';
603
                elsif wb_instr = X"00200073" then
604
                    wb_dec(Instr_URET) := '1';
605
                elsif wb_instr = X"10200073" then
606
                    wb_dec(Instr_SRET) := '1';
607
                elsif wb_instr = X"20200073" then
608
                    wb_dec(Instr_HRET) := '1';
609
                elsif wb_instr = X"30200073" then
610
                    wb_dec(Instr_MRET) := '1';
611
                else
612
                    w_error := '1';
613
                end if;
614
            when "001" =>
615
                wb_dec(Instr_CSRRW) := '1';
616
            when "010" =>
617
                wb_dec(Instr_CSRRS) := '1';
618
            when "011" =>
619
                wb_dec(Instr_CSRRC) := '1';
620
            when "101" =>
621
                wb_dec(Instr_CSRRWI) := '1';
622
            when "110" =>
623
                wb_dec(Instr_CSRRSI) := '1';
624
            when "111" =>
625
                wb_dec(Instr_CSRRCI) := '1';
626
            when others =>
627
                w_error := '1';
628
            end case;
629
        when OPCODE_FENCE =>
630
            case wb_opcode2 is
631
            when "000" =>
632
                wb_dec(Instr_FENCE) := '1';
633
            when "001" =>
634
                wb_dec(Instr_FENCE_I) := '1';
635
            when others =>
636
                w_error := '1';
637
            end case;
638
 
639
        when others =>
640
            w_error := '1';
641
        end case;
642
        wb_instr_out := wb_instr;
643
    end if;
644
 
645
 
646
    if i_f_valid = '1' then
647
        v.valid := '1';
648
        v.pc := i_f_pc;
649
        v.instr := wb_instr_out;
650
        v.compressed := w_compressed;
651
 
652
        v.isa_type := wb_isa_type;
653
        v.instr_vec := wb_dec;
654
        v.memop_store := wb_dec(Instr_SD) or wb_dec(Instr_SW)
655
                      or wb_dec(Instr_SH) or wb_dec(Instr_SB);
656
        v.memop_load := wb_dec(Instr_LD) or wb_dec(Instr_LW)
657
                or wb_dec(Instr_LH) or wb_dec(Instr_LB)
658
                or wb_dec(Instr_LWU) or wb_dec(Instr_LHU)
659
                or wb_dec(Instr_LBU);
660
        v.memop_sign_ext := wb_dec(Instr_LD) or wb_dec(Instr_LW)
661
                or wb_dec(Instr_LH) or wb_dec(Instr_LB);
662
        if (wb_dec(Instr_LD) or wb_dec(Instr_SD)) = '1' then
663
            v.memop_size := MEMOP_8B;
664
        elsif (wb_dec(Instr_LW) or wb_dec(Instr_LWU) or wb_dec(Instr_SW)) = '1' then
665
            v.memop_size := MEMOP_4B;
666
        elsif (wb_dec(Instr_LH) or wb_dec(Instr_LHU) or wb_dec(Instr_SH)) = '1' then
667
            v.memop_size := MEMOP_2B;
668
        else
669
            v.memop_size := MEMOP_1B;
670
        end if;
671
        v.unsigned_op := wb_dec(Instr_DIVU) or wb_dec(Instr_REMU) or
672
                         wb_dec(Instr_DIVUW) or wb_dec(Instr_REMUW);
673
 
674
        v.rv32 := wb_dec(Instr_ADDW) or wb_dec(Instr_ADDIW)
675
            or wb_dec(Instr_SLLW) or wb_dec(Instr_SLLIW) or wb_dec(Instr_SRAW)
676
            or wb_dec(Instr_SRAIW)
677
            or wb_dec(Instr_SRLW) or wb_dec(Instr_SRLIW) or wb_dec(Instr_SUBW)
678
            or wb_dec(Instr_DIVW) or wb_dec(Instr_DIVUW) or wb_dec(Instr_MULW)
679
            or wb_dec(Instr_REMW) or wb_dec(Instr_REMUW);
680
 
681
        v.instr_unimplemented := w_error;
682
    elsif i_any_hold = '0' then
683
        v.valid := '0';
684
    end if;
685
    w_o_valid := r.valid and not i_any_hold;
686
 
687
    if i_nrst = '0' then
688
        v.valid := '0';
689
        v.pc := (others => '0');
690
        v.instr := (others => '0');
691
        v.isa_type := (others => '0');
692
        v.instr_vec := (others => '0');
693
        v.memop_store := '0';
694
        v.memop_load := '0';
695
        v.memop_sign_ext := '0';
696
        v.memop_size := MEMOP_1B;
697
        v.unsigned_op := '0';
698
        v.rv32 := '0';
699
        v.compressed := '0';
700
        v.instr_unimplemented := '0';
701
        if wb_dec = INSTR_NONE then
702
            v.instr_unimplemented := '1';
703
        end if;
704
    end if;
705
 
706
    o_valid <= w_o_valid;
707
    o_pc <= r.pc;
708
    o_instr <= r.instr;
709
    o_memop_load <= r.memop_load;
710
    o_memop_store <= r.memop_store;
711
    o_memop_sign_ext <= r.memop_sign_ext;
712
    o_memop_size <= r.memop_size;
713
    o_unsigned_op <= r.unsigned_op;
714
    o_rv32 <= r.rv32;
715
    o_compressed <= r.compressed;
716
    o_isa_type <= r.isa_type;
717
    o_instr_vec <= r.instr_vec;
718
    o_exception <= r.instr_unimplemented;
719
 
720
    rin <= v;
721
  end process;
722
 
723
  -- registers:
724
  regs : process(i_clk)
725
  begin
726
     if rising_edge(i_clk) then
727
        r <= rin;
728
     end if;
729
  end process;
730
 
731
end;

powered by: WebSVN 2.1.0

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