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

Subversion Repositories plasma_fpu

[/] [plasma_fpu/] [trunk/] [src/] [controlunits/] [plasma_control_MIPSI_FPU.vhd] - Blame information for rev 2

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 __alexs__
-- --------------------------------------------------------------------------
2
-- >>>>>>>>>>>>>>>>>>>>>>>>>>>> COPYRIGHT NOTICE <<<<<<<<<<<<<<<<<<<<<<<<<<<<
3
-- --------------------------------------------------------------------------
4
-- TITLE:       Plasma CONTROL LOGIC
5
-- AUTHOR:      Alex Schoenberger (Alex.Schoenberger@ies.tu-darmstadt.de)
6
-- COMMENT:     This project is based on Plasma CPU core by Steve Rhoads
7
--
8
-- www.ies.tu-darmstadt.de
9
-- TU Darmstadt
10
-- Institute for Integrated Systems
11
-- Merckstr. 25
12
-- 
13
-- 64283 Darmstadt - GERMANY
14
-- --------------------------------------------------------------------------
15
-- PROJECT:       Plasma CPU core with FPU
16
-- FILENAME:      plasma_control.vhd
17
-- --------------------------------------------------------------------------
18
-- COPYRIGHT: 
19
--  This project is distributed by GPLv2.0
20
--  Software placed into the public domain by the author.
21
--  Software 'as is' without warranty.  Author liable for nothing.
22
-- --------------------------------------------------------------------------
23
-- DESCRIPTION:
24
--    switches input for computational units
25
--
26
--    SYNTHESIZABLE
27
--
28
----------------------------------------------------------------------------
29
-- Revision History
30
-- --------------------------------------------------------------------------
31
-- Revision   Date    Author     CHANGES
32
-- 1.0      4/2014    AS         initial
33
-- 2.0     12/2014    AS         separated into MIPS1 simple architecture
34
--                               and with FPU included
35
-- 3.0     05/2015    AS         made port more generic, removed FPU and imm 
36
--                                mux
37
-- --------------------------------------------------------------------------
38
library IEEE;
39
  use IEEE.std_logic_1164.ALL;
40
  use IEEE.numeric_std.ALL;
41
 
42
library PLASMA;
43
  use PLASMA.mips_instruction_set.ALL;
44
  use PLASMA.plasma_pack.ALL;
45
 
46
entity plasma_control_MIPSI_FPU is
47
    generic(
48
      core_idx                : natural := 0
49
    );
50
    port(
51
      control                 : in  t_main_control;
52
      instr_in                : in  t_plasma_word;       -- input instruction
53
      -- memory stalls
54
      prog_stall              : in  std_logic;
55
      data_stall              : in  std_logic;
56
      -- control flags
57
      comp_out                : in  std_logic;          -- comparator output
58
      fpu_cc                  : in  std_logic;          -- FPU comparator output
59
      unit_busy               : in  t_unit_busy;        -- busy flags of units      
60
      -- register bank control
61
      reg_addr                : out t_reg_addr;         -- register bank
62
      fpu_reg_addr            : out t_reg_addr;         -- FPU register bank
63
      mux_ctrl                : out t_plasma_mux_ctrl;  -- datapath muxes
64
      mux_fpu                 : out t_plasma_mux_fpu;   -- additional FPU muxes
65
      stall_src               : out t_stall_source;     -- control registers of datapath
66
      unit_ctrl               : out t_plasma_subunits_ctrl;
67
      fpu_ctrl                : out t_fpu_ctrl;
68
      -- memory access control
69
      mem_func                : out t_mips_opcode
70
    );
71
end entity plasma_control_MIPSI_FPU;
72
--
73
architecture structure_plasma_control_MIPSI_FPU of plasma_control_MIPSI_FPU is
74
 
75
 -- -----------------------------------------------------
76
  -- ___  ____ ____ ____ ___  ____ ____ 
77
  -- |  \ |___ |    |  | |  \ |___ |__/ 
78
  -- |__/ |___ |___ |__| |__/ |___ |  \ 
79
  -- -----------------------------------------------------
80
  -- ---------- 1. STAGE: FETCH AND DECODE ---------------
81
  signal instr_dec            : t_plasma_word;
82
 
83
  --
84
  -- operation decode
85
  --
86
  alias i_opcode_dec          : t_mips_opcode   is instr_dec(31 downto 26);
87
  alias i_format_dec          : t_mips_format   is instr_dec(20 downto 16);
88
  alias i_func_dec            : t_mips_function is instr_dec( 5 downto  0);
89
 
90
  --
91
  -- FPU operation code
92
  --
93
  alias i_fpu_fmt_dec         : t_mips_reg_addr is instr_dec(25 downto 21); -- i_rs_dec
94
  alias i_fpu_func_dec        : t_mips_function is i_func_dec;
95
  alias i_fpu_cc_dec          : t_mips_cc       is instr_dec(10 downto 8);
96
  alias i_fpu_tf_dec          : std_logic       is instr_dec(16);
97
 
98
  --
99
  -- register addresses
100
  --
101
  alias i_rs_dec              : t_mips_reg_addr is instr_dec(25 downto 21);
102
  alias i_rt_dec              : t_mips_reg_addr is instr_dec(20 downto 16);
103
  alias i_rd_dec              : t_mips_reg_addr is instr_dec(15 downto 11);
104
 
105
  alias i_fpu_rs_dec          : t_mips_reg_addr is i_rd_dec;
106
  alias i_fpu_rt_dec          : t_mips_reg_addr is i_rt_dec;
107
  alias i_fpu_rd_dec          : t_mips_reg_addr is instr_dec(10 downto 6);
108
 
109
  --
110
  -- operation units control
111
  --
112
  signal i_unit_ctrl          : t_plasma_subunits_ctrl;
113
  signal i_fpu_mode           : t_fpu_mode;
114
  signal i_mem_func           : t_mips_opcode;
115
 
116
  constant FUNC_INIT          : t_mips_opcode         := (others => '0');     -- do nothing
117
  constant SHIFT_INIT         : t_mips_opcode         := b"10_0000";
