欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

手撕Verilog面试题专题——(12)脉冲信号的跨时钟域传输

程序员文章站 2022-04-20 08:32:00
...

慢时钟域到快时钟域 打两拍

Verilog代码:

module BitTrans(
	input 	clkb,
	input	rst,
	input 	din,
	output	dout
);
	reg	[1:0]	tmp;
	[email protected](posedge clkb or negedge rst)	begin
		if(!rst)
			tmp	<= 2'b00;
		else
			tmp	<= {tmp[0], din};
	end

	assign dout	= tmp[1];
	
endmodule

testbench代码:

module BitTrans_tb();
    reg     clka;
    reg     clkb;
    reg     rst;
    wire    din;
    wire    dout;
    
    reg [4:0]   count;
    
    initial begin
        clka = 0;
        clkb = 0;
        rst = 0;
        #25 rst = 1;
    end
    initial begin
        forever #10 clka = ~clka;
    end
    initial begin
        forever #3 clkb = ~clkb;
    end
    
    [email protected](posedge clka or negedge rst)    begin
        if(!rst)
            count   <= 0;
        else
            count   <= count + 1;            
    end
    
    assign din = (count == 1) ? 1 : 0;
    
    BitTrans test(
	.clkb(clkb),
	.rst(rst),
	.din(din),
	.dout(dout)
    );
        
endmodule

仿真波形:
手撕Verilog面试题专题——(12)脉冲信号的跨时钟域传输
当调换两个时钟信号即由快时钟域到慢时钟域中传输,若还采用上述方法,仿真波形如下。即可能慢时钟尚未采到,快时钟域的信号已经发生变化。所以要另想办法
手撕Verilog面试题专题——(12)脉冲信号的跨时钟域传输

快时钟域到慢时钟域

Verilog代码:

module BitTrans(
	input	clka,	//input 	clkb,	//input	rst,
	input 	din,
	output	dout
);
	
	reg			signal_a;
	reg			signal_b;
	reg	[1:0]	signal_ar;
	reg	[1:0]	signal_br;
	
	// 在将快时钟域中的脉冲展开
	[email protected](posedge clka or negedge rst)	begin
		if(!rst)
			signal_a	<= 0;
		else if (din)
			signal_a	<= 1;
		else if	(signal_ar[1])
			signal_a	<= 0;
		else
			signal_a	<= signal_a;
	end
	
	// 在慢时钟域中的对快时钟域中展开的脉冲进行采样
	[email protected](posedge clkb or negedge rst)	begin
		if(!rst)
			signal_b	<= 0;
		else
			signal_b	<= signal_a;
	end
	// 在慢时钟域中打两拍
	[email protected](posedge clkb or negedge rst)	begin
		if(!rst)
			signal_br	<= 0;
		else
			signal_br	<= {signal_br[0], signal_b};
	end	
	
	assign	dout = ~signal_br[1] & signal_br[0];
	// 慢时钟域中采到信号时给快时钟域反馈一个信号
	[email protected](posedge clka or negedge rst)	begin
		if(!rst)
			signal_ar	<= 0;
		else
			signal_ar	<= {signal_ar[0], signal_br[1]};
	end	
	
endmodule

testbench仿真文件:

module BitTrans_tb();
    reg     clka;
    reg     clkb;
    reg     rst;
    wire    din;
    wire    dout;
    
    reg [4:0]   count;
    
    initial begin
        clka = 0;
        clkb = 0;
        rst = 0;
        #25 rst = 1;
    end
    initial begin
        forever #10 clka = ~clka;
    end
    initial begin
        forever #3 clkb = ~clkb;
    end
    
    [email protected](posedge clkb or negedge rst)    begin
        if(!rst)
            count   <= 0;
        else
            count   <= count + 1;            
    end
    
    assign din = (count == 1) ? 1 : 0;
    
    BitTrans test(
    .clka(clkb),
	.clkb(clka),
	.rst(rst),
	.din(din),
	.dout(dout)
    );
        
endmodule

仿真波形:
手撕Verilog面试题专题——(12)脉冲信号的跨时钟域传输

相关标签: 硬件逻辑