본문 바로가기
Digital Design/SoC

[SoC] Arbiter_Fixed Priority (Design with Verilog)

by 스테고사우르스 2023. 4. 30.

안녕하세요.

지난 시간에는 History Queue를 이용한 LRG 기반의 Round Robin Arbiter를 설계해보았습니다.

 

오늘은 쉬어가는 타임으로 Fixed Priority Arbiter를 설계해보겠습니다.

 

Master 여러개가 Request를 보내면 순서를 정해주는 신호등 역할을 하는 것이 바로 Arbiter라고 했었죠?

Fixed Priority는 우선순위를 고정해 놓는다는 뜻입니다.

 

예를 들어 M0 > M1 > M2 > M3로 순위를 정해 놓았다고 가정해보겠습니다.

만약 M0, M1, M3가 REQ를 보내면 어떻게 될까요?

무조건 M0먼저 처리해줍니다.

 

Fixed Priority Arbiter는 공평하진 않지만, 중요한 Master가 먼저 버스를 사용할 수 있게 만들어준다는 장점이 있습니다.

 

바로 코드를 보겠습니다.

 


Verilog Code

DUT

 

`timescale 1ns / 1ps

module arbiter_fixed_priority(
input i_clk,
input i_reset,
input i_req0,
input i_req1,
input i_req2,
input i_req3,

output reg o_gnt0,
output reg o_gnt1,
output reg o_gnt2,
output reg o_gnt3
);

//PRIORITY: M0 > M1 > M2 > M3
always @ (posedge i_clk or negedge i_reset) begin
    if (!i_reset) begin
        {o_gnt3, o_gnt2, o_gnt1, o_gnt0} <= 4'b0000;
    end
    else if (i_req0) begin
        {o_gnt3, o_gnt2, o_gnt1, o_gnt0} <= 4'b0001;
    end
    else if (i_req1) begin
        {o_gnt3, o_gnt2, o_gnt1, o_gnt0} <= 4'b0010;
    end
    else if (i_req2) begin
        {o_gnt3, o_gnt2, o_gnt1, o_gnt0} <= 4'b0100;
    end
    else if (i_req3) begin
        {o_gnt3, o_gnt2, o_gnt1, o_gnt0} <= 4'b1000;
    end
    else begin  //IF NO REQUEST
        {o_gnt3, o_gnt2, o_gnt1, o_gnt0} <= 4'b0000;
    end
end
    
endmodule

우선순위를 갖기 때문에 if문으로 쉽게 구현할 수 있습니다.

 

 

Testbench

`timescale 1ns / 1ps

module tb_arbiter_fixed_priority();

reg i_clk;
reg i_reset;
reg i_req0;
reg i_req1;
reg i_req2;
reg i_req3;

wire o_gnt0;
wire o_gnt1;
wire o_gnt2;
wire o_gnt3;

arbiter_fixed_priority arbiter_fp (.i_clk (i_clk),
                                   .i_reset (i_reset),
                                   .i_req0 (i_req0),
                                   .i_req1 (i_req1),
                                   .i_req2 (i_req2),
                                   .i_req3 (i_req3),
                                   .o_gnt0 (o_gnt0),
                                   .o_gnt1 (o_gnt1),
                                   .o_gnt2 (o_gnt2),
                                   .o_gnt3 (o_gnt3)  );
                                   
always #5 i_clk = ~i_clk;

initial begin
    i_clk = 1'b0; i_reset = 1'b1;
    {i_req3, i_req2, i_req1, i_req0} = 4'b0000;  #1
    i_reset = 1'b0;                              #1
    i_reset = 1'b1;                              #8
    {i_req3, i_req2, i_req1, i_req0} = 4'b1111;  #10
    {i_req3, i_req2, i_req1, i_req0} = 4'b0110;  #10
    {i_req3, i_req2, i_req1, i_req0} = 4'b1001;  #10
    {i_req3, i_req2, i_req1, i_req0} = 4'b1000;  #10
    {i_req3, i_req2, i_req1, i_req0} = 4'b0101;  #10
    {i_req3, i_req2, i_req1, i_req0} = 4'b0010;  #10
    $finish;
end
                                 
endmodule

 

Simulation

 

req0, req1, req2, req3가 들어왔을 때에는 우선순위에 따라 gnt0를 해주는 것을 볼 수 있습니다.

req1, req2가 들어왔을 때에는 우선순위에 따라 gnt1를 먼저 해주는 것을 볼 수 있습니다.

 


 

댓글