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

Subversion Repositories oops

[/] [oops/] [trunk/] [rtl/] [id_stage.v] - Blame information for rev 2

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 smjoshua
//////////////////////////////////////////////////////////////////
2
//                                                              //
3
//  OoOPs Core Instruction Decode module                        //
4
//                                                              //
5
//  This file is part of the OoOPs project                      //
6
//  http://www.opencores.org/project,oops                       //
7
//                                                              //
8
//  Description:                                                //
9
//  Handles basic decoding of instruction type and register     //
10
//  sources and destinations for Dispatch stages.               //
11
//  We could do full instruction decoding in this stage, but    //
12
//  to save on pipeline flops we will only decode what is needed//
13
//  for dispatch.  We can use the issue stage to do necessary   // 
14
//  decoding for each functional unit.                          //
15
//                                                              //
16
//  Author(s):                                                  //
17
//      - Joshua Smith, smjoshua@umich.edu                      //
18
//                                                              //
19
//////////////////////////////////////////////////////////////////
20
//                                                              //
21
// Copyright (C) 2012 Authors and OPENCORES.ORG                 //
22
//                                                              //
23
// This source file may be used and distributed without         //
24
// restriction provided that this copyright statement is not    //
25
// removed from the file and that any derivative work contains  //
26
// the original copyright notice and the associated disclaimer. //
27
//                                                              //
28
// This source file is free software; you can redistribute it   //
29
// and/or modify it under the terms of the GNU Lesser General   //
30
// Public License as published by the Free Software Foundation; //
31
// either version 2.1 of the License, or (at your option) any   //
32
// later version.                                               //
33
//                                                              //
34
// This source is distributed in the hope that it will be       //
35
// useful, but WITHOUT ANY WARRANTY; without even the implied   //
36
// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR      //
37
// PURPOSE.  See the GNU Lesser General Public License for more //
38
// details.                                                     //
39
//                                                              //
40
// You should have received a copy of the GNU Lesser General    //
41
// Public License along with this source; if not, download it   //
42
// from http://www.opencores.org/lgpl.shtml                     //
43
//                                                              //
44
//////////////////////////////////////////////////////////////////
45
`include "ooops_defs.v"
46
 
47
module id_stage (
48
  input wire                      clk,
49
  input wire                      rst,
50
 
51
  // Flush/stall interface
52
  input wire                      rob_pipe_flush,
53
  input wire                      ds_stall,
54
 
55
  // Interface to IF stage
56
  input wire                      if_id_valid,
57
  input wire  [`INSTR_SZ-1:0]     if_id_instr,
58
  input wire  [`ADDR_SZ-1:0]      if_id_fpc,
59
  input wire  [`BP_SZ-1:0]        if_id_bprd_info,
60
 
61
  // Interface to Dispatch stage
62
  output wire                     id_ds1_valid,
63
  output wire [`ADDR_SZ-1:0]      id_ds1_fpc,
64
  output wire                     id_ds1_in_dly_slot,
65
  output wire [`DEC_BUS_SZ-1:0]   id_ds1_dec_bus,
66
  output wire [`BP_SZ-1:0]        id_ds1_bprd_info
67
  );
68
 
69
  // Internal wires
70
  wire                    id_type_br;
71
  wire                    id_type_ldst;
72
  wire                    id_type_multdiv;
73
  wire                    id_type_alu;
74
  wire [`DEC_BUS_SZ-1:0]  id_dec_bus;
75
  wire                    id_rs_need;
76
  wire                    id_rt_need;
77
  wire                    id_rd_write;
78
  wire [`REG_IDX_SZ-1:0]  id_rs_idx;
79
  wire [`REG_IDX_SZ-1:0]  id_rt_idx;