118
  constant COMP_INIT          : t_mips_opcode         := b"01_1000";
119
 
120
  --
121
  -- pipelined mux control
122
  --
123
  signal i_src_out_select     : t_src_out_select;
124
  signal i_wb_select          : t_wb_select;
125
 
126
  --
127
  -- register bank access
128
  --
129
  signal i_reg_addr           : t_reg_addr;
130
  signal i_fpu_reg_addr       : t_reg_addr;
131
 
132
  --
133
  -- intern flags
134
  --
135
  signal flag_pc_store        : std_logic;              -- store pc value
136
  signal flag_branch          : std_logic;              -- branch command
137
  signal flag_fpu_branch      : std_logic;              -- FPU branch command
138
  signal flag_fpu_mem         : std_logic;              -- FPU memory access command
139
 
140
  signal flag_mult_unit       : std_logic;              -- indicates mult operation
141
  signal flag_fpu_unit        : std_logic;              -- indicates fpu operation
142
  signal flag_fpu_stall       : std_logic;              -- FPU no memory command
143
 
144
  -- ---------- 2. STAGE: EXECUTE ------------------------
145
  --
146
  -- pipelined register bank access type
147
  --
148
  type t_reg_bank_access is
149
    record
150
      we                      : std_logic;
151
      rd                      : t_mips_reg_addr;
152
    end record;
153
 
154
  --
155
  -- unit control
156
  --
157
  signal ex_pc_func           : t_pc_function;          -- pc after branch evaluation
158
  signal i_ex_rd              : t_mips_reg_addr;        -- rd after branch evaluation
159
 
160
  signal reg_ex_unit_ctrl     : t_plasma_subunits_ctrl;
161
  signal reg_ex_mem_func      : t_mips_opcode;
162
 
163
  --
164
  -- mux control
165
  --
166
  signal reg_ex_src_out_sel   : t_src_out_select;
167
  signal reg_ex_wb_sel        : t_wb_select;
168
 
169
  --
170
  -- register bank access
171
  --
172
  signal reg_ex_rb            : t_reg_bank_access;
173
  signal reg_ex_fpu_rb        : t_reg_bank_access;
174
 
175
  --
176
  -- intern flags
177
  --
178
  signal reg_ex_pc_store      : std_logic;
179
  signal reg_flag_branch      : std_logic;
180
  signal reg_ex_fpu_branch    : std_logic;
181
  signal reg_ex_fpu_mem       : std_logic;
182
 
183
  -- ---------- 3. STAGE: MEMORY ACCESS ------------------
184
  --
185
  -- unit control
186
  --
187
  signal reg_mem_mem_func     : t_mips_opcode;
188
 
189
  --
190
  -- mux control
191
  --
192
  signal reg_mem_wb_sel       : t_wb_select;
193
 
194
  --
195
  -- register bank access
196
  --
197
  signal reg_mem_rb           : t_reg_bank_access;
198
  signal reg_mem_fpu_rb       : t_reg_bank_access;
199
 
200
  --
201
  -- intern flags
202
  --
203
  signal reg_mem_fpu_mem      : std_logic;
204
 
205
  -- ---------- 4. STAGE: WRITE BACK ---------------------
206
  --
207
  -- register bank access
208
  --
209
  signal reg_wb_rb            : t_reg_bank_access;
210
 
211
  -- ---------- FORWARDING -------------------------------
212
  type t_forward_stage_flag is
213
    record
214
      rd_zero   : std_logic;
215
      rs        : std_logic;
216
      rt        : std_logic;
217
    end record;
218
 
219
  type t_forward_flag is
220
    record
221
      ex        : t_forward_stage_flag;
222
      mem       : t_forward_stage_flag;
223
      wb        : t_forward_stage_flag;
224
    end record;
225
 
226
  signal forward_flags        : t_forward_flag;
227
 
228
  -- ---------- STALL LOGIC ------------------------------
229
  signal stall_ex_possible    : std_logic;              -- memory access in the previous command
230
  signal stall_ex_detect      : std_logic;              -- stall detection
231
  signal stall_unit_detect    : std_logic;              -- a unit causes stall
232
  signal stall_fpu_detect     : std_logic;              -- fpu stall detection
233
 
234
  signal i_stall              : std_logic;              -- intern stall flag
235
 
236
  -- ---------- BRANCH -----------------------------------
237
  signal branch_true          : std_logic;              -- branch should be taken
238
  signal fpu_branch_true      : std_logic;              -- FPU branch is true
239
 
240
  -- ---------- DEBUGGING --------------------------------
241
  --
242
begin
243
 
244
  -- --------------------------------------------------------------------------
245
  --  _____  ______ _____ ____  _____  ______ _____  
246
  -- |  __ \|  ____/ ____/ __ \|  __ \|  ____|  __ \ 
247
  -- | |  | | |__ | |   | |  | | |  | | |__  | |__) |
248
  -- | |  | |  __|| |   | |  | | |  | |  __| |  _  / 
249
  -- | |__| | |___| |___| |__| | |__| | |____| | \ \ 
250
  -- |_____/|______\_____\____/|_____/|______|_|  \_\
251
  -- --------------------------------------------------------------------------
252
  instr_dec                   <= instr_in;
253
 
254
  -- _     ____ ____ ___ ____ _  _    ____ _  _ ___     ___  ____ ____ ____ ___  ____ 
255
  -- | .   |___ |___  |  |    |__|    |__| |\ | |  \    |  \ |___ |    |  | |  \ |___ 
256
  -- | .   |    |___  |  |___ |  |    |  | | \| |__/    |__/ |___ |___ |__| |__/ |___ 
257
  -- --------------------------------------------------------------------------
258
  --
259
  -- UNIT and MUX control
260
  -- REGISTER BANK REGULAR ADDRESSES
261
  --
262
  -- ___  ____ ____ ____ ___  ____ 
263
  -- |  \ |___ |    |  | |  \ |___ 
264
  -- |__/ |___ |___ |__| |__/ |___ 
265
  decode_process:
