| module arbiter(clock, reset, roundORpriority, request, tpriority, grant); | |
| integer i,j,k,p,q,r,s,t,u,v; //index for "for" loops | |
| //------------------------------------------------------------------------ | |
| // parameters | |
| //------------------------------------------------------------------------ | |
| parameter NUMUNITS = 8; | |
| parameter ADDRESSWIDTH = 3; //number of bits needed to address NUMUNITS | |
| //------------------------------------------------------------------------ | |
| // input and output declarations | |
| //------------------------------------------------------------------------ | |
| input clock; | |
| input reset; | |
| input roundORpriority; | |
| input [NUMUNITS-1 : 0] request; | |
| input [ADDRESSWIDTH*NUMUNITS-1 : 0] tpriority; | |
| output [NUMUNITS-1 : 0] grant; | |
| //hack for 2-D input | |
| reg [ADDRESSWIDTH-1 : 0] prio [NUMUNITS-1 : 0]; | |
| reg [ADDRESSWIDTH-1 : 0] tmp_prio; | |
| always@(tpriority) | |
| begin | |
| for (i=0; i<NUMUNITS; i=i+1) | |
| begin | |
| for (j=0; j<ADDRESSWIDTH; j=j+1) | |
| tmp_prio[j] = tpriority[i*ADDRESSWIDTH + j]; | |
| prio[i] = tmp_prio; | |
| end | |
| end | |
| reg [NUMUNITS-1 : 0] grant; //registered output | |
| reg [NUMUNITS-1 : 0] grantD; //input to "grant" flip-flop | |
| reg [ADDRESSWIDTH-1 : 0] next; //index of next unit in round-robin | |
| reg [ADDRESSWIDTH-1 : 0] nextNext; //input to "next" flip-flop | |
| reg [ADDRESSWIDTH-1 : 0] scan [NUMUNITS-1 : 0]; | |
| //stores info on the order in which to scan units for round-robin | |
| reg [NUMUNITS-2 : 0] found; | |
| //in round-robin search, stores info on where assignment is made | |
| reg [ADDRESSWIDTH-1 : 0] selectPrio[NUMUNITS-1 : 0]; | |
| //holds the priorities of only those units requesting the bus | |
| reg [ADDRESSWIDTH-1 : 0] min; | |
| //holds the minimum priority of all units currently requesting the bus | |
| reg [NUMUNITS-1 : 0] minPrio; | |
| //units that have the minimum priority | |
| wire [NUMUNITS-1 : 0] prioRequest; | |
| //request signals for only those units with minimum priority | |
| reg [NUMUNITS-1 : 0] finalRequest; | |
| //requests actually examined depending on "roundORpriority" | |
| // flip-flop for "grant" signals | |
| always@(posedge clock) | |
| begin | |
| if(!reset) grant <= 0; | |
| else grant <= grantD; | |
| end | |
| // flip-flop for "next" register | |
| always@(posedge clock) | |
| begin | |
| if(!reset) next <= 0; | |
| else next <= nextNext; | |
| end | |
| //selects the priorities of units sending requests | |
| always@(request or prio[7] or prio[6] or prio[5] or prio[4] or | |
| prio[3] or prio[2] or prio[1] or prio[0]) | |
| begin | |
| for(k=0; k<NUMUNITS; k=k+1) | |
| selectPrio[k] = request[k] ? prio[k] : NUMUNITS-1; | |
| end | |
| //selects priority or round robin operation | |
| always@(prioRequest or request or roundORpriority) | |
| begin | |
| for(r=0; r<NUMUNITS; r=r+1) | |
| finalRequest[r] = roundORpriority ? prioRequest[r] : | |
| request[r]; | |
| end | |
| //this logic finds the minimum priority out of all units sending a | |
| //request | |
| always@(selectPrio[7] or selectPrio[6] or selectPrio[5] or | |
| selectPrio[4] or selectPrio[3] or selectPrio[2] or | |
| selectPrio[1] or selectPrio[0]) | |
| begin | |
| min = selectPrio[0]; | |
| for (p=1; p<NUMUNITS; p=p+1) | |
| if (selectPrio[p] < min) min = selectPrio[p]; | |
| end | |
| //this logic decides if the units have minimum priority | |
| always@(min or minPrio or prio[7] or prio[6] or prio[5] or prio[4] | |
| or prio[3] or prio[2] or prio[1] or prio[0]) | |
| begin | |
| for(q=0; q<NUMUNITS; q=q+1) | |
| minPrio[q] = (prio[q]==min) ? 1:0; | |
| end | |
| //produces request signals for units that have minimum priority | |
| assign prioRequest = minPrio & request; | |
| //produces the "scan" array | |
| always@(next) | |
| begin | |
| for(s=0; s<NUMUNITS; s=s+1) | |
| scan[s] = (next+s < NUMUNITS) ? next+s : next+s-NUMUNITS; | |
| end | |
| //produces the "found" array | |
| always@(finalRequest or scan[7] or scan[6] or scan[5] or scan[4] or | |
| scan[3] or scan[2] or scan[1] or scan[0]) | |
| begin | |
| found[0] = finalRequest[scan[0]]; | |
| for(t=1; t<NUMUNITS-1; t=t+1) | |
| found[t] = found[t-1] || finalRequest[scan[t]]; | |
| end | |
| //produces inputs to "grant" flip-flops | |
| always@(finalRequest or found or scan[7] or scan[6] or scan[5] or | |
| scan[4] or scan[3] or scan[2] or scan[1] or scan[0]) | |
| begin | |
| grantD[scan[0]] = finalRequest[scan[0]]; | |
| for(u=1; u<NUMUNITS; u=u+1) | |
| grantD[scan[u]] = finalRequest[scan[u]] && ~found[u-1]; | |
| end | |
| always@(grantD) | |
| begin | |
| nextNext = 0; | |
| for(v=0; v<NUMUNITS-1; v=v+1) | |
| if(grantD[v]) nextNext = v+1; | |
| end | |
| endmodule //arbiter |