80
  wire [`REG_IDX_SZ-1:0]  id_rd_idx;
81
 
82
  // Handle stalling indications
83
  wire id_stall     = ds_stall;
84
 
85
  // Determine basic instruction type
86
  wire id_instr_special   = ~(|if_id_instr[31:26]);
87
 
88
  // MULT/DIV
89
  wire id_mult           = (id_instr_special & if_id_instr[5:1]==5'b01100);
90
  wire id_div            = (id_instr_special & if_id_instr[5:1]==5'b01101);
91
  assign id_type_multdiv = id_mult | id_div;
92
 
93
  // LDST
94
  wire id_mem_ld      = (if_id_instr[31:29]==3'b100) && (~if_id_instr[27] | (if_id_instr[28:26]==3'b011));
95
  wire id_mem_st      = (if_id_instr[31:28]==4'b1010) && (if_id_instr[27:26]!=2'b10);
96
  assign id_type_ldst = id_mem_ld || id_mem_st;
97
 
98
  // Branch
99
  wire id_br_beq      = (if_id_instr[31:27]==5'b00010);
100
  wire id_br_bge      = (if_id_instr[31:26]==6'b000001) && (if_id_instr[20:17]==4'b0000);
101
  wire id_br_bgt      = (if_id_instr[31:27]==5'b00011) && (if_id_instr[20:16]==5'b00000);
102
  wire id_br_neg      = (id_br_beq && if_id_instr[26]) ||   // BNE
103
                        (id_br_bge && if_id_instr[17]) ||   // BLTZ
104
                        (id_br_bgt && !if_id_instr[26]);    // BLEZ
105
  wire id_br_j        = (if_id_instr[31:27]==5'b00001);
106
  wire id_br_jr       = id_instr_special && (if_id_instr[5:1]==5'b00100);
107
  wire id_br_link     = (id_br_bge && if_id_instr[20]) ||   // BGEZAL, BLTZAL
108
                        (id_br_j   && if_id_instr[16]);     // JAL
109
  wire id_br_link_reg = (id_br_jr  && if_id_instr[0]);      // JALR
110
  wire id_except      = id_instr_special && (if_id_instr[5:1]==5'b00110);
111
  //wire id_break       = id_except && if_id_instr[0];
112
  wire id_syscall     = id_except && !if_id_instr[0];
113
  assign id_type_br   = (id_br_beq | id_br_bge | id_br_bgt | id_br_j | id_br_jr | id_except);
114
 
115
  // ALU
116
  wire id_alu_shift     = id_instr_special && (if_id_instr[5:3]==3'b000);
117
  wire id_alu_shift_imm = id_alu_shift & !if_id_instr[2];
118
  wire id_alu_cmp       = (id_instr_special && if_id_instr[5:1]==5'b10101) || // SLT/SLTU
119
                          (if_id_instr[31:27]==5'b00101);                     // SLTI/SLTIU
120
  wire id_alu_log_reg   = id_instr_special && (if_id_instr[5:2]==4'b1001);
121
  wire id_alu_log_imm   = (if_id_instr[31:28]==4'b0011) && !(&if_id_instr[27:26]);
122
  wire id_hilo_mov      = id_instr_special & (if_id_instr[5:2]==4'b0100);
123
  wire id_mfhi          = id_hilo_mov & (if_id_instr[1:0]==2'b00);
124
  wire id_mflo          = id_hilo_mov & (if_id_instr[1:0]==2'b10);
125
  wire id_mthi          = id_hilo_mov & (if_id_instr[1:0]==2'b01);
126
  wire id_mtlo          = id_hilo_mov & (if_id_instr[1:0]==2'b11);
127
  wire id_alu_add_sub   = (id_instr_special && (if_id_instr[5:2]==4'b1000)) ||    // ADD/SUB Reg
128
                          (if_id_instr[31:27]==5'b00100);                         // ADDI
129
  wire id_alu_lui       = (if_id_instr[31:26]==6'b001111);
130
 
131
  // Coprocessor ops included
132
  wire id_cp_op   = (if_id_instr[31:26]==6'b010000) && !(|if_id_instr[25:24]) && !(|if_id_instr[22:21]);
133
  wire id_cp_to   = id_cp_op && if_id_instr[23];
134
  //wire id_cp_num  = if_id_instr[27:26];
135
 
136
  assign id_type_alu = id_alu_shift | id_alu_cmp | id_alu_log_reg | id_alu_log_imm |
137
                       id_type_br | id_hilo_mov | id_alu_add_sub | id_alu_lui | id_cp_op;
138
 
139
 
140
 
141
  // Determine register indices
142
  // Figure out whether operands require register values.
143
  // This is so we know whether to stall for forwarded data for an operand
144
  // For ALU operations, all but LUI need reg_s.  Immediate instructions don't need reg_t
145
  assign id_rs_need = (id_type_alu & !id_alu_lui & !id_br_j) |
146
                      (id_alu_shift & !id_alu_shift_imm) |
147
                      (id_div | id_mult) |
148
                      (id_type_ldst);
149
  assign id_rt_need = (id_type_alu & !id_alu_imm) | id_type_multdiv | id_br_beq | id_cp_to | id_mem_st;
150
  assign id_rd_wr   = !(id_mem_st | (id_type_br & !id_br_link) | id_cp_to | id_syscall);
151
 
152
  // Handle moves to/from HI and LO
153
  assign id_rs_idx = id_mfhi ? `REG_IDX_SZ'd32 :
154
                     id_mflo ? `REG_IDX_SZ'd33 : id_reg_s_idx_pre;
155
  assign id_rt_idx = id_reg_t_idx_pre;
156
  assign id_rd_idx = id_mthi ? `REG_IDX_SZ'd32 :
157
                     id_mtlo ? `REG_IDX_SZ'd33 : id_reg_d_idx_pre;
158
 
159
  // Determine if instructions are in a delay slot
160
  // This is needed by the ROB in case a branch is mispredicted so we know not to flush the delay instruction.
161
  wire id_in_dly_slot_set = !id_stall & (if_id_valid & id_type_br);
162
  wire id_in_dly_slot_rst = !id_stall & (if_id_valid & id_in_dly_slot);
163
  wire id_in_dly_slot_in  = (id_in_dly_slot_set | id_in_dly_slot) & !id_in_dly_slot_rst;
164
  MDFFR #(1) id_in_dly_slot_ff (clk, rst, 1'b0, id_in_dly_slot_in, id_in_dly_slot);
165
 
166
  wire id_in_dly_slot = if_id_valid & id_in_dly_slot;
167
 
168
  // Put together decode bus
169
  assign id_dec_bus[`DEC_REG_D_IDX]     = id_rd_idx;
