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
0 Comments:
Post a Comment