Verilog逻辑设计学习5

Posted on 2023-01-25 02:19  _Chapman  阅读(841)  评论(0编辑  收藏  举报

调度器

调度器是逻辑设计电路中很常见的一种电路,他们被应用在多个领域。调度器一般包括SP、RR、WRR/WFQ等。

SP优先级调度器

SP 调度指的是绝对高优先级调度,此种调度不带权重概念,按照优先级进行调度。 这一种调度方法严格按照优先级从高到低的次序优先发送较高优先级队列中的报文,当较高优先级队列为空时,再发送较低优先级队列中的报文。
也就是说,高优先级队列只要不为空,就一直调度高优先级队列。

简图如下:
image
只要Q2一直有消息,则一直发送Q2的,直到Q2为空切换到Q1发送。当Q1发送完毕之后,切换到Q0。但是只要高优先级队列一直不为空,Q0队列就一直不会发送。

在Verilog里面实现如下:

module sp_sch (
input clk , // 时钟线
input rst_n , // 复位线
input q0_rdy , // 低级优先级队列信号
input q1_rdy , // 中级优先级队列信号
input q2_rdy , // 高级优先级队列信号
output [2:0] sel // 输出占用状态
);

assign sel = q2_rdy ? 3'b100 : ( q1_rdy ? 3'b010 : 3'b001 ) ;
//先比较q1_rdy与q0_rdy,看q1_rdy是否需要占用,输出结果1。
//比较q2_rdy与结果1,看q2_rdy是否需要占用,输出结果sel。

endmodule

RR调度器

这一种调度器是不分优先级和权重的(隔各个队列都拥有平等排队机会),这样可以有效避免一些队列一直无法执行。 调度器总是按照排列顺序占用(空队列将会被跳过),每个队列都在待发。如果一些队列一直为空,则其他队列就可以一直占用。(极端情况下)

结构图如下:
image
在上图,输出按先后顺序分别是:
P0\P6\P11\P1\P7\P12......
假若有一个分组Q3一直为空,则一直让出占用权给Q2\Q1\Q0。假如Q1为空,则执行到Q1时候,直接跳过到Q0。但Q0执行完之后,优先查看Q1,若Q1还是空,则跳到Q2,再查看Q1......如此类推。

在Verilog里面实现:

module rr_sch(
input clk , // system clock 50Mhz on board
input rst_n , // system rst, low active
input q0_rdy , // input q0_rdy
input q1_rdy , // input q1_rdy
input q2_rdy , // input q2_rdy
output [2:0] sel // output sel
);

// Wire define
wire rr_vld ;

// Reg define
reg [2:0] last_winner ;
reg [2:0] curr_winner ;

assign rr_vld = q0_rdy | q1_rdy | q2_rdy ; // 产生调度使能信号
//如果有调度信号,开始准备执行调度。

//每次刷新时钟时,就刷新一次上一次的调度信息
always @ (posedge clk or negedge rst_n) begin
if (rst_n == 1'b0)
last_winner <= 3'b0 ;
else if ( rr_vld == 1'b1 )
last_winner <= curr_winner ; // 记录上一次调度的队列
else ;
end

//轮询系统
always @ (*) begin
if ( last_winner == 3'b001 ) begin // 轮询当前队列
//如果上一次是Q0执行,则本次优先查看Q1和Q2
if ( q1_rdy == 1'b1 )
curr_winner = 3'b010 ;
else if ( q2_rdy == 1'b1 )
curr_winner = 3'b100 ;
else if ( q0_rdy == 1'b1 )
curr_winner = 3'b001 ;
else
//都为空,则执行空闲
curr_winner = 3'b000 ;
end

else if ( last_winner == 3'b010 ) begin
//如果上一次是Q1执行,则本次优先查看Q0和Q2
if ( q2_rdy == 1'b1 )
curr_winner = 3'b100 ;
else if ( q0_rdy == 1'b1 )
curr_winner = 3'b001 ;
else if ( q1_rdy == 1'b1 )
curr_winner = 3'b010 ;
else
//都为空,则执行空闲
curr_winner = 3'b000 ;
end

else if ( last_winner == 3'b100 ) begin
//如果上一次是Q2执行,则本次优先查看Q0和Q1
if ( q0_rdy == 1'b1 )
curr_winner = 3'b001 ;
else if ( q1_rdy == 1'b1 )
curr_winner = 3'b010 ;
else if ( q2_rdy == 1'b1 )
curr_winner = 3'b100 ;
else
//都为空,则执行空闲
curr_winner = 3'b000 ;
end

else begin
//上一次执行为空
if ( q0_rdy == 1'b1 )
curr_winner = 3'b001 ;
else if ( q1_rdy == 1'b1 )
curr_winner = 3'b010 ;
else if ( q2_rdy == 1'b1 )
curr_winner = 3'b100 ;
else
curr_winner = 3'b000 ;
end
end

assign sel = curr_winner ;//输出当前占用状态

endmodule

上述为RR调度器的Verilog描述。

WFQ调度器

WFQ队(Weighted Fair Queuing)是加权公平排队的缩写,调度器中各个队列都有一定权重,调度均匀性极好,是多种调度方式中比较友好的一种。不过WFQ的缺点很明显,因为需要判断队列的多个因素,需要占用大量资源。
WFQ中,队列权重越大,调度宽度越小(权重和宽度成反比),WRR和它相反。通过下列简图解释其工作方式:
image
如上图所示:Q3权重位1;Q2权重位2;Q1权重位3;Q0权重位4;那么,调度顺序为:
round1:
Q0到Q1到Q2到Q3(权重4、3、2、1);

round2:
Q3优先执行
权重变更(全部减去3的权重):
Q0\3
Q1\2
Q2\1
Q3\0
其中Q3已经到零,从新配置权重:
Q0\3
Q1\2
Q2\1
Q3\1

round3:
Q2优先执行
权重变更(全部减去2的权重):
Q0\2
Q1\1
Q2\0
Q3\0
其中Q3、Q2已经到零,从新配置权重:
Q0\2
Q1\1
Q2\2
Q3\0

round4:
Q3优先执行
权重变更(全部减去3的权重):
Q0\2
Q1\1
Q2\2
Q3-1 -》0
其中Q3已经到零,从新配置权重:
Q0\2
Q1\1
Q2\2
Q3\1

round5:
Q1先执行
权重变更(全部减去Q1权重):
Q0\1
Q1\0
Q2\1
Q3\0
其中Q1已经到零,从新配置权重:
Q0\1
Q1\3
Q2\1
Q3\0

round6:
Q3优先执行
权重变更(全部减去Q3权重):
Q0\1
Q1\3
Q2\1
Q3\0
其中Q3已经到零,从新配置权重:
Q0\1
Q1\3
Q2\1
Q3\1

round7:
Q0优先执行
权重变更(全部减去Q0权重):
Q0\0
Q1\2
Q2\0
Q3\0
其中Q0已经到零,从新配置权重:
Q0\4
Q1\2
Q2\0
Q3\0

round8:
Q2优先执行
权重变更(全部减去Q2权重):
Q0\4
Q1\2
Q2\0
Q3\0
其中Q2已经到零,从新配置权重:
Q0\4
Q1\2
Q2\2
Q3\0

round7:
Q3优先执行
权重变更(全部减3的权重):
Q0\4
Q1\2
Q2\2
Q3\0
其中Q3已经到零,从新配置权重:
Q0\4
Q1\2
Q2\2
Q3\1

round8:
Q3优先执行
权重变更(全部减3的权重):
Q0\3
Q1\1
Q2\1
Q3\0
其中Q3已经到零,从新配置权重:
Q0\3
Q1\1
Q2\1
Q3\1

round9:
Q1优先执行
权重变更(全部减1的权重):
Q0\3
Q1\0
Q2\0
Q3\0
其中Q1已经到零,从新配置权重:
Q0\3
Q1\3
Q2\0
Q3\0

round10:
Q2优先执行
权重变更(全部减2的权重):
Q0\3
Q1\3
Q2\0
Q3\0
其中Q2已经到零,从新配置权重:
Q0\3
Q1\3
Q2\2
Q3\0

round11:
Q3优先执行
权重变更(全部减3的权重):
Q0\3
Q1\3
Q2\2
Q3\0
其中Q3已经到零,从新配置权重:
Q0\3
Q1\3
Q2\2
Q3\1

round12:
Q3优先执行
权重变更(全部减3的权重):
Q0\2
Q1\2
Q2\1
Q3\0
其中Q3已经到零,从新配置权重:
Q0\2
Q1\2
Q2\1
Q3\1

round13:
Q2优先执行
权重变更(全部减2的权重):
Q0\1
Q1\1
Q2\0
Q3\0
其中Q2已经到零,从新配置权重:
Q0\1
Q1\1
Q2\2
Q3\0

round14:
Q3优先执行
权重变更(全部减3的权重):
Q0\1
Q1\1
Q2\2
Q3\0
其中Q3已经到零,从新配置权重:
Q0\1
Q1\1
Q2\2
Q3\1

round15:
Q1优先执行
权重变更(全部减1的权重):
Q0\0
Q1\0
Q2\1
Q3\0
其中Q1已经到零,从新配置权重:
Q0\0
Q1\3
Q2\1
Q3\0

round15:
Q0优先执行
权重变更(全部减0的权重):
Q0\0
Q1\3
Q2\1
Q3\0
其中Q0已经到零,从新配置权重:
Q0\4
Q1\3
Q2\1
Q3\0

......
同权重下,初始权重由小到大排列第二小的先排列。
否则权重小的先排列。
总体顺序为:
0、1、2、3、3、2、3、1、3、0、2、3、3、1、2、3、3、2、3、1、0......