266
  process( instr_dec )
267
    variable    clear_rb_access     : boolean   := FALSE;
268
  begin
269
    -- -------------------------------------------------------------------
270
    -- ___  ____ ____ ____ _  _ _    ___    _  _ ____ _    _  _ ____ ____ 
271
    -- |  \ |___ |___ |__| |  | |     |     |  | |__| |    |  | |___ [__  
272
    -- |__/ |___ |    |  | |__| |___  |      \/  |  | |___ |__| |___ ___] 
273
    -- -------------------------------------------------------------------
274
    --
275
    -- SUBCOMPONENTS CONTROL
276
    --
277
    i_unit_ctrl                   <= (pc_func     => PLASMA_PC_INC,
278
                                      alu_func    => i_opcode_dec,
279
                                      shift_func  => SHIFT_INIT,
280
                                      mult_func   => FUNC_INIT,
281
                                      comp_func   => COMP_INIT);
282
 
283
    -- FPU :
284
    fpu_ctrl.operation            <= MIPS_FUNC_FMT_MOV;  -- do nothing
285
    fpu_ctrl.c_reg                <= '0';     -- no FPU control register access
286
    fpu_ctrl.fix                  <= '0';     -- no inter conversion
287
    fpu_ctrl.double               <= '0';     -- single precision
288
 
289
    -- memory control
290
    i_mem_func                    <= i_opcode_dec;        -- pass opcode
291
 
292
    --
293
    -- MUX CONTROL
294
    --
295
    -- source mux control: 
296
    mux_ctrl.src_imm     <= IMM_SIGN;    -- IMMEDIATE = SIGN EXTENDED
297
    mux_ctrl.src_b_imm   <= B_IMM_ON;    -- PASS IMMEDIATE VALUE FOR 2. source
298
 
299
    -- FPU intern muxes
300
    mux_fpu.fpu_id      <= FPU_DATA_INTERN;  -- intern FPU data
301
 
302
    -- coprocessor mux
303
    mux_fpu.cop         <= COP_SELECT_CORE;  -- MAIN CORE
304
 
305
    -- units mux control
306
    i_src_out_select     <= SRC_OUT_ALU;    -- ALU output
307
 
308
    -- write back control
309
    i_wb_select          <= WB_OP_UNIT;     -- unit output
310
 
311
    --
312
    -- REBULAR REGISTER BANK
313
    --
314
    i_reg_addr          <= (we => '1',        -- write access enable
315
                            rs => i_rs_dec,   -- 1. source
316
                            rt => i_rt_dec,   -- target
317
                            rd => i_rt_dec);  -- destination
318
 
319
    clear_rb_access     := FALSE;         -- access to regular register bank
320
 
321
    --
322
    -- FPU REGISTER BANK
323
    --
324
    i_fpu_mode          <= FPU_MODE_NONE; -- NO FPU register bank access
325
    i_fpu_reg_addr      <= ( we => '0',
326
                            rs => i_fpu_rs_dec,
327
                            rt => i_fpu_rt_dec,
328
                            rd => i_fpu_rd_dec);
329
 
330
    --
331
    -- INTERN FLAGS
332
    --
333
    flag_pc_store        <= '0';          -- store next pc value by linked jumps, disabled
334
    flag_branch          <= '0';          -- no branch command
335
    flag_fpu_branch      <= '0';          -- FPU branch command
336
    flag_fpu_mem         <= '0';          -- FPU memory access command
337
 
338
    flag_mult_unit       <= '0';          -- no mult operation
339
    flag_fpu_unit        <= '0';          -- no FPU operation
340
    flag_fpu_stall       <= '0';          -- FPU no memmory access command
341
 
342
    --
343
    -- DEBUGGING
344
    --
345
--synthesis translate_off
346
    i_sim_control.sim_message(core_idx) <= '0';
347
    i_sim_control.sim_stop              <= '0';
348
    i_sim_control.print_message         <= '0';
349
    i_sim_control.sim_finish            <= '0';
350
    i_sim_control.track_en(core_idx)    <= '0';
351
    i_sim_control.track_mark            <= '0';
352
--synthesis translate_on
353
 
354
    -- ------------ OPERATION DECODE -------------------------------------------------------------------
355
    case i_opcode_dec is
356
      -- ----------- REGISTER FORMAT -------------------------------------------------------------------
357
      when MIPS_OPCODE_REG    =>
358
 
359
        mux_ctrl.src_b_imm        <= B_IMM_OF;                                                        -- DEFAULT: cut immediate value passing
360
        i_reg_addr.rd             <= i_rd_dec;                                                        -- DEFAULT: destination is on rd field
361
 
362
        case i_func_dec is
363
          -- ------------------------------------ SHIFTER ----------------------------------------------
364
          when MIPS_FUNC_SLL    |
365
               MIPS_FUNC_SRL    |
366
               MIPS_FUNC_SRA      => i_unit_ctrl.shift_func <= i_func_dec;                            -- pass function
367
 
368
                                     mux_ctrl.src_imm       <= IMM_SHAMT;                             -- shift amount for immediate mux
369
                                     mux_ctrl.src_b_imm     <= B_IMM_ON;                              -- pass immediate value
370
 
371
                                     i_src_out_select       <= SRC_OUT_SHIFT;                         -- output from shifter
372
 
373
                                     i_reg_addr.rs          <= i_rt_dec;                              -- source is on rt field
374
 
375
          when MIPS_FUNC_SLLV   |
376
               MIPS_FUNC_SRLV   |
377
               MIPS_FUNC_SRAV     => i_unit_ctrl.shift_func <= i_func_dec;                            -- pass function
378
 
379
                                     i_src_out_select       <= SRC_OUT_SHIFT;                         -- output from shifter
380
 
381
                                     i_reg_addr.rs          <= i_rt_dec;                              -- 1. and 2. source are switched
382
                                     i_reg_addr.rt          <= i_rs_dec;
383
 
384
          -- ------------------------------------ JUMP REGISTER ----------------------------------------
385
          when MIPS_FUNC_JR       => i_unit_ctrl.pc_func    <= PLASMA_PC_REG;                         -- pc operation code
