Initial commit of OpenSPARC T2 design and verification files.
[OpenSPARC-T2-DV] / verif / env / fnx / vlib / CTSupportClasses / src / CTRapIDManager.vr
CommitLineData
86530b38
AT
1// ========== Copyright Header Begin ==========================================
2//
3// OpenSPARC T2 Processor File: CTRapIDManager.vr
4// Copyright (C) 1995-2007 Sun Microsystems, Inc. All Rights Reserved
5// 4150 Network Circle, Santa Clara, California 95054, U.S.A.
6//
7// * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
8//
9// This program is free software; you can redistribute it and/or modify
10// it under the terms of the GNU General Public License as published by
11// the Free Software Foundation; version 2 of the License.
12//
13// This program is distributed in the hope that it will be useful,
14// but WITHOUT ANY WARRANTY; without even the implied warranty of
15// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16// GNU General Public License for more details.
17//
18// You should have received a copy of the GNU General Public License
19// along with this program; if not, write to the Free Software
20// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21//
22// For the avoidance of doubt, and except that if any non-GPL license
23// choice is available it will apply instead, Sun elects to use only
24// the General Public License version 2 (GPLv2) at this time for any
25// software where a choice of GPL license versions is made
26// available with the language indicating that GPLv2 or any later version
27// may be used, or where a choice of which version of the GPL is applied is
28// otherwise unspecified.
29//
30// Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
31// CA 95054 USA or visit www.sun.com if you need additional information or
32// have any questions.
33//
34// ========== Copyright Header End ============================================
35#include <vera_defines.vrh>
36#include "CTRapIDDefines.vri"
37
38// This class defines a manager that allocates tuples the form:
39//
40// <Device-ID><Packet-ID>
41//
42// where:
43//
44// Device-ID is a number that corresponds to one of N devices.
45//
46// Packet-ID is a number that corresponds to one of N
47// transactions from Device-ID.
48//
49// The combination of Device-ID and Packet-ID is guaranteed to
50// be unique in that the manager will not issue the same combination
51// until the previous instance has been deallocated.
52//
53// The assumption is that this class will be used to allocate raptor
54// request IDs, hence some of those assumptions are built into this class.
55// In particular, bit zero of the device ID is set to zero in all IDs
56// that are returned by the Allocate function. Also, bit zero of the
57// packet ID field is used to signify a read or write transaction.
58
59
60class CTRapIDManager {
61
62 integer Policy = CT_RANDOM_ALLOC;
63
64 //Packet-ID (PID) Pools. Separate pools allow two outstanding PIDs to
65 //differ only in bit zero, which gets tacked on after a PID is selected.
66 local bit [CT_NUMBER_OF_PKT_IDS-1:0] ReadPIDPool[CT_NUMBER_OF_DEVICES];
67 local bit [CT_NUMBER_OF_PKT_IDS-1:0] WritePIDPool[CT_NUMBER_OF_DEVICES];
68
69 local integer AllocSema;
70
71 ////////////////////////////////////// Public Methods /////////////////////////////////////////////////////
72
73 task new (bit [CT_NUMBER_OF_PKT_IDS-1:0] PIDMask = CT_PKT_ID_MASK_DEFAULT) {
74 integer Device;
75
76
77 if (PIDMask === 0)
78 error("CTRapIDManager(new)::At least one packet ID must be enabled\n");
79 else if ((^PIDMask) === 1'bx)
80 error("CTRapIDManager(new)::X-values are not allowed in packet ID mask\n");
81
82 AllocSema = alloc(SEMAPHORE,0,1,1);
83
84 if (AllocSema == 0)
85 error("CTRapIDManager:: Out of semaphore space.\n\n");
86
87
88 //Fill the PID Pools
89 for (Device=0; Device < CT_NUMBER_OF_DEVICES; ++Device) {
90 ReadPIDPool[Device] = PIDMask;
91 WritePIDPool[Device] = PIDMask;
92 }
93
94 }
95
96 function bit [CT_RAP_ID_WIDTH-1:0] Allocate (bit RW,
97 integer Timeout,
98 bit [CT_NUMBER_OF_DEVICES-1:0] DeviceMask = CT_DEVICE_MASK_DEFAULT
99 ) {
100 bit [CT_INTERNAL_DEVICE_ID_WIDTH-1:0] Device;
101 bit [CT_INTERNAL_PKT_ID_WIDTH-1:0] PID;
102
103 semaphore_get(WAIT, AllocSema, 1);
104
105 if (DeviceMask === 0)
106 error("CTRapIDManager(Allocate)::At least one active device must be specified\n");
107 else if ((^DeviceMask) === 1'bx)
108 error("CTRapIDManager(Allocate)::X-values are not allowed in device mask\n");
109
110 if (Timeout === 0)
111 error("CTRapIDManager(Allocate)::At least one cycle timeout window needed to select ID\n");
112
113 Device = SelectDevice(RW, Policy, Timeout, DeviceMask) ;
114
115
116 //This is a PID out of the read or write pool, depending on the value of RW.
117 //The final value of PID comes after appending RW bit.
118 PID = SelectPID(RW, Policy, Device);
119
120 //Take ID out of the pool
121
122 if (RW == CT_RAP_READ)
123 ReadPIDPool[Device] &= ~(1'b1 << PID);
124 else
125 WritePIDPool[Device] &= ~(1'b1 << PID);
126
127 //Bit zero of device ID always zero; Bit zero of packet ID specifies read or write
128 Allocate = {Device, 1'b0, PID, RW};
129
130 semaphore_put(AllocSema, 1);
131 }
132
133
134 task Deallocate (bit [CT_RAP_ID_WIDTH-1:0] ID) {
135 bit [CT_INTERNAL_DEVICE_ID_WIDTH-1:0] Device = ID[CT_DEVICE_ID_RANGE];
136 bit [CT_INTERNAL_PKT_ID_WIDTH-1:0] PID = ID[CT_PKT_ID_RANGE];
137
138 if ((^ID) === 1'bx)
139 error("CTRapIDManager(Deallocate)::X-values are not allowed in ID\n");
140
141 if (PID[0] == CT_RAP_READ)
142 ReadPIDPool[Device] |= (1'b1 << (PID >> 1));
143 else
144 WritePIDPool[Device] |= (1'b1 << (PID >> 1));
145 }
146
147
148 task SetPIDMask (bit [CT_NUMBER_OF_PKT_IDS-1:0] PIDMask) {
149 integer Device;
150
151 if (PIDMask === 0)
152 error("CTRapIDManager(SetPIDMask)::At least one packet ID must be enabled\n");
153 else if ((^PIDMask) === 1'bx)
154 error("CTRapIDManager(SetPIDMask)::X-values are not allowed in packet ID mask\n");
155
156 //Fill the PID Pools
157 for (Device=0; Device < CT_NUMBER_OF_DEVICES; ++Device) {
158 ReadPIDPool[Device] = PIDMask;
159 WritePIDPool[Device] = PIDMask;
160 }
161 }
162
163 ////////////////////////////////////// Private Methods /////////////////////////////////////////////////////
164
165 //It is assumed that Device has PIDs available before this function is called.
166 //Otherwise, SelectRandomPID will pull an error.
167 local function bit [CT_INTERNAL_PKT_ID_WIDTH-1:0] SelectPID(bit RW,
168 integer Policy,
169 bit [CT_INTERNAL_DEVICE_ID_WIDTH-1:0] Device) {
170 bit [CT_NUMBER_OF_PKT_IDS-1:0] PIDVector = (RW == CT_RAP_READ)? ReadPIDPool[Device]:WritePIDPool[Device];
171 bit [CT_INTERNAL_PKT_ID_WIDTH-1:0] PIDPosition;
172
173
174 case (Policy)
175 {
176 CT_RANDOM_ALLOC:
177 {
178 SelectPID = SelectRandomPID(PIDVector);
179 }
180 CT_SEQUENTIAL_ALLOC:
181 {
182 //The meaning of this is still unclear. Maybe random is the only thing that makes sense?
183
184 }
185
186 default: error("CTRapIDManager(Allocate)::Allocation policy unsupported!\n");
187 }
188 }
189
190 local function bit [CT_INTERNAL_DEVICE_ID_WIDTH-1:0] SelectDevice(bit RW,
191 integer Policy,
192 integer Timeout,
193 bit [CT_NUMBER_OF_DEVICES-1:0] DeviceMask) {
194 bit [CT_INTERNAL_DEVICE_ID_WIDTH-1:0] DevicePosition;
195 bit Done = 0;
196
197 case (Policy)
198 {
199 CT_RANDOM_ALLOC:
200 {
201 while (!Done && Timeout > 0) {
202
203 DevicePosition = SelectRandomDevice(DeviceMask);
204
205 if (PIDIsAvailable(DevicePosition, RW))
206 //No cycle time should expire if a PID is available for selected device
207 Done = 1;
208 else {
209 //Try again
210 --Timeout;
211 @(posedge CLOCK);
212 }
213 }
214
215 if (Timeout == 0)
216 error("CTRapIDManager(Allocate)::Allocation Timeout \n");
217
218 SelectDevice = DevicePosition;
219 }
220 CT_SEQUENTIAL_ALLOC:
221 {
222 //The meaning of this is still unclear. Maybe random is the only thing that makes sense?
223
224 }
225
226 default: error("CTRapIDManager(Allocate)::Allocation policy unsupported!\n");
227 }
228 }
229
230
231 //Return true is at least one PID is available at DevicePosition
232 local function bit PIDIsAvailable (bit [CT_INTERNAL_DEVICE_ID_WIDTH-1:0] DevicePosition, bit RW) {
233
234 if (RW == CT_RAP_READ)
235 PIDIsAvailable = (ReadPIDPool[DevicePosition])? 1'b1: 1'b0;
236 else
237 PIDIsAvailable = (WritePIDPool[DevicePosition])? 1'b1: 1'b0;
238 }
239
240//----------------------------------------------------------------------------------------------------------
241// function: SelectRandomDevice
242// Return any number with its corresponding bit set in the argument SetVector
243//----------------------------------------------------------------------------------------------------------
244 local function bit[CT_INTERNAL_DEVICE_ID_WIDTH-1:0] SelectRandomDevice (bit [CT_NUMBER_OF_DEVICES-1:0] SetVector) {
245 integer i, j;
246
247 j = 0;
248 for (i = 0; i < CT_NUMBER_OF_DEVICES; i++) j = j + ((SetVector >> i) & 1'b1);
249 if (j == 0)
250 error ("SelectRandomDevice: set empty\n");
251 j = random() % j;
252
253 for (i = 0; i < CT_NUMBER_OF_DEVICES; i++)
254 if (((SetVector >> i) & 1'b1) == 1'b1)
255 {
256 if (j == 0) SelectRandomDevice = i;
257 j = j - 1;
258 }
259 }
260
261//----------------------------------------------------------------------------------------------------------
262// function: SelectRandomPID
263// Return any number with its corresponding bit set in the argument SetVector
264//----------------------------------------------------------------------------------------------------------
265 local function bit[CT_INTERNAL_PKT_ID_WIDTH-1:0] SelectRandomPID (bit [CT_NUMBER_OF_PKT_IDS-1:0] SetVector) {
266 integer i, j;
267
268 j = 0;
269 for (i = 0; i < CT_NUMBER_OF_PKT_IDS; i++) j = j + ((SetVector >> i) & 1'b1);
270 if (j == 0)
271 error ("SelectRandomTid: set empty\n");
272 j = random() % j;
273
274 for (i = 0; i < CT_NUMBER_OF_PKT_IDS; i++)
275 if (((SetVector >> i) & 1'b1) == 1'b1)
276 {
277 if (j == 0) SelectRandomPID = i;
278 j = j - 1;
279 }
280 }
281
282}
283
284
285
286