170
  assign id_dec_bus[`DEC_REG_T_IDX]     = id_rt_idx;
171
  assign id_dec_bus[`DEC_REG_S_IDX]     = id_rs_idx;
172
  assign id_dec_bus[`DEC_REG_D_WR]      = id_rd_wr;
173
  assign id_dec_bus[`DEC_REG_T_NEED]    = id_rt_need;
174
  assign id_dec_bus[`DEC_REG_S_NEED]    = id_rs_need;
175
  assign id_dec_bus[`DEC_TYPE_CP]       = id_cp_op;
176
  assign id_dec_bus[`DEC_TYPE_BR]       = id_type_br;
177
  assign id_dec_bus[`DEC_TYPE_LDST]     = id_type_ldst;
178
  assign id_dec_bus[`DEC_TYPE_MULTDIV]  = id_type_multdiv;
179
  assign id_dec_bus[`DEC_TYPE_ALU]      = id_type_alu;
180
 
181
  wire id_valid = if_id_valid & !rob_pipe_flush;
182
 
183
  // Flop outputs to DS stage
184
  MDFFLR #(1)           id_ds1_valid_ff       (clk, rst, !id_stall, 1'b0, id_valid, id_ds1_valid);
185
  MDFFL  #(`ADDR_SZ)    id_ds1_fpc_ff         (clk, if_id_valid, if_id_fpc, id_ds1_fpc);
186
  MDFFLR #(1)           id_ds1_in_dly_slot_ff (clk, rst, if_id_valid, 1'b0, id_in_dly_slot, id_ds1_in_dly_slot);
187
  MDFFL  #(`DEC_BUS_SZ) id_ds1_dec_bus_ff     (clk, if_id_valid, id_dec_bus, id_ds1_dec_bus);
188
  MDFFL  #(`BP_SZ)      id_ds1_bprd_info_ff   (clk, if_id_valid, if_id_bprd_info, id_ds1_bprd_info);
189
 
190
endmodule

powered by: WebSVN 2.1.0

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