386
 
387
                                     clear_rb_access        := TRUE;                                  -- no register bank access
388
 
389
          when MIPS_FUNC_JALR     => i_unit_ctrl.pc_func    <= PLASMA_PC_REG;                         -- pc operation code
390
                                     i_src_out_select       <= SRC_OUT_PC;                            -- output source select
391
 
392
                                     i_reg_addr.rd          <= MIPS_R_RA;                             -- return address
393
 
394
          -- ------------------------------------ INTERRUPTS -------------------------------------------
395
--synthesis translate_off     
396
          when MIPS_FUNC_SYSCALL  =>
397
              case( instr_dec(10 downto 6) ) is
398
                when b"00000"   => i_sim_control.sim_message(core_idx)  <= '1';
399
                when b"00001"   => i_sim_control.sim_stop               <= '1';
400
                when b"00010"   => i_sim_control.print_message          <= '1';
401
                when b"00011"   => i_sim_control.sim_finish             <= '1';
402
                when b"00100"   => i_sim_control.track_en(core_idx)     <= '1';
403
                when b"00101"   => i_sim_control.track_mark             <= '1';
404
                when others     =>
405
              end case;
406
--synthesis translate_on
407
          -- when MIPS_FUNC_BREAK    =>
408
 
409
          -- ------------------------------------ MULTIPLICATOR ----------------------------------------
410
          when MIPS_FUNC_MFHI   |
411
               MIPS_FUNC_MFLO     => i_unit_ctrl.mult_func  <= i_func_dec;                            -- pass function
412
 
413
                                     i_src_out_select       <= SRC_OUT_MULT;                          -- output from mult
414
 
415
                                     flag_mult_unit         <= '1';                                   -- possible unit stall
416
 
417
          when MIPS_FUNC_MTHI   |
418
               MIPS_FUNC_MTLO   |
419
               MIPS_FUNC_MULT   |
420
               MIPS_FUNC_MULTU  |
421
               MIPS_FUNC_DIV    |
422
               MIPS_FUNC_DIVU     => i_unit_ctrl.mult_func  <= i_func_dec;                            -- pass function
423
 
424
                                     clear_rb_access        := TRUE;                                  -- no register bank access
425
 
426
                                     flag_mult_unit         <= '1';                                   -- possible unit stall
427
 
428
          -- ------------------------------------ ALU --------------------------------------------------
429
          when MIPS_FUNC_ADD    |
430
               MIPS_FUNC_ADDU   |
431
               MIPS_FUNC_SUB    |
432
               MIPS_FUNC_SUBU   |
433
               MIPS_FUNC_AND    |
434
               MIPS_FUNC_OR     |
435
               MIPS_FUNC_XOR    |
436
               MIPS_FUNC_NOR    |
437
               MIPS_FUNC_SLT    |
438
               MIPS_FUNC_SLTU     =>   i_unit_ctrl.alu_func      <= i_func_dec;                      -- pass function to ALU                                                               -- pass command to ALU
439
 
440
          when others             =>
441
--synthesis translate_off
442
                                      report "WARNING:Unknown function code " & sv2string( i_func_dec );
443
--synthesis translate_on
444
        end case;
445
 
446
      -- ----------------------------------- COPROCESSOR 1 (FPU)----------------------------------------------
447
      when MIPS_OPCODE_COP1    =>
448
 
449
        clear_rb_access               := TRUE;                                                              -- no register bank access
450
 
451
        flag_fpu_unit                 <= '1';                                                               -- possible unit stall 
452
        flag_fpu_stall                <= '1';                                                               -- FPU no memory command
453
 
454
        case i_fpu_fmt_dec is
455
          -- ------------------------------------ FPU ALU OPERATION ------------------------------------
456
          when  MIPS_FMT_FLOAT_SINGLE |
457
                MIPS_FMT_FLOAT_DOUBLE |
458
                MIPS_FMT_FIXED_WORD =>
459
 
460
            fpu_ctrl.operation            <= i_fpu_func_dec;                                          -- pass FPU operation
461
 
462
            if i_fpu_fmt_dec = MIPS_FMT_FLOAT_DOUBLE then fpu_ctrl.double <= '1'; end if;             -- double precision operation
463
            if i_fpu_fmt_dec = MIPS_FMT_FIXED_WORD   then fpu_ctrl.fix    <= '1'; end if;             -- integer (fix point) operation
464
 
465
            i_fpu_reg_addr.we        <= '1';                                                          -- write to FPU register bank
466
 
467
            if std_match(i_fpu_func_dec, MIPS_FUNC_FMT_COND) then
468
              i_fpu_mode                <= FPU_MODE_C;                                                -- COMPARATOR operation
469
            else
470
              i_fpu_mode                <= FPU_MODE_ALU;                                              -- ALU operation
471
            end if;
472
 
473
          -- ------------------------------------ FPU BRANCH -------------------------------------------
474
          when MIPS_FMT_BRANCH    => mux_ctrl.src_imm         <= IMM_BRANCH;                          -- immediate mux control
475
 
476
                                     flag_branch              <= '1';                                 -- set branch flag
477
                                     flag_fpu_branch          <= '1';                                 -- set FPU branch flag 
478
 
479
          -- ------------------------------------ EXCHANGE DATA ----------------------------------------
480
          when MIPS_FMT_MTC       => mux_fpu.fpu_id           <= FPU_DATA_CORE;                       -- data from core
481
 
482
                                     i_fpu_mode               <= FPU_MODE_FGR;                        -- access to FPU register bank
483
                                     i_fpu_reg_addr.we        <= '1';                                 -- write enable
484
                                     i_fpu_reg_addr.rd        <= i_rd_dec;                            -- destination is on rd field
485
 
486
          when MIPS_FMT_CTC       => mux_fpu.fpu_id           <= FPU_DATA_CORE;                       -- data from core
487
 
488
                                     i_fpu_mode               <= FPU_MODE_CTC;                        -- access to FPU control register
489
                                     i_fpu_reg_addr.we        <= '1';                                 -- write enable
