【线性序列机-02】- 请求优先的线性序列机
1. 功能介绍
在第一篇文章中介绍了不同线性序列机的分类,本篇文章将详细介绍其中的一种,请求优先的线性序列机。请求优先的线性序列机是一种在数字电路设计领域中具有独特性质和重要应用的概念或方法。其核心思想是,当计数器在计数过程中再次接收到请求时,会毫不犹豫地放弃当前正在进行的计数功能,转而接受新的请求,并以新的请求为起点重新开始计数。这里的“请求优先”原则,是相对于计数器本身单纯按照设定规则进行的计数功能而言的。它体现了在特定的电路设计场景中,对于外部请求的高度响应性和灵活性。
2. 结构框图
3. 源码实现
module lsm_ctrl1 #(
parameter CW = 4
)(
input wire clk ,
input wire rstn ,
input wire req ,
input wire hold ,
input wire [CW-1:0] cnt_in ,
output wire [CW-1:0] cnt_nxt ,
output reg [CW-1:0] cnt_cur ,
output wire cnt_eq0
);
wire cnt_ne0 = |cnt_cur;
wire cnt_ena = ~hold & (req | cnt_ne0);
assign cnt_eq0 = ~cnt_ne0;
assign cnt_nxt = req ? cnt_in : cnt_cur - cnt_ne0;
always @(posedge clk or negedge rstn)
begin
if(!rstn)
cnt_cur <= {CW{1'b0}};
else if(cnt_ena)
cnt_cur <= cnt_nxt;
end
endmodule
4. 仿真结果
4.1 仿真顶层
module test_top;
reg clk;
reg rstn;
reg req;
reg hold;
reg [3:0] cnt_in;
initial begin
clk = 1'b0;
forever #5 clk = ~clk;
end
initial begin
rstn = 1'b0;
#1_001;
rstn = 1'b1;
end
lsm_ctrl1 #(.CW(4)) dut (
.clk (clk ),
.rstn (rstn ),
.req (req ),
.hold (hold ),
.cnt_in (cnt_in ),
.cnt_nxt ( ),
.cnt_cur ( ),
.cnt_eq0 ( )
);
initial begin
req = 1'b0;
hold = 1'b0;
cnt_in = 4'd0;
#100_000;
for(integer i=0; i<16; i=i+1) begin
@(posedge clk) #1;
req = 1'b1;
cnt_in = i[3:0];
@(posedge clk) #1;
req = 1'b0;
#100_000;
end
for(integer i=0; i<16; i=i+1) begin
@(posedge clk) #1;
req = 1'b1;
cnt_in = i[3:0];
@(posedge clk) #1;
req = 1'b0;
repeat(5) @(posedge clk) #1;
end
#100_000;
$finish();
end
endmodule
4.2 仿真波形
- 单次请求,正常计数
- 重复请求,重新开始计数
从上图可以清晰地看出,在单次请求的情况下,线性序列机能正常地执行计数功能。然而,当遇到多次请求时,它会立即取消之前正在进行的计数操作,毫不犹豫地接受新的请求,并重新开始计数。这种特性体现了请求优先的原则,即新的请求具有更高的优先级,能够打断正在进行的计数过程。具体来说,线性序列机内部设置有计数器,用于对时钟脉冲或其他事件进行计数。在正常情况下,计数器按照预设的规则递增或递减,以达到特定的计数值时触发相应的操作或状态转换。但当新的请求到来时,无论当前计数器处于何种状态,它都会被重置为初始值或特定的值,然后依据新请求的要求重新开始计数。这样可以确保线性序列机能够及时响应新的请求,并按照最新的请求执行相应的操作序列。
在实际应用中,请求优先的线性序列机常用于需要快速响应外部事件或实时调整操作的场景,例如实时通信系统、自动化生产线等,以提高系统的性能和可靠性。其具体实现方式会根据不同的需求和电路设计而有所差异,但核心思想都是在遇到新请求时,优先处理新请求并重新开始计数。
5. 综合结果
在参数CW=4的情况下,以某90nm的数字标准单元库工艺综合的结果如下所示
5.1 面积
Number of ports: 21
Number of nets: 34
Number of cells: 23
Number of combinational cells: 16
Number of sequential cells: 6
Number of macros/black boxes: 0
Number of buf/inv: 2
Number of references: 11
Combinational area: 59.270401
Buf/Inv area: 4.233600
Noncombinational area: 74.793600
Macro/Black Box area: 0.000000
Net Interconnect area: undefined (No wire load specified)
Total cell area: 134.064001
Total area: undefined
5.2 功耗
Internal Switching Leakage Total
Power Group Power Power Power Power ( % ) Attrs
--------------------------------------------------------------------------------------------------
io_pad 0.0000 0.0000 0.0000 0.0000 ( 0.00%)
memory 0.0000 0.0000 0.0000 0.0000 ( 0.00%)
black_box 0.0000 0.0000 0.0000 0.0000 ( 0.00%)
clock_network 0.0000 0.0000 0.0000 0.0000 ( 0.00%)
register 0.0000 0.0000 0.0000 0.0000 ( 0.00%)
sequential 3.4750e-03 1.1090e-04 7.9910e+04 3.6658e-03 ( 59.12%)
combinational 1.4723e-03 1.0012e-03 6.1048e+04 2.5345e-03 ( 40.88%)
--------------------------------------------------------------------------------------------------
Total 4.9472e-03 mW 1.1121e-03 mW 1.4096e+05 pW 6.2003e-03 mW
5.3 时序
Point Incr Path
-----------------------------------------------------------
cnt_cur_reg_0_/CK (DFFRQXL) 0.00 0.00 r
cnt_cur_reg_0_/Q (DFFRQXL) 0.20 0.20 f
U18/Y (OR3XL) 0.13 0.33 f
U19/Y (NOR2XL) 0.09 0.41 r
U31/Y (OAI31XL) 0.04 0.45 f
cnt_nxt[0] (out) 0.00 0.45 f
data arrival time 0.45
-----------------------------------------------------------
6. 应用实例
以下是一个使用请求优先的线性序列机来实现 UART(通用异步收发传输器)发送功能的示例代码。通过这个示例,我们能够清晰地看到,当运用请求优先的线性序列机这种机制时,所编写的代码非常简洁。通常,在实现复杂的通信功能时,代码往往会因为需要处理众多的细节和异常情况而变得冗长且复杂,使得开发者在编写和维护代码的过程中面临巨大的挑战。然而,在此处使用请求优先的线性序列机来构建 UART 发送功能的代码,却打破了这种常规。
这种简洁性不仅仅体现在代码的行数上,更重要的是在代码的逻辑结构和可读性方面。由于请求优先的线性序列机能够有效地管理和处理各种请求的优先级,使得代码的逻辑更加清晰和直观。开发者无需在复杂的条件判断和流程控制中迷失,而是能够以一种更加直接和高效的方式实现所需的功能。例如,在处理发送使能信号、数据存储、计数器控制以及状态转换等关键环节时,代码能够以简洁明了的方式准确地表达出其意图,避免了过多的冗余代码和复杂的嵌套结构。这不仅降低了代码出错的可能性,还极大地提高了代码的可维护性和可扩展性。
6.1 源码实现
module uart_txd(
input wire clk ,
input wire rstn ,
input wire send ,
input wire [7:0] data ,
input wire [15:0] rate ,
output wire done ,
output wire txd
);
reg [8:0] shift;
wire [15:0] bps_cnt;
wire [3:0] bit_cnt;
wire bps_eq0;
wire bit_eq0;
wire sht_ena = ~bit_eq0 & bps_eq0;
wire bps_req = send | sht_ena;
wire bit_hold = ~bps_eq0;
assign txd = shift[0];
assign done = bps_eq0 & bit_eq0;
always @(posedge clk or negedge rstn)
begin
if(!rstn)
shift <= 9'h1ff;
else if(send)
shift <= {data, 1'b0};
else if(sht_ena)
shift <= {1'b1, shift[8:1]};
end
lsm_ctrl1 #(.CW(16)) bps_ctrl (
.clk (clk ),
.rstn (rstn ),
.req (bps_req ),
.hold (1'b0 ),
.cnt_in (rate ),
.cnt_nxt ( ),
.cnt_cur (bps_cnt ),
.cnt_eq0 (bps_eq0 )
);
lsm_ctrl1 #(.CW(4)) bit_ctrl (
.clk (clk ),
.rstn (rstn ),
.req (send ),
.hold (bit_hold ),
.cnt_in (4'd9 ),
.cnt_nxt ( ),
.cnt_cur (bit_cnt ),
.cnt_eq0 (bit_eq0 )
);
endmodule
6.2 仿真顶层
module test_top;
reg clk;
reg rstn;
reg send;
reg [7:0] data;
reg [15:0] rate;
initial begin
clk = 1'b0;
forever #5 clk = ~clk;
end
initial begin
rstn = 1'b0;
#1_001;
rstn = 1'b1;
end
uart_txd dut(
.clk (clk ),
.rstn (rstn ),
.send (send ),
.data (data ),
.rate (rate ),
.done (done ),
.txd (txd )
);
initial begin
send = 1'b0;
data = 8'd0;
rate = 16'd99;
#100_000;
for(integer i=0; i<16; i=i+1) begin
@(posedge clk) #1;
send = 1'b1;
data = $urandom_range(0, 255);
@(posedge clk) #1;
send = 1'b0;
#100_000;
end
#100_000;
$finish();
end
endmodule
6.3 仿真波形
7. 总结
请求优先的线性序列机是一种根据请求进行操作的时序控制机制。它相对计数器的计数功能具有更高的优先级。其优势在于能够灵活响应请求,及时处理新的任务,而不会受到正在进行的计数过程的限制。这使得它在需要快速响应和实时处理的场景中非常有用,可以提高系统的响应性和效率。然而,在设计时需要仔细考虑计数器的设置、请求的触发条件以及相关的逻辑控制,以确保系统的稳定性和正确性。
标签:02,cnt,wire,请求,0.0000,clk,序列,线性,rstn From: https://blog.csdn.net/kearnchen/article/details/140726367