跨时钟域处理
题目:多时钟域设计中,如何处理跨时钟域
- 单bit:两级触发器同步(适用于慢到快)
- 多bit:采用异步FIFO,异步双口RAM
- 加握手信号
- 格雷码转换
题目:编写Verilog代码描述跨时钟域信号传输,慢时钟域到快时钟域
1 reg [1:0] signal_r; 2 //------------------------------------------------------- 3 // 4 always @(posedge clk or negedge rst_n)begin 5 if(rst_n == 1'b0)begin 6 signal_r <= 2'b00; 7 end 8 else begin 9 signal_r <= {signal_r[0], signal_in}; 10 end 11 end 12 13 assign signal_out = signal_r[1];
题目:编写Verilog代码描述跨时钟域信号传输,快时钟域到慢时钟域
跨时钟域处理从快时钟域到慢时钟域,如果是下面第一个图,clkb则可以采样到signal_a_in,但是如果只有单脉冲,如第二个图,则不能确保采样到signal_a_in。这个时候用两级触发器同步是没有用的。
代码如下:
1 //Synchronous 2 module Sync_Pulse( 3 input clka, 4 input clkb, 5 input rst_n, 6 input pulse_ina, 7 output pulse_outb, 8 output signal_outb 9 ); 10 11 //------------------------------------------------------- 12 reg signal_a; 13 reg signal_b; 14 reg [1:0] signal_b_r; 15 reg [1:0] signal_a_r; 16 17 //------------------------------------------------------- 18 //在clka下,生成展宽信号signal_a 19 always @(posedge clka or negedge rst_n)begin 20 if(rst_n == 1'b0)begin 21 signal_a <= 1'b0; 22 end 23 else if(pulse_ina == 1'b1)begin 24 signal_a <= 1'b1; 25 end 26 else if(signal_a_r[1] == 1'b1) 27 signal_a <= 1'b0; 28 else 29 signal_a <= signal_a; 30 end 31 32 //------------------------------------------------------- 33 //在clkb下同步signal_a 34 always @(posedge clkb or negedge rst_n)begin 35 if(rst_n == 1'b0)begin 36 signal_b <= 1'b0; 37 end 38 else begin 39 signal_b <= signal_a; 40 end 41 end 42 43 //------------------------------------------------------- 44 //在clkb下生成脉冲信号和输出信号 45 always @(posedge clkb or negedge rst_n)begin 46 if(rst_n == 1'b0)begin 47 signal_b_r <= 2'b00; 48 end 49 else begin 50 signal_b_r <= {signal_b_r[0], signal_b}; 51 end 52 end 53 54 assign pulse_outb = ~signal_b_r[1] & signal_b_r[0]; 55 assign signal_outb = signal_b_r[1]; 56 57 //------------------------------------------------------- 58 //在clka下采集signal_b[1],生成signal_a_r[1]用于反馈拉低signal_a 59 always @(posedge clka or negedge rst_n)begin 60 if(rst_n == 1'b0)begin 61 signal_a_r <= 2'b00; 62 end 63 else begin 64 signal_a_r <= {signal_a_r[0], signal_b_r[1]}; 65 end 66 end 67 68 endmodule
这部分代码参考:
作者:肉娃娃
出处:https://home.cnblogs.com/u/rouwawa/
慢到快,单脉冲
慢到快,长信号传递
快到慢,单脉冲
单脉冲,长信号传递
上述代码可以实现快到慢,慢到快时钟域任意转换,pulse_outb会输出单个脉冲,signal_outb输出信号时间长度最少为clkb的四个周期,当signal_a_in的信号长度大于clkb的四个周期,signal_outb输出与signal_a_in时间长度相同。
题目:边沿检测
1 reg [1:0] signal_r; 2 //------------------------------------------------------- 3 // 4 always @(posedge clk or negedge rst_n)begin 5 if(rst_n == 1'b0)begin 6 signal_r <= 2'b00; 7 end 8 else begin 9 signal_r <= {signal_r[0], signal_in}; 10 end 11 end 12 13 assign singal_posedge = ~signal_r[1] & signal_r[0];//检测上升沿 14 assign singal_negedge = signal_r[1] & ~signal_r[0];//检测下降沿
记忆:上升沿之前是0,现在变成1,所以上个周期传输到的signal_r[1]是0所以取反。反之亦然。
转载请注明出处:NingHeChuan(宁河川)
个人微信订阅号:硅农
如果你想及时收到个人撰写的博文推送,可以扫描左边二维码(或者长按识别二维码)关注个人微信订阅号
知乎ID:NingHeChuan
微博ID:NingHeChuan