Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- from myhdl import *
- @block
- def grant_selector(request, grant, request_bit):
- if request_bit == 0:
- @always_comb
- def selector():
- grant.next = request[request_bit]
- else:
- @always_comb
- def selector():
- if request[request_bit:] != 0:
- grant.next = False
- else:
- grant.next = request[request_bit]
- return selector
- @block
- def request_rotate(request, reordered_request, rotate):
- bits = len(request)
- if rotate > 0:
- @always_comb
- def reorder():
- reordered_request.next[:rotate] = request[bits-rotate:]
- reordered_request.next[rotate:] = request[:bits-rotate]
- else:
- @always_comb
- def reorder():
- reordered_request.next = request
- return reorder
- @block
- def grant_derotate(grant, rotated_grant, rotate):
- bits = len(grant)
- if rotate > 0:
- @always_comb
- def reorder():
- grant.next[bits-rotate:] = rotated_grant[:rotate]
- grant.next[:bits-rotate] = rotated_grant[rotate:]
- else:
- @always_comb
- def reorder():
- grant.next = rotated_grant
- return reorder
- @block
- def rr_arbiter(clk, req, grant):
- '''The architecture here is we generate a list of rotated requests
- (with associated block to do the rotation). The specific rotated request
- is set by the arbiter_position index.
- The grant bit is then set if all the lower bits than it in the rotated
- request are not set, and that bit is.
- Of course, that means the resultant grant bit vector is rotated, so we
- need to derotate it. This is done by broadcasting to a set of signals
- that are then each derotated, and the correct derotated signal is
- selected using the arbiter_position index.
- The policy is for arbiter_position index to increment on every cycle.
- '''
- n = len(req)
- assert len(req) == len(grant)
- arbiter_position = intbv(0, min=0, max=n)
- rotated_reqs = [Signal(intbv(0)[n:]) for each in range(n)]
- sel_rotators = []
- for p, rotated_req in enumerate(rotated_reqs):
- sel_rotators.append(request_rotate(req, rotated_req, p))
- rot_grant_bits = [Signal(False) for each in range(n)]
- current_rotated_req = Signal(intbv(0)[n:])
- grant_selectors = []
- for p, grant_bit in enumerate(rot_grant_bits):
- grant_selectors.append(
- grant_selector(current_rotated_req, grant_bit, p))
- rotated_grant = Signal(intbv(0)[n:])
- # We need to clone this to all the output rotations
- rotated_grants = [Signal(intbv(0)[n:]) for each in range(n)]
- # This maps to a set of grants which the multiplexor selects
- grants = [Signal(intbv(0)[n:]) for each in range(n)]
- grant_derotators = []
- for p, (each_grant, each_rotated_grant) in enumerate(
- zip(grants, rotated_grants)):
- grant_derotators.append(
- grant_derotate(each_grant, each_rotated_grant, p))
- @always_comb
- def assign_grant_bits():
- for i in range(n):
- rotated_grant[i].next = rot_grant_bits[i]
- @always_comb
- def assign_rotated_grants():
- for i in range(n):
- rotated_grants[i].next = rotated_grant
- @always(clk.posedge)
- def assign_req():
- arbiter_position.next = arbiter_position + 1 % n
- grant.next = grants[arbiter_position]
- current_rotated_req.next = rotated_reqs[arbiter_position]
- return (sel_rotators, grant_selectors, grant_derotators,
- assign_grant_bits, assign_rotated_grants, assign_req)
- def convert():
- clk = Signal(False)
- req = Signal(intbv(0)[4:])
- grant = Signal(intbv(0)[4:])
- inst = rr_arbiter(clk, req, grant)
- inst.convert()
- if __name__ == '__main__':
- convert()
Add Comment
Please, Sign In to add comment