490
 
491
          when MIPS_FMT_MFC       => mux_fpu.cop              <= COP_SELECT_COP1;                     -- input data from FPU
492
                                     i_src_out_select         <= SRC_OUT_MEM_DATA;                    -- inject data from memory path
493
 
494
                                     i_reg_addr.we            <= '1';                                 -- write to regular register bank
495
                                     i_reg_addr.rd            <= i_rt_dec;                            -- destination is on rt field
496
                                     clear_rb_access          := FALSE;
497
 
498
          when MIPS_FMT_CFC       => mux_fpu.cop              <= COP_SELECT_COP1;                     -- input data from FPU
499
                                     i_src_out_select         <= SRC_OUT_MEM_DATA;                    -- inject data from memory path
500
 
501
                                     i_reg_addr.we            <= '1';                                 -- write to regular register bank
502
                                     i_reg_addr.rd            <= i_rt_dec;                            -- destination is on rt field
503
                                     clear_rb_access          := FALSE;
504
 
505
 
506
                                     fpu_ctrl.c_reg <= '1';                                           -- access to control register of FPU
507
 
508
          when others             =>
509
--synthesis translate_off
510
                                      report "WARNING:Unknown FPU function code " & sv2string( i_fpu_fmt_dec );
511
--synthesis translate_on
512
        end case;
513
 
514
      -- ------------------------------------ REGIMM ---------------------------------------------------
515
      when MIPS_OPCODE_REGIMM  =>
516
 
517
        i_unit_ctrl.comp_func      <= '0' & i_format_dec;                                             -- pass format
518
 
519
        mux_ctrl.src_imm           <= IMM_BRANCH;                                                     -- pass branch immediate value
520
 
521
        clear_rb_access            := TRUE;                                                           -- no register bank access
522
 
523
        flag_branch                <= '1';                                                            -- set branch command
524
 
525
        case i_format_dec is
526
          when MIPS_OPCODE_BLTZ |
527
               MIPS_OPCODE_BGEZ   =>                                                                  -- pass opcode
528
 
529
          when MIPS_OPCODE_BLTZAL  |
530
               MIPS_OPCODE_BGEZAL => i_src_out_select           <= SRC_OUT_PC;                        -- pc value as output source
531
 
532
                                     flag_pc_store              <= '1';                               -- set pc store flag 
533
 
534
          when others             =>
535
-- synthesis translate_off
536
                                     report "WARNING:Unknown format code " & sv2string( i_format_dec );
537
-- synthesis translate_on
538
        end case;
539
 
540
      when MIPS_OPCODE_BEQ    |
541
           MIPS_OPCODE_BNE    => i_unit_ctrl.comp_func      <= i_opcode_dec;                          -- pass function
542
 
543
                                 mux_ctrl.src_b_imm         <= B_IMM_OF;                              -- disable immediate pass
544
                                 mux_ctrl.src_imm           <= IMM_BRANCH;                            -- pass branch immediate
545
 
546
                                 clear_rb_access            := TRUE;                                  -- no register bank access
547
 
548
                                 flag_branch                <= '1';                                   -- set branch command
549
 
550
      when MIPS_OPCODE_BLEZ   |
551
           MIPS_OPCODE_BGTZ   => i_unit_ctrl.comp_func      <= i_opcode_dec;                          -- pass function
552
 
553
                                 mux_ctrl.src_imm           <= IMM_BRANCH;                            -- pass branch immediate
554
 
555
                                 clear_rb_access            := TRUE;                                  -- no register bank access
556
 
557
                                 flag_branch                <= '1';                                   -- set branch command
558
 
559
      -- ------------------------------------ ALU ------------------------------------------------------
560
      when MIPS_OPCODE_ADDI   |
561
           MIPS_OPCODE_ADDIU  |
562
           MIPS_OPCODE_SLTI   |
563
           MIPS_OPCODE_SLTIU  =>                                                                      -- pass operation code
564
 
565
      when MIPS_OPCODE_ANDI   |
566
           MIPS_OPCODE_ORI    |
567
           MIPS_OPCODE_XORI   => mux_ctrl.src_imm           <= IMM_UNSIGN;                            -- pass unsigned immediate
568
 
569
      when MIPS_OPCODE_LUI    => mux_ctrl.src_imm           <= IMM_HIGH;                              -- pass shifted immediate
570
 
571
      -- ------------------------------------ LOAD MEMORY ----------------------------------------------
572
      when MIPS_OPCODE_LB     |
573
           MIPS_OPCODE_LH     |
574
           MIPS_OPCODE_LWL    |
575
           MIPS_OPCODE_LW     |
576
           -- MIPS_OPCODE_LWR    |                                                                       -- COMPILER BUG !!
577
           MIPS_OPCODE_LBU    |
578
           MIPS_OPCODE_LHU    => i_unit_ctrl.alu_func       <= MIPS_FUNC_ADD;                         -- switch ALU to addition -> address calcultion
579
 
580
                                 i_wb_select                <= WB_MEMORY;                             -- pass memory data
581
 
582
      when MIPS_OPCODE_LWR    =>                                                                      -- DO NOTHING !!
583
 
584
                                 clear_rb_access            := TRUE;                                  -- no register bank access
585
 
586
      when MIPS_OPCODE_LWC1   => i_unit_ctrl.alu_func       <= MIPS_FUNC_ADD;                         -- switch ALU to addition -> address calcultion
587
 
588
                                 clear_rb_access            := TRUE;                                  -- no register bank access
589
                                 i_fpu_reg_addr.rd          <= i_rt_dec;                              -- destination is on rt field
590
 
591
                                 flag_fpu_mem               <= '1';                                   -- set FPU memory access flag
592
 
593
      -- ------------------------------------ STORE MEMORY ---------------------------------------------
594
      when MIPS_OPCODE_SB     |
595
           MIPS_OPCODE_SH     |
596
           MIPS_OPCODE_SWL    |
597
           MIPS_OPCODE_SW     |
