快时钟域与慢时钟域之间的转化

时钟域就是时钟信号的“势力范围”。一个时钟域只能存在一个时钟信号,但是一个时钟信号最多可以对应两个时钟域,当其上升沿和下降沿分别都被一部分资源敏感的时候。

在时序逻辑中,正是时钟信号将各个存储单元中的数据一级、一级的推动下去,如果时钟信号突然停止,那么整个时序逻辑也将陷入瘫痪

慢到快的DUT

module slow2quick (
                  // input
                  input rst_n              , // system reset
                  input clka               , // clockA
                  input clkb               , // clockB
                  input level_a_in         , // pulsee input from clka
                  // output
                  output pulse_b_neg     , // pulsee output in clkb
                  output pulse_b_pos     , // pulsee output in clkb
                  output level_b_out        // level output in clkb
                  );

parameter         DLY      =  1   ; //

reg level_b_d1, level_b_d2, level_b_d3;

always @ (posedge clka or negedge rst_n)
begin
    if (!rst_n) begin
       level_b_d1 <= #DLY 1'b0;
       level_b_d2 <= #DLY 1'b0;
       level_b_d3 <= #DLY 1'b0;
    end
    else begin
       level_b_d1 <= #DLY level_a_in;
       level_b_d2 <= #DLY level_b_d1;
       level_b_d3 <= #DLY level_b_d2;
    end
end

assign pulse_b_pos = level_b_d2 & (~level_b_d3);
assign pulse_b_neg = level_b_d3 & (~level_b_d2);
assign level_b_out  = level_b_d2;

endmodule

快到慢的DUT

module quick2slow (
                  // input
                  input rst_n              , // system reset
                  input clka               , // clockA
                  input clkb               , // clockB
                  input pulse_a_in          , // pulsee input from clka
                  // output
                  output pulse_b_out        , // pulsee output in clkb
                  output level_b_out        // level output in clkb
                  );

parameter         DLY      =  1   ; //

reg signal_a;
reg signal_b;
reg signal_b_b1;
reg signal_b_b2;
reg signal_b1_a1;
reg signal_b1_a2;

always @ (posedge clka or negedge rst_n)
begin
    if (rst_n == 1'b0)
        signal_a <= # DLY 1'b0 ;
    else if (pulse_a_in)
        signal_a <= # DLY 1'b1 ;
    else if (signal_b1_a2)
        signal_a <= # DLY 1'b0 ;
    else ;
end

always @ (posedge clkb or negedge rst_n)
begin
    if (rst_n == 1'b0)
        signal_b <= # DLY 1'b0 ;
    else
        signal_b <= # DLY signal_a ;
end

always @ (posedge clkb or negedge rst_n)
begin
    if (rst_n == 1'b0) begin
        signal_b_b1 <= # DLY 1'b0 ;
        signal_b_b2 <= # DLY 1'b0 ;
    end
    else begin
        signal_b_b1 <= # DLY signal_b ;
        signal_b_b2 <= # DLY signal_b_b1 ;
    end
end

always @ (posedge clka or negedge rst_n)
begin
    if (rst_n == 1'b0) begin
        signal_b1_a1 <= # DLY 1'b0 ;
        signal_b1_a2 <= # DLY 1'b0 ;
    end
    else begin
        signal_b1_a1 <= # DLY signal_b_b1 ;
        signal_b1_a2 <= # DLY signal_b1_a1 ;
    end
end

assign pulse_b_out = signal_b_b1 & (~signal_b_b2) ;
assign level_b_out = signal_b_b1 ;

endmodule

TB

`timescale 1ns/1ns
module mul_clk_tb;

	reg clka;
	reg clkb;
	reg rst_n;
	reg level_a_in;

	wire pulse_b_neg;
	wire pulse_b_pos;
	wire level_b_out;

	reg  pulse_a_in;
	wire pulse_b_out_l;
	wire pulse_b_out_q;
	wire pulse_b_out;


	slow2quick slow2quick_inst(
		.rst_n		        (rst_n	        ),
		.clka			(clka		),	
		.clkb			(clkb		),	
		.level_a_in		(level_a_in	),
		.pulse_b_neg		(pulse_b_neg	),
		.pulse_b_pos		(pulse_b_pos	),
		.level_b_out		(level_b_out_l	)
);


	quick2slow quick2slow_inst(
		.rst_n		          (rst_n	),
		.clka	           	  (clka         ),
		.clkb	               	  (clkb         ),
		.pulse_a_in		  (pulse_a_in	),
		.pulse_b_out		  (pulse_b_out	),
		.level_b_out		  (level_b_out_q)
 );

	initial clka = 0;
	always#10 clka = ~clka;

	initial clkb = 0;
	always#100 clkb = ~clkb;

	initial begin
	    rst_n = 1;
            #100;
            rst_n = 0;
            #100;
            rst_n = 1;
            #10000;
	    $finish();
	end
//generate level_a_in
always @ (posedge clkb or negedge rst_n) 
 begin 
   if (!rst_n)
       level_a_in <= 0;
   else 
     repeat (100) begin
        level_a_in = {$random}%2;
      end
 end

//generate pulse_a_in  
always @ (posedge clkb or negedge rst_n) 
 begin 
   if (!rst_n)
       pulse_a_in <= 0;
   else 
     repeat (10) begin
        pulse_a_in = {$random}%2;
	#20;
        pulse_a_in = 0;
	#200;
      end
 end


        initial begin
            $fsdbDumpfile("jacky");
            $fsdbDumpvars;
            $vcdpluson;
        end

endmodule

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值