Friday, August 20, 2021

Verilog HDL Examples - Design of Round-Robin Arbiter (with Fixed Time Slices)



Verilog HDL Design of Round Robin Arbiter with Fixed 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

Verilog HDL Code :

Note : Will be coding this design using FSM and the typical FSM Block diagram looks like below -





//---------------Round Robin Arbiter (with Fixed Time Slices ---//

module round_robin_arbiter_fixed_time_slices(

input clk,

input rst,

input [3:0] REQ,

output reg [3:0] GNT

);

reg [2:0] present_state;

reg [2:0] next_state;

parameter [2:0] S_ideal = 3'b000;

parameter [2:0] S_0 = 3'b001;

parameter [2:0] S_1 = 3'b010;

parameter [2:0] S_2 = 3'b011;

parameter [2:0] S_3 = 3'b100;

always @ (poesdge 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 REQ ) // Next State , Combinational always block

begin

case(present_state)

S_ideal : begin

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

else

begin

next_state = S_ideal;

end

end // S_ideal

S_0 : begin

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

elsif(REQ[0])

begin

next_state = S_0;

end

else

begin

next_state = S_ideal;

end

end // S_0

S_1 : begin

if(REQ[2])

begin

next_state = S_2;

end

elsif(REQ[3])

begin

next_state = S_3;

end

elsif(REQ[0])

begin

next_state = S_0;

end

elsif(REQ[1])

begin

next_state = S_1;

end

else

begin

next_state = S_ideal;

end

end //S_1

S_2 : begin

if(REQ[3])

begin

next_state = S_3;

end

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

else

begin

next_state = S_ideal;

end

end // S_2

S_3 : begin

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

else

begin

next_state = S_ideal;

end

end // S_3

default : begin

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

else

begin

next_state = S_ideal;

end

end // default

endcase // case(state)

end

always @(present_state or next_state) // Output , Combinational always block

begin

case(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 Fixed Time Slices


Note : Other ways to code output logic : -

1) For a Glitch Free Output

always @(posedge clk or negedge rst)

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

2) Using direct continuous assignment statements : -

assign GNT = (present_state = = S_0) ? 4'b0001 :

(present_state = = S_1) ? 4'b0010 :

(present_state = = S_2) ? 4'b0100 :

(present_state = = S_3) ? 4'b1000 : 4'b0000;

3) Output logic can be coded along with the next state , combinational logic as well


Test Bench:

// Code your testbench here

module fixed_priority_Arbiter_fixed_time_slices_test;
reg clk;
reg rst;
reg [3:0] REQ;
wire [3:0] GNT;

//Instantiate Design Under Test

round_robin_arbiter_fixed_time_slices 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
#10 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'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 ---------------------------------------



0 Comments:

Post a Comment