【SOC架构】(一)同步与异步信号
阿里云国内75折 回扣 微信号:monov8 |
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6 |
写在前面
本章节主要参考《SOC设计方法与实现 第三版》也是整个SOC架构学习的起点下面我们正式开始
目前流行的设计架构GALSGlobal Asynchronize Local Synchronize即全局异步局部同步这是顺应了多核SOC设计的潮流同时也符合EDA工具对同步电路设计的广泛支持。
回顾同步电路
同步电路的定义触发器、寄存器都由一个统一的时钟控制。并且在同步电路中为方便后端设计一般使用统一触发方式上升沿或下降沿中的一种
同步电路时序收敛满足触发器的建立时间和保持时间。EDA的时序分析工具可以检查同步电路的收敛问题。
同步电路优缺点
同步性减少了电路竞争冒险和毛刺噪声
时钟偏斜(时钟到达每个触发器时间不一致可以用EDA时钟树综合以最长的时钟路径为基准短的路径加入延时单元)和功耗问题
异步电路
异步电路的触发器可能在任何时间跳变。
异步电路采用握手协议实现自同步。常用的握手协议分为二相位和四相位握手。
下图的Req和Ack是简单的握手信号即request和acknowledge先握手的是request而后回应的是acknowledge
二相位握手协议在Req和Ack的任何一对跳变沿组合处均可实现一次数据传输。而四相位握手协议只能实现一次数据传输。四相位握手协议是首选因为稳定性高
异步电路优缺点
模块化突出、对信号延迟不敏感、没有时钟偏斜、高速低功耗
设计复杂缺乏EDA工具支持
亚稳态
亚稳态本质上是信号跨时钟域传输时输入的信号可能会不满足某个触发器的建立保持时间要求从而锁存进一个不正常的电平可能代表着NMOS和PMOS同时导通并且可能传播下去会造成后续电路工作不正常
降低亚稳态发生概率使用二级触发器同步器其本质是因为亚稳态最终会稳定在一个电平上增加一级D触发器可以保证等亚稳态恢复到0或者1再采样这样亚稳态就不会再传播下去。
一点思考:如有不对请指正
但是这样不能保证跨时钟域的数据传输正确只能保证亚稳态概率降到很低。
因为发生亚稳态时第二级触发器等待第一级触发器亚稳态输出回恢复稳定再采样然而恢复到0还是1这是不能确定的因此在这种情况下二级触发器采样输出的数据虽说不会有暂稳态传播下去但是数据有可能是错误的
同步器的代码如下(参考上图)
module synchronizer(
input bclk,
input reset_b,
input adat,
output bdat
);
reg bdat1,bdat2;
always@(posedge bclk, negedge reset_b)begin
if(reset_b)
{bdat2,bdat1}<=2'b0;
else
{bdat2,bdat1}<={bdat1,adat};
end
assign bdat=bdat2;
endmodule
异步控制信号同步
同步的定义把异步信号采样到目的时钟域的动作
1.慢时钟域控制信号同步到快时钟域。
问题描述直接用同步器采样的话慢时钟域持续1个慢时钟周期的控制信号采样到快时钟域可能会持续多个快周期。在慢时钟域中被认为是一次控制就会在快时钟域中被认为多次控制操作该问题如下图所示。
经过快时钟下的同步器采样两级触发器得到rd_en_s2f2
控制信号(图上标注有误rd_en_s2f
应当为rd_en_s2f2
)该信号在快时钟域下持续多个周期而不是单个周期需要对其进行处理将其转化为快时钟域下单个周期的信号需要缩短控制信号。
处理方法采用简单的逻辑波形变换注意因为rd_en_s2f1
可能有亚稳态现象因此只能用同步器输出的信号进行变换即rd_en_s2f2
,具体变换如下图所示。
代码如下
module synchronizer(
input clk_fst,
reset_b,
rd_en,
output rd_en_s2f
);
reg rd_en_s2f1,
rd_en_s2f2,
rd_en_s2f3;
always@(posedge clk_fst or negdege reset_b)begin//多级触发器赋值
if(~reset_b)
{rd_en_s2f3,rd_en_s2f2,ed_en_s2f1}<=3'b000;
else
{rd_en_s2f3,rd_en_s2f2,ed_en_s2f1}<={rd_en_s2f2,rd_en_s2f1,rd_en};
end
always@(rd_en_s2f3,rd_en_s2f2)
case({rd_en_s2f3,rd_en_s2f2})
2'b01://条件句
rd_en_s2f<=1'b1;
default:
rd_en_s2f<=1'b0;
endcase
endmodule
重要提示:学习多级触发器的verilog语句熟练使用{ }语法
小结:慢时钟域控制信号同步到快时钟域的本质就是一个边缘检测或者信号计数器。
不管持续时间多长的信号只要大于一个快时钟周期都会生成一个快时钟域内持续一个周期的信号。
通过对上述代码中的条件句进行控制还可以实现下降沿的检测
2.快时钟域控制信号同步到慢时钟域。
问题描述慢时钟域同步快时钟域下持续一个快周期的信号在慢时钟域中会不满一个慢时钟周期因此在下一个慢时钟到来之前信号就已经无效。该问题如下图所示。
因此需要延长控制信号。
处理方法加入握手机制在快时钟域中加入反馈只有接收方确认收到有效控制信号后控制信号再失效。
代码如下
/*快时钟域控制信号同步到慢时钟域*/
module f2s_control(
input adat,
rst,
aclk,
bclk,
output reg bdat
);
reg adat1,
bdat1, bdat2, bdat3,
abdat1, abdat2;
//实例化慢时钟域同步器
always @(posedge bclk or negedge rst) begin
if(~rst)
{bdat2,bdat1}<=2'b00;
else
{bdat2,bdat1}<={bdat1,adat1};
end
//实例化快时钟域同步器
always @(posedge aclk or negedge rst) begin
if(~rst)
{abdat2,abdat1}<=2'b00;
else
{abdat2,abdat1}<={abdat1,bdat2};
end
//实例化快时钟域同步慢时钟域方法:缩短
always @(posedge bclk or negedge rst) begin
if(~rst)
bdat3<=1'b0;
else
bdat3<=bdat2;
end
always @(bdat3,bdat2) begin
bdat<=({bdat3,bdat2}==2'b01)?1'b1:1'b0;
end
//实例化慢时钟域同步快时钟域方法反馈延时
always @(posedge aclk or negedge rst) begin
if(~rst)
adat1<=1'b0;
else //adat触发abdat2关闭
if(abdat2)
adat1<=1'b0;
else
if(adat)
adat1<=1'b1;
end
endmodule
testbench
代码如下
/*快时钟域控制信号同步到慢时钟域*/
/*测试*/
`timescale 1ns/1ns
`include "f2s_control.v"
module f2s_control_tb;
//************<端口声明>****************
reg adat,
rst,
aclk,
bclk;
wire bdat;
//***********<模块例化>******************
f2s_control M1(
adat,
rst,
aclk,
bclk,
bdat
);
initial begin
$dumpfile("f2s_control.vcd");
$dumpvars;
aclk<=0;
bclk<=0;
rst<=0;
adat<=0;
#12 rst<=1;
#20 @(posedge aclk) adat<=1;
@(posedge aclk) adat<=0;
#1000 $finish;
end
always #7
aclk<=~aclk;
always #10
bclk<=~bclk;
endmodule
测试结果如下