Friday, August 20, 2021

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-------------------------------------------

1 comment:

  1. 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