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];
跨时钟域处理从快时钟域到慢时钟域,如果是下面第一个图,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所以取反。反之亦然。