598
           MIPS_OPCODE_SWR    => i_unit_ctrl.alu_func       <= MIPS_FUNC_ADD;                         -- switch ALU to addition -> address calcultion
599
 
600
                                 clear_rb_access            := TRUE;                                  -- no register bank access
601
 
602
      when MIPS_OPCODE_SWC1   => i_unit_ctrl.alu_func       <= MIPS_FUNC_ADD;                         -- switch ALU to addition -> address calcultion
603
 
604
                                 mux_fpu.cop                <= COP_SELECT_COP1;                       -- data from FPU
605
 
606
                                 clear_rb_access            := TRUE;                                  -- no register bank access
607
                                 i_fpu_reg_addr.rs          <= i_fpu_rt_dec;                          -- source is on rt field
608
 
609
      -- ------------------------------------ JUMP -----------------------------------------------------
610
      when MIPS_OPCODE_J      => i_unit_ctrl.pc_func        <= PLASMA_PC_IMM;                         -- pc = long immedate
611
 
612
                                 mux_ctrl.src_imm           <= IMM_JUMP;                              -- pass long immediate
613
 
614
                                 clear_rb_access            := TRUE;                                  -- no register bank access
615
 
616
      when MIPS_OPCODE_JAL    => i_unit_ctrl.pc_func        <= PLASMA_PC_IMM;                         -- pc = long immedate
617
 
618
                                 mux_ctrl.src_imm           <= IMM_JUMP;                              -- pass long immediate
619
                                 i_src_out_select           <= SRC_OUT_PC;                            -- pass pc value
620
 
621
                                 i_reg_addr.rd              <= MIPS_R_RA;                             -- return address
622
 
623
      when others             =>
624
--synthesis translate_off
625
                                report "Unknown opcode " & sv2string( i_opcode_dec );
626
--synthesis translate_on
627
    end case;
628
 
629
    --
630
    -- clear register bank access
631
    --
632
    if clear_rb_access then
633
      i_reg_addr.we     <= '0';                                               -- no write enable
634
      i_reg_addr.rd     <= MIPS_R_ZERO;                                       -- for forward logic
635
    end if;
636
  end process;
637
  -- --------------------------------------------------------------------------
638
 
639
  -- ____ ____ ____ _ _ _ ____ ____ ___  _ _  _ ____ 
640
  -- |___ |  | |__/ | | | |__| |__/ |  \ | |\ | | __ 
641
  -- |    |__| |  \ |_|_| |  | |  \ |__/ | | \| |__]
642
  --
643
  -- detect equal addresses
644
  --
645
  -- execution stage
646
  forward_flags.ex.rd_zero    <= '1'  when reg_ex_rb.rd = MIPS_R_ZERO  else '0';
647
  forward_flags.ex.rs         <= not forward_flags.ex.rd_zero   when i_reg_addr.rs = reg_ex_rb.rd   else '0';
648
  forward_flags.ex.rt         <= not forward_flags.ex.rd_zero   when i_reg_addr.rt = reg_ex_rb.rd   else '0';
649
 
650
  -- memory stage
651
  forward_flags.mem.rd_zero   <= '1'  when reg_mem_rb.rd = MIPS_R_ZERO  else '0';
652
  forward_flags.mem.rs        <= not forward_flags.mem.rd_zero  when i_reg_addr.rs = reg_mem_rb.rd  else '0';
653
  forward_flags.mem.rt        <= not forward_flags.mem.rd_zero  when i_reg_addr.rt = reg_mem_rb.rd  else '0';
654
 
655
  -- write back stage
656
  forward_flags.wb.rd_zero    <= '1'  when reg_wb_rb.rd = MIPS_R_ZERO  else '0';
657
  forward_flags.wb.rs         <= not forward_flags.wb.rd_zero   when i_reg_addr.rs = reg_wb_rb.rd   else '0';
658
  forward_flags.wb.rt         <= not forward_flags.wb.rd_zero   when i_reg_addr.rt = reg_wb_rb.rd   else '0';
659
 
660
  --
661
  -- set forwarded register bank addresses
662
  --
663
  forward_process:
664
  process( forward_flags )
665
  begin
666
    --
667
    -- -------- A SOURCE FORWARDING -----------------
668
    --
669
       if forward_flags.ex.rs   = '1' then  mux_ctrl.src_a  <=   SRC_OP_OUT;
670
    elsif forward_flags.mem.rs  = '1' then  mux_ctrl.src_a  <=   SRC_MEM_OUT;
671
    elsif forward_flags.wb.rs   = '1' then  mux_ctrl.src_a  <=   SRC_WB_OUT;
672
    else                                    mux_ctrl.src_a  <=   SRC_REG;
673
    end if;
674
 
675
    --
676
    -- -------- B SOURCE FORWARDING ------------------
677
    --
678
       if forward_flags.ex.rt   = '1' then  mux_ctrl.src_b  <=   SRC_OP_OUT;
679
    elsif forward_flags.mem.rt  = '1' then  mux_ctrl.src_b  <=   SRC_MEM_OUT;
680
    elsif forward_flags.wb.rt   = '1' then  mux_ctrl.src_b  <=   SRC_WB_OUT;
681
    else                                    mux_ctrl.src_b  <=   SRC_REG;
682
    end if;
683
  end process;
684
 
685
  -- ____ ___ ____ _    _       _    ____ ____ _ ____ 
686
  -- [__   |  |__| |    |       |    |  | | __ | |    
687
  -- ___]  |  |  | |___ |___    |___ |__| |__] | |___ 
688
  --
689
  -- 4. ID  EX  MEM  WB
690
  -- 3.     ID  EX   MEM  WB
691
  -- 2.         ID   EX   MEM  WB
692
  -- 1.              ID   EX   MEM  WB
693
  --                 /\
694
  --                 ||
695
  --
696
  -- data_stall: 1 + 2 + 3 remain in the corresponding stages 
697
  -- unit_stall: 1 + 2     remain in the corresponding stages
698
  -- ex_stall:   1         remain for 1 clock cycle in the ID stage
699
  -- prog_stall: 1         remain in the ID stage
