J
Joseph H Allen
Guest
This is the way I make arbiters:
// Concise priority arbiter
input [26:0] req; // Bit zero is highest priority
wire [26:0] gnt = req & -req; // Isolate least significant set bit
Since this method uses fast carry logic, it's quite fast- the best win is in
FPGAs, where the carry chain is much faster than regular routing. If you
can do a 32-bit add in one cycle, you can certainly do a 27-bit priority
arbiter. With ASICs or fully custom, you can pick the carry lookahead method
of your choice. Notice also that it is very easy to parameterize.
It's not hard to make a full round-robin arbiter out of this:
reg [26:0] prev; // Previous winner (saved from last cycle)
wire [26:0] req1 = req & ~((prev - 1) | prev); // Mask off previous winners
wire [26:0] gnt1 = req1 & -req1; // Select new winner
wire [26:0] winner = |gnt1 ? gnt1 : gnt; // Start from bit zero if none
// Save previous winner
always @(posedge clk) if (winner) prev <= winner;
The idea is that this expression converts from "one-hot" coding to
"thermometer" coding: ((x-1)|x))
Want more tricks? I highly recommend Henry Warren's _Hacker's Delight_:
http://www.hackersdelight.org
See also HAKMEM- MIT AI Lab Memo No. 239:
http://www.inwap.com/pdp10/hbaker/hakmem/hakmem.html
(It seems that the people at the AI lab were interested in just about
anything except AI
Also the unpublished (but downloadable) Volume 4A of Knuth's _The Art of
Computer Programming_:
http://www-cs-faculty.stanford.edu/~knuth/taocp.html
--
/* jhallen@world.std.com AB1GO */ /* Joseph H. Allen */
int a[1817];main(z,p,q,r){for(p=80;q+p-80;p-=2*a[p])for(z=9;z--q=3&(r=time(0)
+r*57)/7,q=q?q-1?q-2?1-p%79?-1:0%79-77?1:0<1659?79:0>158?-79:0,q?!a[p+q*2
]?a[p+=a[p+=q]=q]=q:0:0;for(;q++-1817printf(q%79?"%c":"%c\n"," #"[!a[q-1]]);}
// Concise priority arbiter
input [26:0] req; // Bit zero is highest priority
wire [26:0] gnt = req & -req; // Isolate least significant set bit
Since this method uses fast carry logic, it's quite fast- the best win is in
FPGAs, where the carry chain is much faster than regular routing. If you
can do a 32-bit add in one cycle, you can certainly do a 27-bit priority
arbiter. With ASICs or fully custom, you can pick the carry lookahead method
of your choice. Notice also that it is very easy to parameterize.
It's not hard to make a full round-robin arbiter out of this:
reg [26:0] prev; // Previous winner (saved from last cycle)
wire [26:0] req1 = req & ~((prev - 1) | prev); // Mask off previous winners
wire [26:0] gnt1 = req1 & -req1; // Select new winner
wire [26:0] winner = |gnt1 ? gnt1 : gnt; // Start from bit zero if none
// Save previous winner
always @(posedge clk) if (winner) prev <= winner;
The idea is that this expression converts from "one-hot" coding to
"thermometer" coding: ((x-1)|x))
Want more tricks? I highly recommend Henry Warren's _Hacker's Delight_:
http://www.hackersdelight.org
See also HAKMEM- MIT AI Lab Memo No. 239:
http://www.inwap.com/pdp10/hbaker/hakmem/hakmem.html
(It seems that the people at the AI lab were interested in just about
anything except AI
Also the unpublished (but downloadable) Volume 4A of Knuth's _The Art of
Computer Programming_:
http://www-cs-faculty.stanford.edu/~knuth/taocp.html
--
/* jhallen@world.std.com AB1GO */ /* Joseph H. Allen */
int a[1817];main(z,p,q,r){for(p=80;q+p-80;p-=2*a[p])for(z=9;z--q=3&(r=time(0)
+r*57)/7,q=q?q-1?q-2?1-p%79?-1:0%79-77?1:0<1659?79:0>158?-79:0,q?!a[p+q*2
]?a[p+=a[p+=q]=q]=q:0:0;for(;q++-1817printf(q%79?"%c":"%c\n"," #"[!a[q-1]]);}