牛客网Verilog刷题——VL48

牛客网Verilog刷题——VL48

题目

  在data_en为高期间,data_in将保持不变,data_en为高至少保持3个B时钟周期。表明,当data_en为高时,可将数据进行同步。本题中data_in端数据变化频率很低,相邻两个数据间的变化,至少间隔10个B时钟周期。
  电路的接口如下图所示:
在这里插入图片描述

  端口说明如下表所示:

在这里插入图片描述
   本题考察的就是多比特跨时钟域处理,但是题目中没有指出是快时钟域到慢时钟域还是慢时钟域到快时钟域,只是明确指出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
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值