700
  -- fpu_stall:  1         remain for 1 or 2 clock cycles in the ID stage
701
  --
702
  -- DETECTION:
703
  --
704
  -- prog_stall, data_stall: from memory
705
  -- unit_stall            : from subunits
706
  -- ex_stall              : destination address evaluation
707
  -- fpu_stall             : LWC1 command
708
  --
709
  stall_ex_possible           <= '1' when reg_ex_wb_sel   = WB_MEMORY else '0';                         -- previous command with memory access in execute stage
710
  stall_ex_detect             <= stall_ex_possible  and (forward_flags.ex.rs  or forward_flags.ex.rt);  -- fire only if stall possible
711
 
712
  stall_unit_detect           <= (flag_mult_unit and unit_busy.mult) or (flag_fpu_unit and unit_busy.fpu);-- current command accesses to busy unit
713
 
714
  stall_fpu_detect            <= flag_fpu_stall  and (reg_ex_fpu_mem or reg_mem_fpu_mem);               -- current command is FPU command and FPU to mem came previously
715
 
716
  --
717
  -- INTERN STALL
718
  --
719
  i_stall     <=    data_stall                      -- data cache stalls
720
                or  prog_stall                      -- instruction cache stalls
721
                or  stall_ex_detect                 -- data conflict with previous command
722
                or  stall_unit_detect               -- a unit is busy
723
                or  stall_fpu_detect;               -- fpu memory command
724
 
725
  --
726
  -- for DATAPATH stage registers control
727
  --
728
  stall_src.pc           <= i_stall;
729
  stall_src.data         <= data_stall;
730
  stall_src.unit         <= stall_unit_detect;
731
 
732
  -- --------------------------------------------------------------------------
733
  --  ____  _____            _   _  _____ _    _ 
734
  -- |  _ \|  __ \     /\   | \ | |/ ____| |  | |
735
  -- | |_) | |__) |   /  \  |  \| | |    | |__| |
736
  -- |  _ <|  _  /   / /\ \ | . ` | |    |  __  |
737
  -- | |_) | | \ \  / ____ \| |\  | |____| |  | |
738
  -- |____/|_|  \_\/_/    \_\_| \_|\_____|_|  |_|
739
  -- --------------------------------------------------------------------------
740
  --
741
  -- PROVIDE PC FUNCTION AND REGISTER BANK WRITE ADDRESS
742
  --
743
  --
744
  -- FPU branch evaluation
745
  --
746
  -- tf field indicates branch reference (true or false)
747
  -- this field should be equal with FPU flag cc (xor)
748
  -- if yes branch should be taken for appropriate command
749
  --
750
  fpu_branch_true             <= flag_fpu_branch and (not (fpu_cc xor i_fpu_tf_dec));
751
 
752
  --
753
  -- overall branch evaluation
754
  --
755
  branch_true                 <= reg_flag_branch and ( comp_out or reg_ex_fpu_branch );
756
 
757
  --
758
  -- branch process
759
  --
760
jump_branch_process:
761
  process( reg_ex_unit_ctrl.pc_func, reg_ex_rb.rd,
762
           branch_true,
763
           reg_ex_pc_store)
764
  begin
765
 
766
    ex_pc_func      <= reg_ex_unit_ctrl.pc_func;                             -- DEFAULT: decoded pc function
767
    i_ex_rd         <= reg_ex_rb.rd;                                         -- DEFAULT: decoded register bank address
768
 
769
  -- ---------- COMPARATOR OUTPUT -----------------
770
    if branch_true = '1' then                                                -- if branch should be taken
771
      ex_pc_func  <= PLASMA_PC_BRANCH;                                       -- PC should take calculated/immediate value
772
  -- ---------- PC STORE COMMAND ------------------
773
      if reg_ex_pc_store = '1' then                                          -- if pc value should be stored
774
        i_ex_rd   <= MIPS_R_RA;                                              -- set register bank write address to MIPS_RA
775
      end if;
776
 
777
    end if;
778
  end process;
779
 
780
  -- --------------------------------------------------------------------------
781
  --  _____ _____ _____  ______ _      _____ _   _ ______ 
782
  -- |  __ \_   _|  __ \|  ____| |    |_   _| \ | |  ____|
783
  -- | |__) || | | |__) | |__  | |      | | |  \| | |__   
784
  -- |  ___/ | | |  ___/|  __| | |      | | | . ` |  __|  
785
  -- | |    _| |_| |    | |____| |____ _| |_| |\  | |____ 
786
  -- |_|   |_____|_|    |______|______|_____|_| \_|______|
787
  -- --------------------------------------------------------------------------
788
  --
789
  -- PROVIDE PIPELINE REGISTERS
790
  --
791
pipeline_regs:
792
  process( control.clk )
793
  begin
794
    if rising_edge( control.clk ) then
795
      if control.rst = '1' then                                                   --  << RESET
796
        -- ############ << EXECUTION STAGE >> #################################
797
        reg_ex_unit_ctrl    <= (PLASMA_PC_INC, FUNC_INIT, SHIFT_INIT, FUNC_INIT, COMP_INIT );
798
        reg_ex_mem_func     <= FUNC_INIT;
799
 
800
        reg_ex_src_out_sel  <= SRC_OUT_ALU;
801
        reg_ex_wb_sel       <= WB_OP_UNIT;
802
 
803
        reg_ex_rb           <= ('0', MIPS_R_ZERO);
804
        reg_ex_fpu_rb       <= ('0', MIPS_R_ZERO);
805
 
806
        reg_ex_pc_store     <= '0';
807
        reg_flag_branch     <= '0';
808
        reg_ex_fpu_branch   <= '0';
809
        reg_ex_fpu_mem      <= '0';
810
 
811
        -- ############ << MEMORY STAGE >> ####################################
812
        reg_mem_mem_func    <= FUNC_INIT;
813
 
814
        reg_mem_wb_sel      <= WB_OP_UNIT;
815
 
816
        reg_mem_rb          <= ('0', MIPS_R_ZERO);
817
        reg_mem_fpu_rb      <= ('0', MIPS_R_ZERO);
