1 |
83 |
jamey.hick |
|
2 |
|
|
// The MIT License
|
3 |
|
|
|
4 |
|
|
// Copyright (c) 2006-2007 Massachusetts Institute of Technology
|
5 |
|
|
|
6 |
|
|
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
7 |
|
|
// of this software and associated documentation files (the "Software"), to deal
|
8 |
|
|
// in the Software without restriction, including without limitation the rights
|
9 |
|
|
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
10 |
|
|
// copies of the Software, and to permit persons to whom the Software is
|
11 |
|
|
// furnished to do so, subject to the following conditions:
|
12 |
|
|
|
13 |
|
|
// The above copyright notice and this permission notice shall be included in
|
14 |
|
|
// all copies or substantial portions of the Software.
|
15 |
|
|
|
16 |
|
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
17 |
|
|
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
18 |
|
|
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
19 |
|
|
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
20 |
|
|
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
21 |
|
|
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
22 |
|
|
// THE SOFTWARE.
|
23 |
|
|
|
24 |
3 |
jamey.hick |
//This is a simple round robin memory scheduler. It's kind of bad because it's a CAM, but hey, don't have so many clients
|
25 |
|
|
|
26 |
|
|
package mkRoundRobinMemScheduler;
|
27 |
|
|
|
28 |
|
|
|
29 |
|
|
import MemControllerTypes::*;
|
30 |
|
|
import IMemScheduler::*;
|
31 |
|
|
import Vector::*;
|
32 |
|
|
|
33 |
|
|
module mkRoundRobinMemScheduler (IMemScheduler#(number_clients, address_type))
|
34 |
|
|
provisos
|
35 |
|
|
(Bits#(address_type, addr_p),
|
36 |
|
|
Eq#(address_type),
|
37 |
|
|
Bits#(MemReqType#(address_type), mem_req_type_p),
|
38 |
|
|
Eq#(MemReqType#(address_type))
|
39 |
|
|
);
|
40 |
|
|
Reg#(Bit#((TAdd#(1, TLog#(number_clients))))) first_index <- mkReg(0);
|
41 |
|
|
|
42 |
|
|
function Bit#(TAdd#(1, TLog#(number_clients))) next_index ( Bit#(TAdd#(1, TLog#(number_clients))) curr_index );
|
43 |
|
|
next_index = (curr_index < fromInteger(valueof(number_clients) - 1)) ? (curr_index + 1):(0);
|
44 |
|
|
endfunction: next_index
|
45 |
|
|
|
46 |
|
|
function Bit#(TAdd#(1, TLog#(number_clients))) prev_index ( Bit#(TAdd#(1, TLog#(number_clients))) curr_index );
|
47 |
|
|
prev_index = (curr_index > 0) ? (curr_index - 1):(fromInteger(valueof(number_clients) - 1));
|
48 |
|
|
endfunction: prev_index
|
49 |
|
|
|
50 |
|
|
method ActionValue#(Maybe#(Bit#(TAdd#(1, TLog#(number_clients))))) choose_client(Vector#(number_clients, MemReqType#(address_type)) req_vec);
|
51 |
|
|
Maybe#(Bit#(TAdd#(1,(TLog#(number_clients))))) target_index = tagged Invalid;
|
52 |
|
|
|
53 |
|
|
// Loop through command indicies backwards... this enables us to get the highest priority
|
54 |
|
|
// command.
|
55 |
|
|
for(Bit#((TAdd#(1, TLog#(number_clients)))) curr_index = prev_index(first_index), int count = 0;
|
56 |
|
|
count < fromInteger(valueof(number_clients));
|
57 |
|
|
curr_index = prev_index(curr_index), count = count + 1)
|
58 |
|
|
begin
|
59 |
|
|
if(req_vec[curr_index].req != tagged Nop)
|
60 |
|
|
begin
|
61 |
|
|
target_index = tagged Valid curr_index;
|
62 |
|
|
end
|
63 |
|
|
end
|
64 |
|
|
// set the next "high priority" index.
|
65 |
|
|
if(target_index matches tagged Valid .v)
|
66 |
|
|
begin
|
67 |
|
|
first_index <= next_index(v);
|
68 |
|
|
end
|
69 |
|
|
return target_index;
|
70 |
|
|
endmethod
|
71 |
|
|
endmodule
|
72 |
|
|
|
73 |
|
|
endpackage
|