牛客网Verilog刷题——VL48

牛客网Verilog刷题——VL48

  • 题目
  • 答案

题目

  在data_en为高期间,data_in将保持不变,data_en为高至少保持3个B时钟周期。表明,当data_en为高时,可将数据进行同步。本题中data_in端数据变化频率很低,相邻两个数据间的变化,至少间隔10个B时钟周期。
  电路的接口如下图所示:
牛客网Verilog刷题——VL48_第1张图片

  端口说明如下表所示:

牛客网Verilog刷题——VL48_第2张图片
   本题考察的就是多比特跨时钟域处理,但是题目中没有指出是快时钟域到慢时钟域还是慢时钟域到快时钟域,只是明确指出data_en至少保持3个clk_b时钟周期,data_in至少保持10个clk_b时钟周期,也就是说,时钟域clk_a下的信号同步到时钟域clk_b下,在clk_b的上升沿处,肯定能被采集到,不会出现像我们常见的快时钟域到慢时钟域处理中,出现的慢时钟域采集不到快时钟域信号的情况,所以本题只需要简单的将单比特的使能信号进行跨时钟域处理后,再作为多比特跨时钟域处理打拍中的使能信号即可。

答案

module mux(
	input 				clk_a	, 
	input 				clk_b	,   
	input 				arstn	,
	input				brstn   ,
	input		[3:0]	data_in	,
	input               data_en ,

	output reg  [3:0] 	dataout
);
    reg [3:0] data_reg; //输入数据打拍(时钟域clk_a)
    reg       data_en_reg_a; //输入使能信号打拍(时钟域clk_a)
	reg       data_en_reg1_b, data_en_reg2_b; //打两拍跨时钟域处理(时钟域clk_b)
    
	//输入数据在clk_a时钟域下打一拍,消除毛刺
    always@(posedge clk_a or negedge arstn) begin
        if(~arstn)
            data_reg <= 0;
        else
            data_reg <= data_in;
    end
    
	//使能信号在clk_a时钟域下打一拍,消除毛刺
    always@(posedge clk_a or negedge arstn) begin
        if(~arstn)
            data_en_reg_a <= 0;
        else
            data_en_reg_a <= data_en;
    end
    
	//时钟域clk_a下使能信号同步到时钟域clk_b下(打两拍,防止亚稳态)
    always@(posedge clk_b or negedge brstn) begin
        if(~brstn) begin
            data_en_reg1_b <= 0;
            data_en_reg2_b <= 0;
        end
        else begin
            data_en_reg1_b <= data_en_reg_a;
            data_en_reg2_b <= data_en_reg1_b;
        end
    end
    
	//时钟域clk_b下,根据同步后的使能信号进行取值
    always@(posedge clk_b or negedge brstn) begin
        if(~brstn) 
            dataout <= 0;
        else 
            dataout <= data_en_reg2_b? data_reg: dataout;
    end
endmodule

你可能感兴趣的:(牛客刷题,fpga开发,Verilog,跨时钟域处理)