818
 
819
        reg_mem_fpu_mem     <= '0';
820
 
821
        -- ############ << WRITE BACK STAGE >> ################################
822
        reg_wb_rb           <= ('0', MIPS_R_ZERO);
823
 
824
      else                                                                   -- << RISING_EDGE( CLK )
825
        -- ############ << EXECUTION STAGE >> #################################
826
        if i_stall = '0' then
827
          reg_ex_unit_ctrl    <= i_unit_ctrl;
828
          reg_ex_mem_func     <= i_mem_func;
829
 
830
          reg_ex_src_out_sel  <= i_src_out_select;
831
          reg_ex_wb_sel       <= i_wb_select;
832
 
833
          reg_ex_rb           <= (i_reg_addr.we, i_reg_addr.rd);
834
          reg_ex_fpu_rb       <= (i_fpu_reg_addr.we, i_fpu_reg_addr.rd);
835
 
836
          reg_ex_pc_store     <= flag_pc_store;
837
          reg_flag_branch     <= flag_branch;
838
          reg_ex_fpu_branch   <= fpu_branch_true;
839
        end if;
840
 
841
        if data_stall = '0' then                                            -- FPU stall should not stop this
842
          reg_ex_fpu_mem      <= flag_fpu_mem;
843
        end if;
844
 
845
        -- ############ << MEMORY STAGE >> ####################################
846
        if (data_stall = '0') and
847
           (stall_unit_detect = '0') then
848
          reg_mem_mem_func    <= reg_ex_mem_func;
849
          reg_mem_wb_sel      <= reg_ex_wb_sel;
850
 
851
          reg_mem_rb          <= (reg_ex_rb.we, i_ex_rd);
852
          reg_mem_fpu_rb      <= reg_ex_fpu_rb;
853
          reg_mem_fpu_mem     <= reg_ex_fpu_mem;
854
        end if;
855
 
856
        -- ############ << WRITE BACK STAGE >> ################################
857
        if data_stall = '0' then
858
          reg_wb_rb           <= reg_mem_rb;
859
        end if;
860
 
861
      end if;
862
    end if;
863
  end process;
864
 
865
  -- --------------------------------------------------------------------------
866
  --   ____  _    _ _______ _____  _    _ _______ _____ 
867
  --  / __ \| |  | |__   __|  __ \| |  | |__   __/ ____|
868
  -- | |  | | |  | |  | |  | |__) | |  | |  | | | (___  
869
  -- | |  | | |  | |  | |  |  ___/| |  | |  | |  \___ \ 
870
  -- | |__| | |__| |  | |  | |    | |__| |  | |  ____) |
871
  --  \____/ \____/   |_|  |_|     \____/   |_| |_____/ 
872
  -- --------------------------------------------------------------------------
873
  -- _     ___  ____ ____ ____ ___  ____ 
874
  -- | .   |  \ |___ |    |  | |  \ |___ 
875
  -- | .   |__/ |___ |___ |__| |__/ |___ 
876
  --
877
  -- DECODE STAGE OUTPUTS
878
  --
879
  reg_addr.rs                 <= i_reg_addr.rs;
880
  reg_addr.rt                 <= i_reg_addr.rt;
881
 
882
  fpu_reg_addr.rs             <= i_fpu_reg_addr.rs;
883
  fpu_reg_addr.rt             <= i_fpu_reg_addr.rt;
884
 
885
  fpu_reg_addr.we             <= i_fpu_reg_addr.we and (not i_stall)
886
                                                    when reg_mem_fpu_mem = '0' else '1';
887
  fpu_reg_addr.rd             <= i_fpu_reg_addr.rd  when reg_mem_fpu_mem = '0' else reg_mem_fpu_rb.rd;
888
 
889
  fpu_ctrl.mode               <= i_fpu_mode         when reg_mem_fpu_mem = '0' else FPU_MODE_FGR;
890
  mux_fpu.fpu_mem             <= FPU_DATA_INTERN    when reg_mem_fpu_mem = '0' else FPU_DATA_CORE;
891
 
892
  -- _ _     ____ _  _ ____ ____ _  _ ___ ____ 
893
  -- | | .   |___  \/  |___ |    |  |  |  |___ 
894
  -- | | .   |___ _/\_ |___ |___ |__|  |  |___ 
895
  --
896
  -- EXECUTE STAGE OUTPUTS
897
  --
898
  unit_ctrl                   <= (ex_pc_func, reg_ex_unit_ctrl.alu_func, reg_ex_unit_ctrl.shift_func,
899
                                  reg_ex_unit_ctrl.mult_func, reg_ex_unit_ctrl.comp_func);
900
 
901
  --
902
  -- MUX CONTROL
903
  --
904
  mux_ctrl.src_out            <= reg_ex_src_out_sel;                                   -- operation unit output mux control
905
 
906
 
907
  -- _ _ _     _  _ ____ _  _ ____ ____ _   _ 
908
  -- | | | .   |\/| |___ |\/| |  | |__/  \_/  
909
  -- | | | .   |  | |___ |  | |__| |  \   |   
910
  --
911
  -- MEMORY STAGE OUTPUTS
912
  --
913
  mem_func                    <= reg_mem_mem_func;                                     -- memory access function
914
 
915
  mux_ctrl.wb                 <= reg_mem_wb_sel;                                       -- memory output mux control
916
 
917
  -- _ _  _     _ _ _ ____ _ ___ ____    ___  ____ ____ _  _ 
918
  -- | |  | .   | | | |__/ |  |  |___    |__] |__| |    |_/  
919
  -- |  \/  .   |_|_| |  \ |  |  |___    |__] |  | |___ | \_ 
920
  --
921
  -- WRITE BACK STAGE OUTPUTS
922
  --
923
  reg_addr.rd                 <= reg_wb_rb.rd;                                         -- register bank write address
924
  reg_addr.we                 <= reg_wb_rb.we;                                         -- register bank write enable
925
 
926
end architecture structure_plasma_control_MIPSI_FPU;

powered by: WebSVN 2.1.0

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