rnumdec.v
7.12 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
/*
*************************************************************************
* *
* Copyright (C) 1994, Silicon Graphics, Inc. *
* *
* These coded instructions, statements, and computer programs contain *
* unpublished proprietary information of Silicon Graphics, Inc., and *
* are protected by Federal copyright law. They may not be disclosed *
* to third parties or copied or duplicated in any form, in whole or *
* in part, without the prior written consent of Silicon Graphics, Inc. *
* *
*************************************************************************
*/
// $Id: rnumdec.v,v 1.1 2002/03/28 00:26:14 berndt Exp $
// rnumdec.v: register address decode, 5->32, 4 times (or so)
// includes logic for write enable stability and transpose
`timescale 1ns / 10ps
// *** The read ports of the register file must always be driven (from
// *** Compass designer), so make sure exactly one decoded read line is
// *** active.
module rnumdec (clk, st_rnum, xp_rnum, ld_rnum, vd, wbv_wr_en, bwe, xpose, slice,
wb_div_type, wb_div_elem,
vurfile_ld_hi_t, vurfile_ld_hi_f, vurfile_ld_lo_t, vurfile_ld_lo_f,
vurfile_st_t, vurfile_st_f, vurfile_vd_t, vurfile_vd_f);
input clk;
input [4:0] st_rnum; // RD stage ST addr,
input [4:0] xp_rnum; // RD stage ST XPOSE addr
input [4:0] ld_rnum; // ACC stage LD addr
input [4:0] vd; // WB stage
input wbv_wr_en; // write enable for dp results,WB stage
input [1:0] bwe; // load port byte write enable,WB stage
input xpose;
input [2:0] slice;
input wb_div_type;
input [2:0] wb_div_elem;
output [31:0] vurfile_ld_hi_t;
output [31:0] vurfile_ld_hi_f;
output [31:0] vurfile_ld_lo_t;
output [31:0] vurfile_ld_lo_f;
output [31:0] vurfile_st_t;
output [31:0] vurfile_st_f;
output [31:0] vurfile_vd_t;
output [31:0] vurfile_vd_f;
wire [4:0] next_ld_rnum;
wire [31:0] vurfile_ls;
wire [31:0] vurfile_ls_bar;
wire [31:0] vurfile_ld_hi_bar;
wire [31:0] vurfile_ld_lo_bar;
wire [31:0] vurfile_vd_bar;
wire write_this;
/*
* function [31:0] rNumDecode;
* input [4:0] rNum;
* integer i;
* integer bitValue;
* begin
* rNumDecode = 0;
* bitValue = 1;
*
* for (i=0; i<32; i=i+1) begin
* if (rNum==i) rNumDecode = bitValue;
* bitValue = bitValue*2;
* end
* end
* endfunction
*/
// *** Check read port timing (store, vs, vt) for Compass; t/f skew
// store port
wire [4:0] actual_xpst_rnum;
wire [2:0] xpose_st_rnum;
wire vct_xposeadd0co_rd ; /* carry out of bit 0 of xpose adder */
wire vct_xposeadd1co_rd ; /* carry out of bit 1 of xpose adder */
wire vct_xposeadd2co_rd ; /* carry out of bit 2 of xpose adder - unused */
assign vct_xposeadd0co_rd = slice[0] && xp_rnum[0] ;
xo02d1h vctxposeadd0rd (
.z (xpose_st_rnum[0]),
.a1 (xp_rnum[0]),
.a2 (slice[0])
) ;
ad01d1h vctxposeadd1rd (
.co (vct_xposeadd1co_rd),
.s (xpose_st_rnum[1]),
.a (xp_rnum[1]),
.b (slice[1]),
.ci (vct_xposeadd0co_rd)
) ;
ad01d1h vctxposeadd2rd (
.co (vct_xposeadd2co_rd),
.s (xpose_st_rnum[2]),
.a (xp_rnum[2]),
.b (slice[2]),
.ci (vct_xposeadd1co_rd)
) ;
mx21d1h vctxposemx0rd (
.z (actual_xpst_rnum[0]),
.i0 (st_rnum[0]),
.i1 (xpose_st_rnum[0]),
.s (xpose)
) ;
mx21d1h vctxposemx1rd (
.z (actual_xpst_rnum[1]),
.i0 (st_rnum[1]),
.i1 (xpose_st_rnum[1]),
.s (xpose)
) ;
mx21d1h vctxposemx2rd (
.z (actual_xpst_rnum[2]),
.i0 (st_rnum[2]),
.i1 (xpose_st_rnum[2]),
.s (xpose)
) ;
mx21d1h vctxposemx3rd (
.z (actual_xpst_rnum[3]),
.i0 (st_rnum[3]),
.i1 (xp_rnum[3]),
.s (xpose)
) ;
mx21d1h vctxposemx4rd (
.z (actual_xpst_rnum[4]),
.i0 (st_rnum[4]),
.i1 (xp_rnum[4]),
.s (xpose)
) ;
regfile_decode decode_store ( .rNumdecode (vurfile_st_t),
.rNumdecode_b (vurfile_st_f),
.rNum (actual_xpst_rnum)
);
// load port
wire [2:0] xpose_ld_rnum;
wire [4:0] actual_ld_rnum;
wire vct_loadadd0co_rd ; /* carry out of bit 0 of load adder */
wire vct_loadadd1co_rd ; /* carry out of bit 1 of load adder */
wire vct_loadadd2co_rd ; /* carry out of bit 2 of load adder - unused */
assign vct_loadadd0co_rd = slice[0] && ld_rnum[0] ;
xo02d1h vctloadadd0rd (
.z (xpose_ld_rnum[0]),
.a1 (ld_rnum[0]),
.a2 (slice[0])
) ;
ad01d1h vctloadadd1rd (
.co (vct_loadadd1co_rd),
.s (xpose_ld_rnum[1]),
.a (ld_rnum[1]),
.b (slice[1]),
.ci (vct_loadadd0co_rd)
) ;
ad01d1h vctloadadd2rd (
.co (vct_loadadd2co_rd),
.s (xpose_ld_rnum[2]),
.a (ld_rnum[2]),
.b (slice[2]),
.ci (vct_loadadd1co_rd)
) ;
mx21d1h vctloadmx0rd (
.z (actual_ld_rnum[0]),
.i0 (ld_rnum[0]),
.i1 (xpose_ld_rnum[0]),
.s (xpose)
) ;
mx21d1h vctloadmx1rd (
.z (actual_ld_rnum[1]),
.i0 (ld_rnum[1]),
.i1 (xpose_ld_rnum[1]),
.s (xpose)
) ;
mx21d1h vctloadmx2rd (
.z (actual_ld_rnum[2]),
.i0 (ld_rnum[2]),
.i1 (xpose_ld_rnum[2]),
.s (xpose)
) ;
assign actual_ld_rnum[3] = ld_rnum[3] ;
assign actual_ld_rnum[4] = ld_rnum[4] ;
asdff #(5,0) ls_rnum_wr_x_ff(next_ld_rnum, actual_ld_rnum, clk, 1'b1);
regfile_decode decode_load ( .rNumdecode (vurfile_ls),
.rNumdecode_b (vurfile_ls_bar),
.rNum (next_ld_rnum)
);
/*
* assign xpose_ls_rnum = ls_rnum[2:0] + slice;
*
* assign actual_ls_rnum = xpose ? {ls_rnum[4:3],xpose_ls_rnum} : ls_rnum;
*
* assign vurfile_ls = rNumDecode(next_ls_rnum);
*/
/*
* assign vurfile_st_t = vurfile_ls;
* assign vurfile_st_f = vurfile_ls_bar;
*/
assign vurfile_ld_hi_bar = ~({32{bwe[1]}} & vurfile_ls);
assign vurfile_ld_lo_bar = ~({32{bwe[0]}} & ~vurfile_ls_bar);
rsp_lden32_t u_vurfile_ld_hi_t(
.en_t (vurfile_ld_hi_t),
.ld_bar (vurfile_ld_hi_bar),
.clk (clk)
);
rsp_lden32_f u_vurfile_ld_hi_f(
.en_f (vurfile_ld_hi_f),
.ld_bar (vurfile_ld_hi_bar),
.clk (clk)
);
rsp_lden32_t u_vurfile_ld_lo_t(
.en_t(vurfile_ld_lo_t),
.ld_bar(vurfile_ld_lo_bar),
.clk(clk)
);
rsp_lden32_f u_vurfile_ld_lo_f(
.en_f(vurfile_ld_lo_f),
.ld_bar(vurfile_ld_lo_bar),
.clk(clk)
);
/*
* The VS and VT address decoding is done in vuctl since it is
* not dependent on slice and can be shared between the two
* datapaths.
*/
// VD port
wire [31:0] vurfile_vd_dec;
wire [31:0] vurfile_vd_dec_bar;
regfile_decode decode_vd ( .rNumdecode (vurfile_vd_dec),
.rNumdecode_b (vurfile_vd_dec_bar),
.rNum (vd)
);
assign write_this = wbv_wr_en && (!wb_div_type ||(wb_div_elem==slice));
assign vurfile_vd_bar = ~(vurfile_vd_dec & {32{write_this}});
rsp_lden32_t u_vurfile_vd_t(
.en_t (vurfile_vd_t),
.ld_bar (vurfile_vd_bar),
.clk (clk)
);
rsp_lden32_f u_vurfile_vd_f(
.en_f (vurfile_vd_f),
.ld_bar (vurfile_vd_bar),
.clk (clk)
);
endmodule