牛客网Verilog刷题——VL49

牛客网Verilog刷题——VL49

题目

  从A时钟域提取一个单时钟周期宽度脉冲,然后在新的时钟域B建立另一个单时钟宽度的脉冲。A时钟域的频率是B时钟域的10倍;A时钟域脉冲之间的间隔很大,无需考虑脉冲间隔太小的问题。电路的接口如下图所示。data_in是脉冲输入信号,data_out是新的脉冲信号clk_fast是A时钟域时钟信号,clk_slow是B时钟域时钟信号;rst_n是异步复位信号。

在这里插入图片描述

  输入输出描述:

信号类型输入/输出位宽描述
clk_fastwireIntput1快时钟域时钟信号
clk_slowwireIntput1慢时钟域时钟信号
rst_nwireIntput1异步复位信号,低电平有效
data_inwireIntput1输入脉冲信号(快时钟域脉冲信号)
data_outwireOutput1输出脉冲信号(慢时钟域脉冲信号)

解析

  本题要求设计一个脉冲同步电路,将快时钟域的脉冲信号同步到慢时钟域,得到慢时钟域的脉冲信号。本题考察的实际上就是单比特跨时钟域(脉冲信号从快到慢)。由于快时钟域clk_fast的时钟频率大于慢时钟域clk_slow的时钟频率,快时钟域的脉冲信号可能无法被慢时钟域采样到,因此需要把快时钟域clk_fast的脉冲信号进行展宽,然后再将展宽后的快时钟域下的脉冲信号用“打两拍”的方法同步到慢时钟域,这里存在一个问题:快时钟域的脉冲信号展宽要展宽为几个时钟宽度?什么时候拉低?展宽后的脉冲信号同步到慢时钟域后,需要再进行打拍,用于生成慢时钟域的脉冲信号。

  具体步骤如下:

(1)将快时钟域clk_fast下的脉冲信号signal_pulse_fast进行展宽,展宽后的快时钟域脉冲信号为signal_pulse_fast_extend;
(2)将展宽后的快时钟域脉冲信号signal_pulse_fast_extend同步到慢时钟域clk_slow(打两拍),得到signal_pulse_fast_extend_f2s_2;
(3)再对信号signal_pulse_fast_extend_f2s_2在慢时钟域打一拍后,用于生成慢时钟域脉冲信号signal_pulse_slow;
(4)将慢时钟域的脉冲信号同步到快时钟域(打两拍),得到signal_pulse_slow_s2f_2,用于控制快时钟域展宽脉冲信号signal_pulse_fast_extend的宽度(控制什么时候拉低);

答案

`timescale 1ns/1ns

module pulse_detect(
	input 				clk_fast	, 
	input 				clk_slow	,   
	input 				rst_n		,
	input				data_in		,

	output  		 	dataout
);

wire signal_pulse_fast; //快时钟域脉冲信号
reg  signal_pulse_fast_extend; //快时钟域脉冲信号展宽信号
reg  signal_pulse_fast_extend_f2s_1; //快时钟域脉冲信号展宽信号同步到慢时钟域(打一拍)
reg  signal_pulse_fast_extend_f2s_2; //快时钟域脉冲信号展宽信号同步到慢时钟域(打两拍)
reg  signal_pulse_fast_extend_f2s_2_r; //快时钟域脉冲信号展宽信号同步到慢时钟域(打三拍)

wire signal_pulse_slow; //慢时钟域脉冲信号
reg  signal_pulse_slow_s2f_1; //慢时钟域脉冲信号同步到快时钟域
reg  signal_pulse_slow_s2f_2; //慢时钟域脉冲信号同步到快时钟域

//快时钟域脉冲信号
assign signal_pulse_fast = data_in;

//快时钟域电平信号
always @(posedge clk_fast or negedge rst_n) begin
	if(!rst_n)
		signal_pulse_fast_extend <= 1'b0;
	else if(signal_pulse_fast)
		signal_pulse_fast_extend <= 1'b1;
	else if(signal_pulse_slow_s2f_2)
		signal_pulse_fast_extend <= 1'b0;
	else
		signal_pulse_fast_extend <= signal_pulse_fast_extend;
end

//快时钟域电平信号同步到慢时钟域
always @(posedge clk_slow or negedge rst_n) begin
	if(!rst_n) begin
		signal_pulse_fast_extend_f2s_1 <= 1'b0;
		signal_pulse_fast_extend_f2s_2 <= 1'b0;
	end
	else begin
		signal_pulse_fast_extend_f2s_1 <= signal_pulse_fast_extend;
		signal_pulse_fast_extend_f2s_2 <= signal_pulse_fast_extend_f2s_1;
	end
end

//慢时钟域电平信号打拍
always @(posedge clk_slow or negedge rst_n) begin
	if(!rst_n)
		signal_pulse_fast_extend_f2s_2_r <= 1'b0;
	else
		signal_pulse_fast_extend_f2s_2_r <= signal_pulse_fast_extend_f2s_2;
end

//慢时钟域脉冲信号
assign signal_pulse_slow = signal_pulse_fast_extend_f2s_2 && (~signal_pulse_fast_extend_f2s_2_r);

//慢时钟域脉冲信号同步到快时钟域
always @(posedge clk_fast or negedge rst_n) begin
	if(!rst_n) begin
		signal_pulse_slow_s2f_1 <= 1'b0;
		signal_pulse_slow_s2f_2 <= 1'b0;
 	end
	else begin
		signal_pulse_slow_s2f_1 <= signal_pulse_slow;
		signal_pulse_slow_s2f_2 <= signal_pulse_slow_s2f_1;
	end	
end

assign dataout = signal_pulse_slow;

//--------备注--------//
//本题考察的实际上就是单比特跨时钟域处理的方法(快时钟域到慢时钟域)

endmodule
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值