状态跳转图
通道优先级译码表
当处于不同状态时,不同通道的request有不同的优先级编码,00最高,11最低。
设计讲解
当有多个外设同时发起req请求,DMA的仲裁器将按照其规定的优先级顺序,处理DMA请求。
该文章中设计的电路是一个轮转优先级发生器,
输入为四个DMA通道的request信号,
输出为对应这4个request的仲裁优先级。
当上电复位后,系统进入状态1
然后DMA等待request
1-假如此时req0有效,则会继续维持在状态1
2-后req1有效,则状态会从状态1条至状态2
3-后req1和req0同时有效,则状态会从状态2跳至状态1.(状态2时优先级:req0>req1)
4-后req2有效,则状态会从状态1跳至状态3
5-后req2和req0同时有效,则状态会从状态3跳至状态1
6-后req2和req1同时有效,则状态会从状态1跳至状态2
7-后req2,req1,req0同时有效,则状态会从状态2跳至状态3
8-后req3有效,则状态会从状态3跳至状态0
RTL代码
module round_robin(
input wire hclk ,
input wire hresetn ,
input wire req_in_ch0 ,
input wire req_in_ch1 ,
input wire req_in_ch2 ,
input wire req_in_ch3 ,
output wire [1:0] priority_ch0,
output wire [1:0] priority_ch1,
output wire [1:0] priority_ch2,
output wire [1:0] priority_ch3
);
reg [7:0] priority ;
wire [3:0] req_in ;
wire [3:0] arb_state ;
reg [3:0] arb_state_pre;
reg [3:0] req_in_dly ;
assign req_in = {req_in_ch3,req_in_ch2,req_in_ch1,req_in_ch0};
always @ (posedge hclk or negedge hresetn) begin
if (hresetn == 1'b0)
req_in_dly <= 4'b0000;
else
req_in_dly <= req_in ;
end
wire [3:0] req_in_rise = req_in & ~req_in_dly ;
always @ (posedge hclk or negedge hresetn)
begin : arb_state_pre_PROC
if (hresetn == 1'b0)
arb_state_pre <= {4'b0001};
else if(req_in_rise!= 4'b0000)
begin
case(arb_state)
4'b1000:
if(req_in[0]) arb_state_pre<= 4'b0001;
else if(req_in[1]) arb_state_pre<= 4'b0010;
else if(req_in[2]) arb_state_pre<= 4'b0100;
else if(req_in[3]) arb_state_pre<= 4'b1000;
4'b0001 :
if(req_in[1]) arb_state_pre<= 4'b0010;
else if(req_in[2]) arb_state_pre<= 4'b0100;
else if(req_in[3]) arb_state_pre<= 4'b1000;
else if(req_in[0]) arb_state_pre<= 4'b0001;
4'b0010 :
if(req_in[2]) arb_state_pre<= 4'b0100;
else if(req_in[3]) arb_state_pre<= 4'b1000;
else if(req_in[0]) arb_state_pre<= 4'b0001;
else if(req_in[1]) arb_state_pre<= 4'b0010;
4'b0100 :
if(req_in[3]) arb_state_pre<= 4'b1000;
else if(req_in[0]) arb_state_pre<= 4'b0001;
else if(req_in[1]) arb_state_pre<= 4'b0010;
else if(req_in[2]) arb_state_pre<= 4'b0100;
default :
if(req_in[0]) arb_state_pre<= 4'b0001;
else if(req_in[1]) arb_state_pre<= 4'b0010;
else if(req_in[2]) arb_state_pre<= 4'b0100;
else if(req_in[3]) arb_state_pre<= 4'b1000;
endcase
end
end
assign arb_state = arb_state_pre ;
always @ (posedge hclk or negedge hresetn)
begin : priority_PROC
if (hresetn == 1'b0)
priority <= {8'b0};
else
begin
case(arb_state)
4'b0000 :
priority<= 8'd0;
4'b0001 :
priority<= { 2'b10,2'b01,2'b00,2'b11} ;
4'b0010 :
priority<= { 2'b01,2'b00,2'b11,2'b10} ;
4'b0100 :
priority<= { 2'b00,2'b11,2'b10,2'b01} ;
4'b1000 :
priority<= { 2'b11,2'b10,2'b01,2'b00} ;
default :
priority<= { 2'b11,2'b10,2'b01,2'b00} ;
endcase
end
end
assign priority_ch0 = priority[1:0];
assign priority_ch1 = priority[3:2];
assign priority_ch2 = priority[5:4];
assign priority_ch3 = priority[7:6];
endmodule