本篇著重講解單bit信號由快時鐘域到慢時鐘域的轉化,
對于跨時鐘域信號的處理,方法我們都知道:
單bit:兩級觸發器同步(適用于慢到快)
多bit:采用異步FIFO,異步雙口RAM 加握手信號 格雷碼轉換
對于多bit信號來說我們想要跨時鐘域處理直接使用fifo就可以了,如果對于單bit信號來說,慢時鐘域到快時鐘域使用兩級觸發器就可以,代碼如下圖所示:
//---------慢時鐘域到快時鐘域----------//
module mul_clk(
input clk, //快時鐘域時鐘
input rst_n,
input pulse_a,
output pulse_b
);
reg [1:0]pulse_r;
always@(posedge clk or negedge rst_n)begin
if(!rst_n)
pulse_r <= 2'b00;
else
pulse_r <= {pulse_r[0],pulse_a};
end
assign pulse_b = pulse_r[1];
endmodule
波形仿真:

跨時鐘域處理從快時鐘域到慢時鐘域根據信號寬度可以分為兩種情況,如第一個圖所示,ckl_b則可以采樣到signal_a_in,但是如第二個圖所示,只有單脈沖,就不能確保可以采樣到signal_a_in,這種情況用兩級觸發器同步是沒有用的,


所以針對第二種情況需要特殊處理,如下所示為針對第二種跨時鐘域的處理代碼:
//----------------快時鐘域到慢時鐘域----------------//
module mul_clk(
input clk_a,
input clk_b,
input rst_n,
input pulse_a,
output pulse_b
);
reg signal_a;
reg signal_b;
reg [1:0]signal_a_r;
reg [1:0]signal_b_r;
//----------時鐘域A下進行脈沖pulse_a的展寬------------//
always@(posedge clk_a or negedge rst_n)begin
if(!rst_n)
signal_a <= 1'b0;
else if(pulse_a)
signal_a <= 1'b1;
else if(signal_a_r[1])
signal_a <= 1'b0;
else
signal_a <= signal_a;
end
//--------時鐘域B下采集時鐘域A拓展的脈寬信號signal_a-------//
always@(posedge clk_b or negedge rst_n)begin
if(!rst_n)
signal_b <= 1'b0;
else
signal_b <= signal_a;
end
//-------時鐘域B下快取signal_b信號,生成時鐘域B下的脈沖------//
always@(posedge clk_b or negedge rst_n)begin
if(!rst_n)
signal_b_r <= 2'b00;
else
signal_b_r <= {signal_b_r[0],signal_b};
end
assign pulse_b = ~signal_b_r[1] & signal_b_r[0];
//--------時鐘域A下采集signal_b_r,反饋到時鐘域A控制signal_a拉低------//
always@(posedge clk_a or negedge rst_n)begin
if(!rst_n)
signal_a_r <= 2'b00;
else
signal_a_r <= {signal_a_r[0],signal_b_r[1]};
end
endmodule
仿真代碼:
`timescale 1ns/1ns
module mul_clk_tb;
// reg clk;
// reg rst_n;
// reg pulse_a;
//
// wire pulse_b;
//
// mul_clk mul_clk_inst(
// .clk (clk ), //快時鐘域時鐘
// .rst_n (rst_n ),
// .pulse_a (pulse_a ),
// .pulse_b (pulse_b )
//);
reg clk_a;
reg clk_b;
reg rst_n;
reg pulse_a;
wire pulse_b;
mul_clk mul_clk_inst(
.clk_a (clk_a ),
.clk_b (clk_b ),
.rst_n (rst_n ),
.pulse_a (pulse_a ),
.pulse_b (pulse_b )
);
initial clk_a = 0;
always#10 clk_a = ~clk_a;
initial clk_b = 0;
always#30 clk_b = ~clk_b;
initial begin
rst_n = 0;
pulse_a = 0;
#200;
rst_n = 1;
#200;
pulse_a = 1;
#30;
pulse_a = 0;
#500;
$stop;
end
endmodule
波形仿真:

轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/286860.html
標籤:其他
上一篇:平衡放大器優缺點
