1 |
2 |
dmitryr |
// ========== Copyright Header Begin ==========================================
|
2 |
|
|
//
|
3 |
|
|
// OpenSPARC T1 Processor File: sparc_ifu_imd.v
|
4 |
|
|
// Copyright (c) 2006 Sun Microsystems, Inc. All Rights Reserved.
|
5 |
|
|
// DO NOT ALTER OR REMOVE COPYRIGHT NOTICES.
|
6 |
|
|
//
|
7 |
|
|
// The above named program is free software; you can redistribute it and/or
|
8 |
|
|
// modify it under the terms of the GNU General Public
|
9 |
|
|
// License version 2 as published by the Free Software Foundation.
|
10 |
|
|
//
|
11 |
|
|
// The above named program is distributed in the hope that it will be
|
12 |
|
|
// useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
|
13 |
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
14 |
|
|
// General Public License for more details.
|
15 |
|
|
//
|
16 |
|
|
// You should have received a copy of the GNU General Public
|
17 |
|
|
// License along with this work; if not, write to the Free Software
|
18 |
|
|
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
|
19 |
|
|
//
|
20 |
|
|
// ========== Copyright Header End ============================================
|
21 |
|
|
////////////////////////////////////////////////////////////////////////
|
22 |
|
|
/*
|
23 |
|
|
// Module Name: sparc_ifu_imd
|
24 |
|
|
// Description:
|
25 |
|
|
// Contains the immediate operand datapath. Has two outputs: The
|
26 |
|
|
// simm data to the EXU and the branch offset to the IFU.
|
27 |
|
|
*/
|
28 |
|
|
|
29 |
|
|
|
30 |
|
|
module sparc_ifu_imd(/*AUTOARG*/
|
31 |
|
|
// Outputs
|
32 |
|
|
ifu_exu_imm_data_d, dtu_inst_d, ifu_exu_rd_d, ifu_lsu_rd_e,
|
33 |
|
|
ifu_lsu_imm_asi_d, ifu_tlu_imm_asi_d, ifu_lsu_imm_asi_vld_d, ifu_tlu_sraddr_d,
|
34 |
|
|
ifu_tlu_sraddr_d_v2, imd_dcl_brcond_d, imd_dcl_mvcond_d,
|
35 |
|
|
imd_dcl_abit_d, so, ifu_ffu_frs1_d, ifu_ffu_frs2_d, ifu_ffu_frd_d,
|
36 |
|
|
ifu_ffu_fpopcode_d, ifu_ffu_fcc_num_d,
|
37 |
|
|
// Inputs
|
38 |
|
|
rclk, se, si, fdp_dtu_inst_s, fcl_imd_oddwin_d,
|
39 |
|
|
dcl_imd_immdata_sel_simm13_d_l, dcl_imd_immdata_sel_movcc_d_l,
|
40 |
|
|
dcl_imd_immdata_sel_sethi_d_l, dcl_imd_immdata_sel_movr_d_l,
|
41 |
|
|
dcl_imd_broff_sel_call_d_l, dcl_imd_broff_sel_br_d_l,
|
42 |
|
|
dcl_imd_broff_sel_bcc_d_l, dcl_imd_broff_sel_bpcc_d_l,
|
43 |
|
|
dcl_imd_immbr_sel_br_d, dcl_imd_call_inst_d
|
44 |
|
|
);
|
45 |
|
|
|
46 |
|
|
input rclk,
|
47 |
|
|
se,
|
48 |
|
|
si;
|
49 |
|
|
|
50 |
|
|
input [31:0] fdp_dtu_inst_s; // instruction from fetch
|
51 |
|
|
|
52 |
|
|
input fcl_imd_oddwin_d; // are we in an even or odd window
|
53 |
|
|
|
54 |
|
|
input dcl_imd_immdata_sel_simm13_d_l, // imm data selects
|
55 |
|
|
dcl_imd_immdata_sel_movcc_d_l,
|
56 |
|
|
dcl_imd_immdata_sel_sethi_d_l,
|
57 |
|
|
dcl_imd_immdata_sel_movr_d_l;
|
58 |
|
|
|
59 |
|
|
input dcl_imd_broff_sel_call_d_l, // dir branch offset select
|
60 |
|
|
dcl_imd_broff_sel_br_d_l,
|
61 |
|
|
dcl_imd_broff_sel_bcc_d_l,
|
62 |
|
|
dcl_imd_broff_sel_bpcc_d_l;
|
63 |
|
|
|
64 |
|
|
input dcl_imd_immbr_sel_br_d; // use branch offset or simm data
|
65 |
|
|
input dcl_imd_call_inst_d;
|
66 |
|
|
|
67 |
|
|
output [31:0] ifu_exu_imm_data_d; // imm data to EXU
|
68 |
|
|
output [31:0] dtu_inst_d; // D stage inst to DEC
|
69 |
|
|
|
70 |
|
|
output [4:0] ifu_exu_rd_d,
|
71 |
|
|
ifu_lsu_rd_e;
|
72 |
|
|
|
73 |
|
|
output [7:0] ifu_lsu_imm_asi_d; // ASI for ldA and stA
|
74 |
|
|
output [8:0] ifu_tlu_imm_asi_d; // ASI for ldA and stA
|
75 |
|
|
output ifu_lsu_imm_asi_vld_d;
|
76 |
|
|
output [6:0] ifu_tlu_sraddr_d;
|
77 |
|
|
output [6:0] ifu_tlu_sraddr_d_v2;
|
78 |
|
|
output [3:0] imd_dcl_brcond_d;
|
79 |
|
|
output [7:0] imd_dcl_mvcond_d;
|
80 |
|
|
|
81 |
|
|
output imd_dcl_abit_d; // anull bit for cond branch
|
82 |
|
|
|
83 |
|
|
output so;
|
84 |
|
|
|
85 |
|
|
output [4:0] ifu_ffu_frs1_d,
|
86 |
|
|
ifu_ffu_frs2_d,
|
87 |
|
|
ifu_ffu_frd_d;
|
88 |
|
|
|
89 |
|
|
output [8:0] ifu_ffu_fpopcode_d;
|
90 |
|
|
output [1:0] ifu_ffu_fcc_num_d;
|
91 |
|
|
|
92 |
|
|
|
93 |
|
|
//-----------------------------------
|
94 |
|
|
// Declaration of local signals
|
95 |
|
|
//----------------------------------
|
96 |
|
|
wire [4:0] sraddr5;
|
97 |
|
|
|
98 |
|
|
wire [31:0] imm_data_d; // imm data
|
99 |
|
|
|
100 |
|
|
wire [31:0] dtu_inst_d,
|
101 |
|
|
simm13,
|
102 |
|
|
simm11,
|
103 |
|
|
simm10,
|
104 |
|
|
imm22,
|
105 |
|
|
dbr16,
|
106 |
|
|
dbcc22_nopred,
|
107 |
|
|
dbcc19_pred,
|
108 |
|
|
dcall,
|
109 |
|
|
broffset_d;
|
110 |
|
|
|
111 |
|
|
wire clk, ifu_lsu_imm_asi_vld_f;
|
112 |
|
|
|
113 |
|
|
|
114 |
|
|
//----------------------------------------------------------------------
|
115 |
|
|
// Code starts here
|
116 |
|
|
//----------------------------------------------------------------------
|
117 |
|
|
assign clk = rclk;
|
118 |
|
|
|
119 |
|
|
//--------
|
120 |
|
|
// S Stage
|
121 |
|
|
// Contains mostly random logic to help with decode in D stage
|
122 |
|
|
//--------
|
123 |
|
|
|
124 |
|
|
// Regfile operations:
|
125 |
|
|
// REMOVED
|
126 |
|
|
// assign ifu_exu_rs1_s = fdp_dtu_inst_s[18:14] ^
|
127 |
|
|
// {{fdp_dtu_inst_s[17] & dcl_imd_oddwin_s}, 4'b0000};
|
128 |
|
|
|
129 |
|
|
// assign ifu_exu_rs2_s = fdp_dtu_inst_s[4:0] ^
|
130 |
|
|
// {{fdp_dtu_inst_s[3] & dcl_imd_oddwin_s}, 4'b0000};
|
131 |
|
|
|
132 |
|
|
// assign ifu_exu_rs3_s = fdp_dtu_inst_s[29:25] ^
|
133 |
|
|
// {{fdp_dtu_inst_s[28] & dcl_imd_oddwin_s}, 4'b0000};
|
134 |
|
|
|
135 |
|
|
// assign imd_dcl_op_s = fdp_dtu_inst_s[31:30];
|
136 |
|
|
// assign imd_dcl_op3_s = fdp_dtu_inst_s[24:19];
|
137 |
|
|
|
138 |
|
|
//--------
|
139 |
|
|
// D stage
|
140 |
|
|
// Contains the immediate data and branch offset muxes
|
141 |
|
|
//--------
|
142 |
|
|
|
143 |
|
|
dff_s #(32) inst_d_reg(.din (fdp_dtu_inst_s),
|
144 |
|
|
.clk (clk),
|
145 |
|
|
.q (dtu_inst_d),
|
146 |
|
|
.se (se), .si(), .so());
|
147 |
|
|
|
148 |
|
|
dff_s #(1) ifu_lsu_imm_asi_inst(.din (fdp_dtu_inst_s[13]),
|
149 |
|
|
.clk (clk),
|
150 |
|
|
.q (ifu_lsu_imm_asi_vld_f),
|
151 |
|
|
.se (se), .si(), .so());
|
152 |
|
|
|
153 |
|
|
assign imd_dcl_abit_d = dtu_inst_d[29];
|
154 |
|
|
|
155 |
|
|
// imm data select
|
156 |
|
|
// sext12:0 -- add/sub/and/or/xor/taggedOP/jmpl/ld/store/atomic/div/mul/popc
|
157 |
|
|
// prefetch/return/restore/save/sir/wr/shft/flush
|
158 |
|
|
// !!!CAS does not use Imm data!!!
|
159 |
|
|
//
|
160 |
|
|
// sext10:0 -- movcc
|
161 |
|
|
// sext9:0 -- movr
|
162 |
|
|
// 21:0,10'b0 -- sethi
|
163 |
|
|
|
164 |
|
|
assign simm13 = {{19{dtu_inst_d[12]}},dtu_inst_d[12:0]};
|
165 |
|
|
assign simm11 = {{21{dtu_inst_d[10]}},dtu_inst_d[10:0]};
|
166 |
|
|
assign simm10 = {{22{dtu_inst_d[9]}},dtu_inst_d[9:0]};
|
167 |
|
|
assign imm22 = {dtu_inst_d[21:0], 10'b0};
|
168 |
|
|
|
169 |
|
|
dp_mux4ds #(32) immdata_mux(.dout (imm_data_d),
|
170 |
|
|
.in0 (simm13),
|
171 |
|
|
.in1 (simm11),
|
172 |
|
|
.in2 (simm10),
|
173 |
|
|
.in3 (imm22),
|
174 |
|
|
.sel0_l (dcl_imd_immdata_sel_simm13_d_l),
|
175 |
|
|
.sel1_l (dcl_imd_immdata_sel_movcc_d_l),
|
176 |
|
|
.sel2_l (dcl_imd_immdata_sel_movr_d_l),
|
177 |
|
|
.sel3_l (dcl_imd_immdata_sel_sethi_d_l));
|
178 |
|
|
|
179 |
|
|
|
180 |
|
|
// branch offset select
|
181 |
|
|
assign dbr16 = {{14{dtu_inst_d[21]}}, dtu_inst_d[21:20],
|
182 |
|
|
dtu_inst_d[13:0], 2'b0};
|
183 |
|
|
assign dbcc22_nopred = {{8{dtu_inst_d[21]}}, dtu_inst_d[21:0], 2'b0};
|
184 |
|
|
assign dbcc19_pred = {{11{dtu_inst_d[18]}}, dtu_inst_d[18:0], 2'b0};
|
185 |
|
|
assign dcall = {dtu_inst_d[29:0], 2'b0};
|
186 |
|
|
|
187 |
|
|
dp_mux4ds #(32) broffset_mux(.dout (broffset_d[31:0]),
|
188 |
|
|
.in0 (dcall[31:0]), // call
|
189 |
|
|
.in1 (dbr16[31:0]), // br on reg
|
190 |
|
|
.in2 (dbcc22_nopred[31:0]), // branch w/o pred
|
191 |
|
|
.in3 (dbcc19_pred[31:0]), // branch w/ pred
|
192 |
|
|
.sel0_l (dcl_imd_broff_sel_call_d_l),
|
193 |
|
|
.sel1_l (dcl_imd_broff_sel_br_d_l),
|
194 |
|
|
.sel2_l (dcl_imd_broff_sel_bcc_d_l),
|
195 |
|
|
.sel3_l (dcl_imd_broff_sel_bpcc_d_l));
|
196 |
|
|
|
197 |
|
|
dp_mux2es #(32) immbr_mux(.dout (ifu_exu_imm_data_d[31:0]),
|
198 |
|
|
.in0 (imm_data_d[31:0]),
|
199 |
|
|
.in1 (broffset_d[31:0]),
|
200 |
|
|
.sel (dcl_imd_immbr_sel_br_d));
|
201 |
|
|
|
202 |
|
|
// branch/move condition to dcl
|
203 |
|
|
assign imd_dcl_brcond_d = dtu_inst_d[28:25];
|
204 |
|
|
assign imd_dcl_mvcond_d = dtu_inst_d[17:10];
|
205 |
|
|
|
206 |
|
|
// if call instruction set rd = 0f (15)
|
207 |
|
|
assign ifu_exu_rd_d[3:0] = dtu_inst_d[28:25] | {4{dcl_imd_call_inst_d}};
|
208 |
|
|
assign ifu_exu_rd_d[4] = (dtu_inst_d[29] & ~dcl_imd_call_inst_d) ^
|
209 |
|
|
(ifu_exu_rd_d[3] & fcl_imd_oddwin_d);
|
210 |
|
|
|
211 |
|
|
dff_s #(5) rde_ff(.din (ifu_exu_rd_d[4:0]),
|
212 |
|
|
.clk (clk),
|
213 |
|
|
.q (ifu_lsu_rd_e[4:0]),
|
214 |
|
|
.se (se), .si(), .so());
|
215 |
|
|
|
216 |
|
|
// read/write pr and read/write sr
|
217 |
|
|
dp_mux2es #(5) sraddr_mux(.dout (sraddr5[4:0]),
|
218 |
|
|
.in0 (dtu_inst_d[18:14]), // rs1 for rdpr
|
219 |
|
|
.in1 (dtu_inst_d[29:25]), // rd for wrpr
|
220 |
|
|
.sel (dtu_inst_d[23]));
|
221 |
|
|
|
222 |
|
|
assign ifu_tlu_sraddr_d = {dtu_inst_d[19], // hpriv
|
223 |
|
|
{dtu_inst_d[20] & ~dtu_inst_d[19]}, // priv
|
224 |
|
|
sraddr5[4:0]};
|
225 |
|
|
assign ifu_tlu_sraddr_d_v2 = ifu_tlu_sraddr_d;
|
226 |
|
|
|
227 |
|
|
|
228 |
|
|
// asi fields for stA, ldA
|
229 |
|
|
// same as fpopcode_d
|
230 |
|
|
|
231 |
|
|
assign ifu_lsu_imm_asi_d[7:0] = dtu_inst_d[12:5];
|
232 |
|
|
assign ifu_tlu_imm_asi_d[8:0] = dtu_inst_d[13:5];
|
233 |
|
|
|
234 |
|
|
assign ifu_lsu_imm_asi_vld_d = ~ifu_lsu_imm_asi_vld_f;
|
235 |
|
|
|
236 |
|
|
// fp reg fields
|
237 |
|
|
assign ifu_ffu_frd_d = dtu_inst_d[29:25];
|
238 |
|
|
assign ifu_ffu_fcc_num_d = dtu_inst_d[26:25];
|
239 |
|
|
assign ifu_ffu_frs1_d = dtu_inst_d[18:14];
|
240 |
|
|
assign ifu_ffu_fpopcode_d = dtu_inst_d[13:5];
|
241 |
|
|
assign ifu_ffu_frs2_d = dtu_inst_d[4:0];
|
242 |
|
|
|
243 |
|
|
endmodule // sparc_ifu_imd
|