Verilog HDL Examples - Design of Round-Robin Arbiter (with Variable Time Slices)
Design of Round-Robin Arbiter (with Variable Time Slices) :
- Round Robin algorithm is employed when multiple users having same priority are trying to access a common resource (e.g Memory Location)
- Used by process and network schedules in computing
- Time slices are assigned to each process/scheduler/user in equal portion and in circular order without any priority (cyclic executive)
- Simple algorithm, easy to implement and starvation free
- In variable time slice type of Round Robin Arbiter, we will be incorporating a counter to count the number of clock pulses a particular request can be granted.
- If the request is dropped in between the defined time, then the next respective request will be granted and hence saving the time slices
Note : We will be coding this design using FSM and a typical FSM design block diagram looks like below -
Verilog HDL Code for a Variable Time Slice Round Robin Arbiter :
////Author: VLSI Excellence
//-------------------------Variable Time Slice Round Robin Arbiter -----------------------------//
module round_robin_arbiter_variable_time_slice(
input clk,
input rst,
input [3:0] REQ,
output reg[3:0] GNT
);
reg [1:0] count;
reg [3:0] present_state;
reg [3:0] next_state;
parameter [3:0] S_ideal = 3'b0000;
parameter [3:0] S_0 = 3'b0001;
parameter [3:0] S_1 = 3'b0010;
parameter [3:0] S_2 = 3'b100;
parameter [3:0] S_3 = 3'b1000;
always @ (posedge clk or negedge rst) // State Register, Sequential always block
begin
if(!rst)
present_state <= S_ideal;
else
present_state <= next_state;
end
always @(present_state or next_state or REQ) // Next State Logic , Combinational always
begin
case(present_state)
S_ideal : begin
count = 2'b00;
if(REQ[0])
begin
next_state = S_0;
end
elsif(REQ[1])
begin
next_state = S_1;
end
elsif(REQ[2])
begin
next_state = S_2;
end
elsif(REQ[3])
begin
next_state = S_3;
end
end
S_0 : begin
if(REQ[0])
begin
if(count == 2'b11)
begin
if(REQ[1])
begin
count = 2'b00;
next_state = S_1;
end
elsif(REQ[2])
begin
count = 2'b00;
next_state = S_2;
end
elsif(REQ[3])
begin
count = 2'b00;
next_state = S_3;
end
else
begin
count = 2'b00;
next_state = S_0;
end
end // if(count = 2'b11)
else
count = count + 1'b1;
next_state = S_0;
end // if(REQ[0])
elsif(REQ[1])
begin
count = 2'b00;
next_state = S_1;
end
elsif(REQ[2])
begin
count = 2'b00;
next_state = S_2;
end
elsif(REQ[3])
begin
count = 2'b00;
next_state = S_3;
end
else
begin
count = 2'b00;
next_state = S_ideal;
end
end // S_0
S_1 : begin
if(REQ[1])
begin
if(count == 2'b11)
begin
if(REQ[2])
begin
count = 2'b00;
next_state = S_2;
end
elsif(REQ[3])
begin
count = 2'b00;
next_state = S_3;
end
elsif(REQ[0])
begin
count = 2'b00;
next_state = S_0;
end
else
begin
count = 2'b00;
next_state = S_1;
end
end // if(count = 2'b11)
else
count = count + 1'b1;
next_state = S_1;
end // if(REQ[1])
elsif(REQ[2])
begin
count = 2'b00;
next_state = S_2;
end
elsif(REQ[3])
begin
count = 2'b00;
next_state = S_3;
end
elsif(REQ[0])
begin
count = 2'b00;
next_state = S_0;
end
else
begin
count = 2'b00;
next_state = S_ideal;
end
end // S_1
S_2 : begin
if(REQ[2])
begin
if(count == 2'b11)
begin
if(REQ[3])
begin
count = 2'b00;
next_state = S_3;
end
elsif(REQ[0])
begin
count = 2'b00;
next_state = S_0;
end
elsif(REQ[1])
begin
count = 2'b00;
next_state = S_1;
end
else
begin
count = 2'b00;
next_state = S_2;
end
end // if(count = 2'b11)
else
count = count + 1'b1;
next_state = S_2;
end // if(REQ[2])
elsif(REQ[3])
begin
count = 2'b00;
next_state = S_3;
end
elsif(REQ[0])
begin
count = 2'b00;
next_state = S_0;
end
elsif(REQ[1])
begin
count = 2'b00;
next_state = S_1;
end
else
begin
count = 2'b00;
next_state = S_ideal;
end
end // S_2
S_3 : begin
if(REQ[3])
begin
if(count == 2'b11)
begin
if(REQ[0])
begin
count = 2'b00;
next_state = S_0;
end
elsif(REQ[1])
begin
count = 2'b00;
next_state = S_1;
end
elsif(REQ[2])
begin
count = 2'b00;
next_state = S_2;
end
else
begin
count = 2'b00;
next_state = S_3;
end
end // if(count = 2'b11)
else
count = count + 1'b1;
next_state = S_3;
end // if(REQ[3])
elsif(REQ[0])
begin
count = 2'b00;
next_state = S_0;
end
elsif(REQ[1])
begin
count = 2'b00;
next_state = S_1;
end
elsif(REQ[2])
begin
count = 2'b00;
next_state = S_2;
end
else
begin
count = 2'b00;
next_state = S_ideal;
end
end // S_3
default : begin
count = 2'b00;
if(REQ[0])
begin
next_state = S_0;
end
elsif(REQ[1])
begin
next_state = S_1;
end
elsif(REQ[2])
begin
next_state = S_2;
end
elsif(REQ[3])
begin
next_state = S_3;
end
end
endcase
end
always @(posedge clk or negedge rst) // Sequential Registered Output Logic (Glitch Free)
begin
if(!rst)
GNT <= 4'b0000;
else
case(present_state)
S_0 : begin GNT <= 4'b0001; end
S_1 : begin GNT <= 4'b0010; end
S_2 : begin GNT <= 4'b0100; end
S_3 : begin GNT <= 4'b1000; end
default : begin GNT <= 4'b0000; end
endcase
end
endmodule // Round Robin Arbiter with Variable Slice Time
Test Bench:
//Author: VLSI Excellence
// Code your testbench here
// or browse Examples
module Arbiter_test;
reg clk;
reg rst;
reg [3:0] REQ;
wire [3:0] GNT;
//Instantiate Design Under Test
round_robin_arbiter_variable_time_slice DUT(.clk(clk), .rst(rst), .REQ(REQ), .GNT(GNT));
//Generate a 10 ns Time Period Clock
always #5 clk = ~clk;
//Drive the DUT or Generate stimuli for the DUT
initial begin
clk = 0;
rst = 1;
REQ = 4'b0;
// Assert the Asynchronous Reset after 1 clock period
#1 rst = 0;
//Deassert the Reset
#5 rst = 1;
@(negedge clk) REQ = 4'b1000;
@(negedge clk) REQ = 4'b1010;
@(negedge clk) REQ = 4'b0010;
@(negedge clk) REQ = 4'b0110;
@(negedge clk) REQ = 4'b1110;
@(negedge clk) REQ = 4'b1111;
@(negedge clk) REQ = 4'b0100;
@(negedge clk) REQ = 4'b0100;
@(negedge clk) REQ = 4'b0001;
@(negedge clk) REQ = 4'b0010;
@(negedge clk) REQ = 4'b0010;
@(negedge clk) REQ = 4'b0010;
#5 rst = 0;
#100 $finish;
end
initial begin
// below two lines are used to show waveform
$dumpfile("dump.vcd");
$dumpvars(1);
end
endmodule
Waveform:
--------------------------------------------Happy Learning-------------------------------------------
You've written a very useful article. This article provided me with some useful knowledge. Thank you for providing this information. Keep up the good work. Analog Circuit Design Course
ReplyDelete