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

Subversion Repositories rv01_riscv_core

[/] [rv01_riscv_core/] [trunk/] [VHDL/] [RV01_idec.vhd] - Blame information for rev 2

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 madsilicon
-----------------------------------------------------------------
2
--                                                             --
3
-----------------------------------------------------------------
4
--                                                             --
5
-- Copyright (C) 2015 Stefano Tonello                          --
6
--                                                             --
7
-- This source file may be used and distributed without        --
8
-- restriction provided that this copyright statement is not   --
9
-- removed from the file and that any derivative work contains --
10
-- the original copyright notice and the associated disclaimer.--
11
--                                                             --
12
-- THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY         --
13
-- EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED   --
14
-- TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS   --
15
-- FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL THE AUTHOR      --
16
-- OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,         --
17
-- INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES    --
18
-- (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE   --
19
-- GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR        --
20
-- BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF  --
21
-- LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT  --
22
-- (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT  --
23
-- OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE         --
24
-- POSSIBILITY OF SUCH DAMAGE.                                 --
25
--                                                             --
26
-----------------------------------------------------------------
27
 
28
---------------------------------------------------------------
29
-- Instruction decoder (stage 1)
30
---------------------------------------------------------------
31
 
32
library IEEE;
33
use IEEE.std_logic_1164.all;
34
use IEEE.numeric_std.all;
35
 
36
library work;
37
use work.RV01_CONSTS_PKG.all;
38
use work.RV01_TYPES_PKG.all;
39
use work.RV01_FUNCS_PKG.all;
40
use work.RV01_ARITH_PKG.all;
41
use work.RV01_IDEC_PKG.all;
42
use work.RV01_OP_PKG.all;
43
use work.RV01_CSR_PKG.all;
44
 
45
entity RV01_IDEC is
46
  port(
47
    INSTR_i : in std_logic_vector(ILEN-1 downto 0);
48
    IADR_MIS_i : in std_logic;
49
    IADR_ERR_i : in std_logic;
50
 
51
    OPA_PC_o : out std_logic;
52
    OPB_IMM_o : out std_logic;
53
    DEC_INSTR_o : out DEC_INSTR_T
54
  );
55
end RV01_IDEC;
56
 
57
architecture ARC of RV01_IDEC is
58
 
59
  signal OPCODE : std_logic_vector(7-1 downto 0);
60
  signal FUNCT3 : std_logic_vector(3-1 downto 0);
61
  signal FUNCT7 : std_logic_vector(7-1 downto 0);
62
  signal RD,RS1,RS2 : RID_T;
63
  signal IMNMC : INST_MNEMONIC_T;
64
  signal WRD,RRS1,RRS2,SU,WRD_NZ,WCSR,WCSR_NZ : std_logic;
65
  signal ALU_OP : ALU_OP_T;
66
  signal BJ_OP : BJ_OP_T;
67
  signal LS_OP : LS_OP_T;
68
  signal CS_OP : CS_OP_T;
69
  signal IMM : signed(SDLEN-1 downto 0);
70
  signal RES_SRC : RES_SRC_T;
71
  signal P0_ONLY,P1_ONLY : std_logic;
72
  signal IMM12_I,IMM12_S : std_logic_vector(12-1 downto 0);
73
  signal IMM12_SB : std_logic_vector(13-1 downto 0);
74
  signal IMM20_U : std_logic_vector(20-1 downto 0);
75
  signal IMM20_UJ : std_logic_vector(21-1 downto 0);
76
  signal B7 : std_logic_vector(4-1 downto 0);
77
  signal EXCP,ILLG,SEQX : std_logic;
78
  signal SCALL,SBREAK : std_logic;
79
  signal ECAUSE : std_logic_vector(5-1 downto 0);
80
  signal RFTCH : std_logic;
81
 
82
begin
83
 
84
  -- instruction subfields extraction
85
  process(INSTR_i)
86
  begin
87
 
88
    -- main opcode
89
    OPCODE <= INSTR_i(6 downto 0);
90
 
91
    -- 3-bit function field
92
    FUNCT3 <= INSTR_i(14 downto 12);
93
 
94
    -- 7-bit function field
95
    FUNCT7 <= INSTR_i(31 downto 25);
96
 
97
    -- register identifiers
98
    RD <= to_integer(to_unsigned(INSTR_i(11 downto 7)));
99
    RS1 <= to_integer(to_unsigned(INSTR_i(19 downto 15)));
100
    RS2 <= to_integer(to_unsigned(INSTR_i(24 downto 20)));
101
 
102
    -- I-type immediate
103
    IMM12_I <= INSTR_i(31 downto 20);
104
 
105
    -- S-type immediate
106
    IMM12_S <= INSTR_i(31 downto 25) & INSTR_i(11 downto 7);
107
 
108
    -- SB-type immediate
109
    IMM12_SB <= INSTR_i(31) & INSTR_i(7) & INSTR_i(30 downto 25) & INSTR_i(11 downto 8) & '0';
110
 
111
    -- U-type immediate
112
    IMM20_U <= INSTR_i(31 downto 12);
113
 
114
    -- UJ-type immediate
115
    IMM20_UJ <= INSTR_i(31) & INSTR_i(19 downto 12)& INSTR_i(20) & INSTR_i(30 downto 21) & '0';
116
 
117
    -- 7-th byte (used for fence instructions)
118
    B7 <= INSTR_i(31 downto 28);
119
 
120
  end process;
121
 
122
  -- instruction mnemonic and operand flags extraction
123
  process(OPCODE,FUNCT3,FUNCT7,IMM12_I,B7,RS1,RD)
124
  begin
125
 
126
    IMNMC <= IM_BAD_INSTR; -- instruction mnemonic (unique id).
127
    WCSR <= '0'; -- write CSR flag
128
    WRD <= '0'; -- write rd flag
129
    RRS1 <= '0'; -- read rs1 flag
130
    RRS2 <= '0'; -- read rs2 flag
131
    SU <= '1'; -- sign/unsigned selector 
132
    ALU_OP <= ALU_NIL; -- ALU operation type
133
    BJ_OP <= BJ_NIL; -- B/J operation type
134
    LS_OP <= LS_NIL; -- L/S operation type
135
    CS_OP <= CS_NIL; -- CSR operation type
136
    RES_SRC <= RS_NIL; -- result source
137
    P0_ONLY <= '0'; -- (can execute on) slot # 0 only flag 
138
    P1_ONLY <= '0'; -- (can execute on) slot # 1 only flag (never used)
139
    SEQX <= '0'; -- sequential execution flag
140
    ILLG <= '1'; -- illegal instruction flag
141
 
142
    -- A Mix of priority-based and parallel muxing
143
    -- logic is used to try to balance logic tree 
144
    -- depth between main opcodes with many 
145
    -- instructions (like OP_ALU) and main opcodes
146
    -- with few instructions (like OP_JAL).
147
 
148
    if(OPCODE = OP_ALU) then
149
 
150
        -- ALU instructions
151
        case FUNCT3 is
152
          when "000" =>
153
            case FUNCT7 is
154
              when "0000000" =>
155
                -- add rd,rs1,rs2
156
                IMNMC <= IM_ADD;
157
                RRS1 <= '1';
158
                RRS2 <= '1';
159
                WRD <= '1';
160
                ALU_OP <= ALU_ADD;
161
                RES_SRC <= RS_PIPEA;
162
                --P0_ONLY <= '1';
163
                ILLG <= '0';
164
              when "0000001" =>
165
                -- mul rd,rs1,rs2
166
                IMNMC <= IM_MUL;
167
                RRS1 <= '1';
168
                RRS2 <= '1';
169
                WRD <= '1';
170
                ALU_OP <= ALU_MUL;
171
                RES_SRC <= RS_PIPEB;
172
                P0_ONLY <= '1';
173
                ILLG <= '0';
174
              when "0100000" =>
175
                -- sub rd,rs1,rs2
176
                IMNMC <= IM_SUB;
177
                RRS1 <= '1';
178
                RRS2 <= '1';
179
                WRD <= '1';
180
                ALU_OP <= ALU_SUB;
181
                RES_SRC <= RS_PIPEB; --A;
182
                P0_ONLY <= '1';
183
                ILLG <= '0';
184
              when others =>
185
                -- invalid instruction
186
                IMNMC <= IM_BAD_INSTR;
187
                ILLG <= '1';
188
            end case;
189
          when "010" =>
190
            if(FUNCT7 = "0000000") then
191
              -- slt rd,rs1,rs2
192
              IMNMC <= IM_SLT;
193
              RRS1 <= '1';
194
              RRS2 <= '1';
195
              WRD <= '1';
196
              RES_SRC <= RS_PIPEB; --A;
197
              ALU_OP <= ALU_SLT;
198
              P0_ONLY <= '1';
199
              ILLG <= '0';
200
            elsif(FUNCT7 = "0000001") then
201
              -- mulhsu rd,rs1,rs2
202
              IMNMC <= IM_MULHSU;
203
              RRS1 <= '1';
204
              RRS2 <= '1';
205
              WRD <= '1';
206
              SU <= '0';
207
              ALU_OP <= ALU_MULHSU;
208
              RES_SRC <= RS_PIPEB;
209
              P0_ONLY <= '1';
210
              ILLG <= '0';
211
            else
212
              -- invalid instruction
213
              IMNMC <= IM_BAD_INSTR;
214
              ILLG <= '1';
215
            end if;
216
          when "011" =>
217
            if(FUNCT7 = "0000000") then
218
              -- sltu rd,rs1,rs2
219
              IMNMC <= IM_SLTU;
220
              RRS1 <= '1';
221
              RRS2 <= '1';
222
              WRD <= '1';
223
              SU <= '0';
224
              RES_SRC <= RS_PIPEB; --A;
225
              ALU_OP <= ALU_SLT;
226
              P0_ONLY <= '1';
227
              ILLG <= '0';
228
            elsif(FUNCT7 = "0000001") then
229
              -- mulhu rd,rs1,rs2
230
              IMNMC <= IM_MULHU;
231
              RRS1 <= '1';
232
              RRS2 <= '1';
233
              WRD <= '1';
234
              SU <= '0';
235
              ALU_OP <= ALU_MULHU;
236
              RES_SRC <= RS_PIPEB;
237
              P0_ONLY <= '1';
238
              ILLG <= '0';
239
            else
240
              -- invalid instruction
241
              IMNMC <= IM_BAD_INSTR;
242
              ILLG <= '1';
243
            end if;
244
          when "100" =>
245
            if(FUNCT7 = "0000000") then
246
              -- xor rd,rs1,rs2
247
              IMNMC <= IM_XOR;
248
              RRS1 <= '1';
249
              RRS2 <= '1';
250
              WRD <= '1';
251
              ALU_OP <= ALU_XOR;
252
              RES_SRC <= RS_PIPEA; --B;
253
              --P0_ONLY <= '1';
254
              ILLG <= '0';
255
            elsif(FUNCT7 = "0000001") then
256
              -- div rd,rs1,rs2
257
              IMNMC <= IM_DIV;
258
              RRS1 <= '1';
259
              RRS2 <= '1';
260
              WRD <= '1';
261
              ALU_OP <= ALU_DIV;
262
              RES_SRC <= RS_DIVU;
263
              P0_ONLY <= '1';
264
              ILLG <= '0';
265
            else
266
              -- invalid instruction
267
              IMNMC <= IM_BAD_INSTR;
268
              ILLG <= '1';
269
            end if;
270
          when "110" =>
271
            if(FUNCT7 = "0000000") then
272
              -- or rd,rs1,rs2
273
              IMNMC <= IM_OR;
274
              RRS1 <= '1';
275
              RRS2 <= '1';
276
              WRD <= '1';
277
              ALU_OP <= ALU_OR;
278
              RES_SRC <= RS_PIPEA; --B;
279
              --P0_ONLY <= '1';
280
              ILLG <= '0';
281
            elsif(FUNCT7 = "0000001") then
282
              -- rem rd,rs1,rs2
283
              IMNMC <= IM_REM;
284
              RRS1 <= '1';
285
              RRS2 <= '1';
286
              WRD <= '1';
287
              ALU_OP <= ALU_REM;
288
              RES_SRC <= RS_DIVU;
289
              P0_ONLY <= '1';
290
              ILLG <= '0';
291
            else
292
              -- invalid instruction
293
              IMNMC <= IM_BAD_INSTR;
294
              ILLG <= '1';
295
            end if;
296
          when "111" =>
297
            if(FUNCT7 = "0000000") then
298
              -- and rd,rs1,rs2
299
              IMNMC <= IM_AND;
300
              RRS1 <= '1';
301
              RRS2 <= '1';
302
              WRD <= '1';
303
              ALU_OP <= ALU_AND;
304
              RES_SRC <= RS_PIPEA; --B;
305
              --P0_ONLY <= '1';
306
              ILLG <= '0';
307
            elsif(FUNCT7 = "0000001") then
308
              -- remu rd,rs1,rs2
309
              IMNMC <= IM_REMU;
310
              RRS1 <= '1';
311
              RRS2 <= '1';
312
              WRD <= '1';
313
              SU <= '0';
314
              ALU_OP <= ALU_REM;
315
              RES_SRC <= RS_DIVU;
316
              P0_ONLY <= '1';
317
              ILLG <= '0';
318
            else
319
              -- invalid instruction
320
              IMNMC <= IM_BAD_INSTR;
321
              ILLG <= '1';
322
            end if;
323
          when "001" =>
324
            if(FUNCT7 = "0000000") then
325
              -- sll rd,rs1,shamnt
326
              IMNMC <= IM_SLL;
327
              RRS1 <= '1';
328
              RRS2 <= '1';
329
              WRD <= '1';
330
              ALU_OP <= ALU_SHL;
331
              RES_SRC <= RS_PIPEA; --B;
332
              --P0_ONLY <= '1';
333
              ILLG <= '0';
334
            elsif(FUNCT7 = "0000001") then
335
              -- mulh rd,rs1,rs2
336
              IMNMC <= IM_MULH;
337
              RRS1 <= '1';
338
              RRS2 <= '1';
339
              WRD <= '1';
340
              ALU_OP <= ALU_MULH;
341
              RES_SRC <= RS_PIPEB;
342
              P0_ONLY <= '1';
343
              ILLG <= '0';
344
            else
345
              -- invalid instruction
346
              IMNMC <= IM_BAD_INSTR;
347
              ILLG <= '1';
348
            end if;
349
          when "101" =>
350
            if(FUNCT7 = "0000000") then
351
              -- srl rd,rs1,shamnt
352
              IMNMC <= IM_SRL;
353
              RRS1 <= '1';
354
              RRS2 <= '1';
355
              WRD <= '1';
356
              SU <= '0';
357
              ALU_OP <= ALU_SHR;
358
              RES_SRC <= RS_PIPEA; --B;
359
              --P0_ONLY <= '1';
360
              ILLG <= '0';
361
            elsif(FUNCT7 = "0000001") then
362
              -- divu rd,rs1,rs2
363
              IMNMC <= IM_DIVU;
364
              RRS1 <= '1';
365
              RRS2 <= '1';
366
              WRD <= '1';
367
              SU <= '0';
368
              ALU_OP <= ALU_DIV;
369
              RES_SRC <= RS_DIVU;
370
              P0_ONLY <= '1';
371
              ILLG <= '0';
372
            elsif(FUNCT7 = "0100000") then
373
              -- sra rd,rs1,shamnt
374
              IMNMC <= IM_SRA;
375
              RRS1 <= '1';
376
              RRS2 <= '1';
377
              WRD <= '1';
378
              ALU_OP <= ALU_SHR;
379
              RES_SRC <= RS_PIPEA; --B;
380
              --P0_ONLY <= '1';
381
              ILLG <= '0';
382
            else
383
              -- invalid instruction
384
              IMNMC <= IM_BAD_INSTR;
385
              ILLG <= '1';
386
            end if;
387
          when others =>
388
            -- invalid instruction
389
            ILLG <= '1';
390
            IMNMC <= IM_BAD_INSTR;
391
        end case;
392
 
393
    elsif(OPCODE = OP_ALUI) then
394
 
395
        -- ALU-immediate instructions
396
        case FUNCT3 is
397
          when "000" =>
398
            -- addi rd,rs1,imm12
399
            IMNMC <= IM_ADDI;
400
            RRS1 <= '1';
401
            WRD <= '1';
402
            RES_SRC <= RS_PIPEA;
403
            ALU_OP <= ALU_ADD;
404
            --P0_ONLY <= '1';
405
            ILLG <= '0';
406
          when "010" =>
407
            -- slti rd,rs1,imm12
408
            IMNMC <= IM_SLTI;
409
            RRS1 <= '1';
410
            WRD <= '1';
411
            RES_SRC <= RS_PIPEB; --A;
412
            ALU_OP <= ALU_SLT;
413
            P0_ONLY <= '1';
414
            ILLG <= '0';
415
          when "011" =>
416
            -- sltiu rd,rs1,imm12
417
            IMNMC <= IM_SLTIU;
418
            RRS1 <= '1';
419
            WRD <= '1';
420
            SU <= '0';
421
            RES_SRC <= RS_PIPEB; --A;
422
            ALU_OP <= ALU_SLT;
423
            P0_ONLY <= '1';
424
            ILLG <= '0';
425
          when "100" =>
426
            -- xori rd,rs1,imm12
427
            IMNMC <= IM_XORI;
428
            RRS1 <= '1';
429
            WRD <= '1';
430
            ALU_OP <= ALU_XOR;
431
            RES_SRC <= RS_PIPEA; --B;
432
            --P0_ONLY <= '1';
433
            ILLG <= '0';
434
          when "110" =>
435
            -- ori rd,rs1,imm12
436
            IMNMC <= IM_ORI;
437
            RRS1 <= '1';
438
            WRD <= '1';
439
            ALU_OP <= ALU_OR;
440
            RES_SRC <= RS_PIPEA; --B;
441
            --P0_ONLY <= '1';
442
            ILLG <= '0';
443
          when "111" =>
444
            -- andi rd,rs1,imm12
445
            IMNMC <= IM_ANDI;
446
            RRS1 <= '1';
447
            WRD <= '1';
448
            ALU_OP <= ALU_AND;
449
            RES_SRC <= RS_PIPEA; --B;
450
            --P0_ONLY <= '1';
451
            ILLG <= '0';
452
          when "001" =>
453
            RES_SRC <= RS_PIPEA; --B;
454
            if(FUNCT7 = "0000000") then
455
              -- slli rd,rs1,shamnt
456
              IMNMC <= IM_SLLI;
457
              RRS1 <= '1';
458
              WRD <= '1';
459
              ALU_OP <= ALU_SHL;
460
              --P0_ONLY <= '1';
461
              ILLG <= '0';
462
            else
463
              -- invalid instruction
464
              ILLG <= '1';
465
              IMNMC <= IM_BAD_INSTR;
466
            end if;
467
          when "101" =>
468
            if(FUNCT7 = "0000000") then
469
              -- srli rd,rs1,shamnt
470
              IMNMC <= IM_SRLI;
471
              RRS1 <= '1';
472
              WRD <= '1';
473
              SU <= '0';
474
              ALU_OP <= ALU_SHR;
475
              --P0_ONLY <= '1';
476
              ILLG <= '0';
477
            elsif(FUNCT7 = "0100000") then
478
              -- srai rd,rs1,shamnt
479
              IMNMC <= IM_SRAI;
480
              RRS1 <= '1';
481
              WRD <= '1';
482
              ALU_OP <= ALU_SHR;
483
              --P0_ONLY <= '1';
484
              ILLG <= '0';
485
            else
486
              -- invalid instruction
487
              ILLG <= '1';
488
              IMNMC <= IM_BAD_INSTR;
489
            end if;
490
          when others =>
491
            -- invalid instruction
492
            IMNMC <= IM_BAD_INSTR;
493
            ILLG <= '1';
494
        end case;
495
 
496
    elsif(OPCODE = OP_SYSTEM) then
497
 
498
        -- system instructions
499
        P0_ONLY <= '1';
500
        case FUNCT3 is
501
          when "000" =>
502
            case IMM12_I is
503
              when X"000" =>
504
                -- syscall
505
                IMNMC <= IM_SCALL;
506
                ILLG <= '0';
507
              when X"001" =>
508
                -- break
509
                IMNMC <= IM_SBREAK;
510
                ILLG <= '0';
511
              when X"100" =>
512
                -- eret
513
                IMNMC <= IM_ERET;
514
                ILLG <= '0';
515
              --when X"102" =>
516
              --  -- wfi
517
              --  IMNMC <= IM_WFI;
518
              --  ILLG <= '0';
519
              --when X"101" =>
520
              --  if(RD = 0) then
521
              --    -- sfrence.vm rs1
522
              --    IMNMC <= IM_SFENCEVM;
523
              --    ILLG <= '0';
524
              --  else
525
              --    -- invalid instruction
526
              --    IMNMC <= IM_BAD_INSTR;
527
              --    ILLG <= '1';
528
              --  end if;
529
              when others =>
530
              -- invalid instruction
531
              IMNMC <= IM_BAD_INSTR;
532
              ILLG <= '1';
533
            end case;
534
          when "001" =>
535
            -- csrrw rd,csr,rs1
536
            IMNMC <= IM_CSRRW;
537
            RRS1 <= '1';
538
            WRD <= '1';
539
            WCSR <= '1';
540
            CS_OP <= CS_RW;
541
            SEQX <= '1';
542
            RES_SRC <= RS_SIU;
543
            ILLG <= '0';
544
          when "010" =>
545
            -- csrrs rd,csr,rs1
546
            IMNMC <= IM_CSRRS;
547
            RRS1 <= '1';
548
            WRD <= '1';
549
            WCSR <= '1';
550
            CS_OP <= CS_RS;
551
            SEQX <= '1';
552
            RES_SRC <= RS_SIU;
553
            ILLG <= '0';
554
          when "011" =>
555
            -- csrrc rd,csr,rs1
556
            IMNMC <= IM_CSRRC;
557
            RRS1 <= '1';
558
            WRD <= '1';
559
            WCSR <= '1';
560
            CS_OP <= CS_RC;
561
            SEQX <= '1';
562
            RES_SRC <= RS_SIU;
563
            ILLG <= '0';
564
          when "101" =>
565
            -- csrrwi rd,csr,imm
566
            IMNMC <= IM_CSRRWI;
567
            RRS1 <= '1';
568
            WRD <= '1';
569
            WCSR <= '1';
570
            CS_OP <= CS_RWI;
571
            SEQX <= '1';
572
            RES_SRC <= RS_SIU;
573
            ILLG <= '0';
574
          when "110" =>
575
            -- csrrsi rd,csr,imm
576
            IMNMC <= IM_CSRRSI;
577
            RRS1 <= '1';
578
            WRD <= '1';
579
            WCSR <= '1';
580
            CS_OP <= CS_RSI;
581
            SEQX <= '1';
582
            RES_SRC <= RS_SIU;
583
            ILLG <= '0';
584
          when "111" =>
585
            -- csrrci rd,csr,imm
586
            IMNMC <= IM_CSRRCI;
587
            RRS1 <= '1';
588
            WRD <= '1';
589
            WCSR <= '1';
590
            CS_OP <= CS_RCI;
591
            SEQX <= '1';
592
            RES_SRC <= RS_SIU;
593
            ILLG <= '0';
594
          when others =>
595
            -- invalid instruction
596
            IMNMC <= IM_BAD_INSTR;
597
            ILLG <= '1';
598
        end case;
599
 
600
    else
601
 
602
      case OPCODE is
603
 
604
      when OP_LUI =>
605
        -- lui rD,imm20
606
        IMNMC <= IM_LUI;
607
        WRD <= '1';
608
        ALU_OP <= ALU_MOVB;
609
        RES_SRC <= RS_PIPEB;
610
        P0_ONLY <= '1';
611
        ILLG <= '0';
612
 
613
      when OP_AUIPC =>
614
        -- auipc rD,imm20
615
        IMNMC <= IM_AUIPC;
616
        WRD <= '1';
617
        ALU_OP <= ALU_AUIPC;
618
        RES_SRC <= RS_PIPEB;
619
        P0_ONLY <= '1';
620
        ILLG <= '0';
621
 
622
      when OP_JAL =>
623
        -- jal rD,imm20
624
        IMNMC <= IM_JAL;
625
        WRD <= '1';
626
        BJ_OP <= BJ_JAL;
627
        ALU_OP <= ALU_JAL;
628
        RES_SRC <= RS_PIPEB;
629
        --P0_ONLY <= '1';
630
        ILLG <= '0';
631
 
632
      when OP_JALR =>
633
        if(FUNCT3 = "000") then
634
          -- jalr rD,rs1,imm12
635
          IMNMC <= IM_JALR;
636
          RRS1 <= '1';
637
          WRD <= '1';
638
          BJ_OP <= BJ_JALR;
639
          ALU_OP <= ALU_JAL;
640
          RES_SRC <= RS_PIPEB;
641
          --P0_ONLY <= '1';
642
          ILLG <= '0';
643
        else
644
          -- invalid instruction
645
          IMNMC <= IM_BAD_INSTR;
646
          ILLG <= '1';
647
        end if;
648
 
649
      when OP_BRANCH =>
650
        --P0_ONLY <= '1';
651
        -- branch instructions
652
        case FUNCT3 is
653
          when "000" =>
654
            -- beq rs1,rs2,imm12
655
            IMNMC <= IM_BEQ;
656
            RRS1 <= '1';
657
            RRS2 <= '1';
658
            BJ_OP <= BJ_BEQ;
659
            ILLG <= '0';
660
          when "001" =>
661
            -- bne rs1,rs2,imm12
662
            IMNMC <= IM_BNE;
663
            RRS1 <= '1';
664
            RRS2 <= '1';
665
            BJ_OP <= BJ_BNE;
666
            ILLG <= '0';
667
          when "100" =>
668
            -- blt rs1,rs2,imm12
669
            IMNMC <= IM_BLT;
670
            RRS1 <= '1';
671
            RRS2 <= '1';
672
            BJ_OP <= BJ_BLT;
673
            ILLG <= '0';
674
          when "101" =>
675
            -- bge rs1,rs2,imm12
676
            IMNMC <= IM_BGE;
677
            RRS1 <= '1';
678
            RRS2 <= '1';
679
            BJ_OP <= BJ_BGE;
680
            ILLG <= '0';
681
          when "110" =>
682
            -- bltu rs1,rs2,imm12
683
            IMNMC <= IM_BLTU;
684
            RRS1 <= '1';
685
            RRS2 <= '1';
686
            SU <= '0';
687
            BJ_OP <= BJ_BLT;
688
            ILLG <= '0';
689
          when "111" =>
690
            -- bgeu rs1,rs2,imm12
691
            IMNMC <= IM_BGEU;
692
            RRS1 <= '1';
693
            RRS2 <= '1';
694
            SU <= '0';
695
            BJ_OP <= BJ_BGE;
696
            ILLG <= '0';
697
          when others =>
698
            -- invalid instruction
699
            ILLG <= '1';
700
            IMNMC <= IM_BAD_INSTR;
701
        end case;
702
 
703
      when OP_LOAD =>
704
        -- load instructions
705
        RES_SRC <= RS_LSU;
706
        case FUNCT3 is
707
          when "000" =>
708
            -- lb rd,rs1,imm12
709
            IMNMC <= IM_LB;
710
            RRS1 <= '1';
711
            WRD <= '1';
712
            LS_OP <= LS_LB;
713
            ILLG <= '0';
714
          when "001" =>
715
            -- lh rd,rs1,imm12
716
            IMNMC <= IM_LH;
717
            RRS1 <= '1';
718
            WRD <= '1';
719
            LS_OP <= LS_LH;
720
            ILLG <= '0';
721
          when "010" =>
722
            -- lw rd,rs1,imm12
723
            IMNMC <= IM_LW;
724
            RRS1 <= '1';
725
            WRD <= '1';
726
            LS_OP <= LS_LW;
727
            ILLG <= '0';
728
          when "100" =>
729
            -- lbu rd,rs1,imm12
730
            IMNMC <= IM_LBU;
731
            RRS1 <= '1';
732
            WRD <= '1';
733
            SU <= '0';
734
            LS_OP <= LS_LB;
735
            ILLG <= '0';
736
          when "101" =>
737
            -- lhu rd,rs1,imm12
738
            IMNMC <= IM_LHU;
739
            RRS1 <= '1';
740
            WRD <= '1';
741
            SU <= '0';
742
            LS_OP <= LS_LH;
743
            ILLG <= '0';
744
          when others =>
745
            -- invalid instruction
746
            IMNMC <= IM_BAD_INSTR;
747
            ILLG <= '1';
748
        end case;
749
 
750
      when OP_STORE =>
751
        --P0_ONLY <= '1';
752
        -- store instructions
753
        case FUNCT3 is
754
          when "000" =>
755
            -- sb rs1,rs2,imm12
756
            IMNMC <= IM_SB;
757
            RRS1 <= '1';
758
            RRS2 <= '1';
759
            LS_OP <= LS_SB;
760
            ILLG <= '0';
761
          when "001" =>
762
            -- sh rs1,rs2,imm12
763
            IMNMC <= IM_SH;
764
            RRS1 <= '1';
765
            RRS2 <= '1';
766
            LS_OP <= LS_SH;
767
            ILLG <= '0';
768
          when "010" =>
769
            -- sw rs1,rs2,imm12
770
            IMNMC <= IM_SW;
771
            RRS1 <= '1';
772
            RRS2 <= '1';
773
            LS_OP <= LS_SW;
774
            ILLG <= '0';
775
          when others =>
776
            -- invalid instruction
777
            IMNMC <= IM_BAD_INSTR;
778
            ILLG <= '1';
779
        end case;
780
 
781
      when OP_MISCMEM =>
782
        P0_ONLY <= '1';
783
        if(RD = 0 and RS1 = 0) then
784
          if(FUNCT3 = "000" and B7 = "0000") then
785
            -- fence
786
            IMNMC <= IM_FENCE;
787
            ILLG <= '0';
788
          elsif(FUNCT3 = "001" and IMM12_I = X"000") then
789
            -- fence.i
790
            IMNMC <= IM_FENCEI;
791
            ILLG <= '0';
792
          else
793
            -- invalid instruction
794
            ILLG <= '1';
795
            IMNMC <= IM_BAD_INSTR;
796
          end if;
797
        else
798
          -- invalid instruction
799
          ILLG <= '1';
800
          IMNMC <= IM_BAD_INSTR;
801
        end if;
802
 
803
      when others =>
804
        -- invalid instruction
805
        ILLG <= '1';
806
        IMNMC <= IM_BAD_INSTR;
807
 
808
      end case;
809
 
810
    end if;
811
 
812
  end process;
813
 
814
  -- OPB-as-immediate flag (set to '1' for all instructions
815
  -- except branch, store and ALU R-type ones)
816
  OPB_IMM_o <= '0' when (
817
    OPCODE = OP_BRANCH or
818
    OPCODE = OP_STORE or
819
    OPCODE = OP_ALU
820
  ) else '1';
821
 
822
  -- OPA-as-pc flag (set to '1' for jump&link and auipc
823
  -- instructions)
824
  OPA_PC_o <= '1' when (
825
    OPCODE = OP_AUIPC or
826
    OPCODE = OP_JAL
827
    --OPCODE = OP_JAL or 
828
    --OPCODE = OP_JALR
829
  ) else '0';
830
 
831
  -- immediate operand selector
832
  process(OPCODE,IMM12_I,IMM12_S,IMM12_SB,IMM20_U,IMM20_UJ)
833
    variable ZERO_12 : std_logic_vector(12-1 downto 0) := (others => '1');
834
  begin
835
    case OPCODE is
836
      when OP_LUI|OP_AUIPC =>
837
        IMM(12-1 downto 0) <= (others => '0');
838
        IMM(SDLEN-1 downto 12) <= to_signed(IMM20_U);
839
      when OP_JAL => IMM <= EXTS32(IMM20_UJ);
840
      when OP_BRANCH => IMM <= EXTS32(IMM12_SB);
841
      when OP_STORE => IMM <= EXTS32(IMM12_S);
842
      when others => IMM <= EXTS32(IMM12_I); -- OP_ALUI
843
    end case;
844
  end process;
845
 
846
  -- rd-non-zero rd write flag
847
  WRD_NZ <= WRD when (RD /= 0) else '0';
848
 
849
  -- rs1-non-zero CSR write flag (csrrw writes CSR even
850
  -- when rs1 is r0).
851
  WCSR_NZ <= WCSR when (RS1 /= 0 or IMNMC = IM_CSRRW) else '0';
852
 
853
  -- Exception flag
854
  EXCP <=
855
    IADR_MIS_i or
856
    IADR_ERR_i or
857
    ILLG;
858
 
859
  -- Exception cause
860
  ECAUSE <=
861
   IADRMIS when IADR_MIS_i = '1' else
862
   IACCFLT when IADR_ERR_i = '1' else
863
   ILLGINS;
864
 
865
  -- Re-Fetch flag (to be set in IX* stages)
866
  RFTCH <= '0';
867
 
868
  -- decoded instruction
869
  DEC_INSTR_o <= (
870
    IMNMC,
871
    WCSR_NZ,
872
    WRD_NZ,
873
    RRS1,
874
    RRS2,
875
    RD,
876
    RS1,
877
    RS2,
878
    IMM,
879
    SU,
880
    ALU_OP,
881
    BJ_OP,
882
    LS_OP,
883
    CS_OP,
884
    RES_SRC,
885
    P0_ONLY,
886
    P1_ONLY,
887
    EXCP,
888
    ECAUSE,
889
    RFTCH,
890
    SEQX
891
  );
892
 
893
end ARC;

powered by: WebSVN 2.1.0

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