一、处理多比特信号跨时钟域的问题
如上图所示adata信号从2’b00变到2‘b一段时间后,11会变成2‘b但是因为寄存器同步器delay随机性可能在一个周期后同步,也可能需要两个周期。 这样我们就可以了bdata1看到一个周期的2’b01之后也可能看到一个周期的2’b这两个值都是10adata没有出现的,也就是说,bdata有错误的值。 为了解决这个问题,我们介绍了一个"MUX/DMUX多比特信号的跨时钟域问题问题。
二、MUX/DMUX同步器
2.1 电路波形图
如上图所示,MUX/DMUX同步器主要用于同步器多比特数据跨时钟域问题,多比特数据。 上图中,红色虚线框主要处理数据有效标志信号。可以发现,单比特的数据有效标志信号实际上是bclk时钟域打了两拍,其实是单比特从慢速时钟域到快速时钟域的处理方法。时钟内有效标记数据信号bclk下打两拍后,与该拍的时钟域同步,。 此外,对adata_valid_rr在bclk拍摄主要是为了有效地标记数据的信号和同步bclk数据匹配。 这里需要注意的是,如果bclk时钟速率小于aclk对于时钟速率,我们只需将上图中红色虚线框中的电路换成单比特从快速时钟域到慢速时钟域的处理方法。
2.2 代码
module mux_synchronizer( input adata_valid, input [7:0] adata, input brst_n, input bclk, output reg [7:0] bdata, output reg bdata_valid ); reg adata_valid_r; reg adata_valid_rr; always@(posedge bclk or negedge brst_n) begin if(brst_n==1'b0) {bdata_valid,adata_valid_rr,adata_valid_r}<=3'b0; else {bdata_valid,adata_valid_rr,adata_valid_r}<={adata_valid_rr,adata_valid_r,adata_valid}; end always@(posedge bclk or negedge brst_n) begin if(brst_n==1'b0) bdata<=8'b0; else if(adata_valid_rr==1'b1) bdata<=adata; end endmodule
三、使用MUX/DMUX同步器处理多比特数据跨时钟域问题
假设两个异步时钟aclk和bclk,aclk=148.5M,bclk=145M。 如图,bclk时钟域中一个8bit数据data通过data_valid标记有效,持续有效约8个时钟周期,数据保存稳定,每40个ms更新一次。 要求bclk同步时钟域的数据信号aclk时钟域,data_valid在aclk时钟域持续一个时钟周期,请使用您熟悉的hdl语言描述。请在设计中使用异步低复位。
3.1 电路波形图
3.2 代码
module mux_synchronizer( input aclk, input arst_n, input [7:0] data, input data_valid, output reg [7:0] adata, output reg adata_valid ); reg[2:0] adata_valid_r; wire adata_valid_rise; always@(posedge aclk or negedge arst_n) begin if(arst_n==1'b0) adata_valid_r[2:0]<=3'd0; else adata_valid_r[2:0]<={adata_valid_r[1:0],data_valid}; end assign adata_valid_rise=~adata_valid_r[2]&adata_valid_r[1];//检测data_valid的上升沿 always@(posedge aclk or negedge arst_n) begin if(arst_n==1'b0) adata<=8'd0; else if(adata_valid_rise==1'1)
adata<=data;
end
always@(posedge aclk or negedge arst_n)
begin
if(arst_n==1'b0)
adata_valid<=1'b0;
else
adata_valid<=adata_valid_rise;
end
endmodule
3.3 验证
module mux_synchronizer_tb();
reg aclk;
reg arst_n;
reg [7:0] data;
reg data_valid;
wire adata_valid;
wire [7:0] adata;
reg bclk;
always #3.448 bclk=~bclk;
always #3.365 aclk=~aclk;
initial begin
aclk=1;
bclk=1;
arst_n=0;
data_valid=0;
data=0;
#200;
arst_n=1;
//第一次数据
@(posedge bclk)
data_valid=1;
data=1;
#53.84;
@(posedge bclk)
data_valid=0;
#400;
//第二次数据
@(posedge bclk)
data_valid=1;
data=2;
#53.84;
@(posedge bclk)
data_valid=0;
end
mux_synchronizer u1(
.aclk(aclk),
.arst_n(arst_n),
.data(data),
.data_valid(data_valid),
.adata(adata),
.adata_valid(adata_valid)
);
endmodule
四、其他多比特数据跨时钟域处理方法
4.1 异步FIFO
4.2 握手反馈
链接给的单比特数据跨时钟域处理,多比特数据跨时钟域处理方式原理和此类似。
五、参考文献
多bit信号跨时钟域怎么办?
如何用MUX/DMUX处理多比特数据跨时钟域