题解 | #时钟分频(偶数)#【计数器实现】

时钟分频(偶数)

https://www.nowcoder.com/practice/49a7277c203a4ddd956fa385e687a72e

思路

本道题的解决思路有很多。这里介绍计数器的方法。为什么执着于计数器方法呢?因为小编认为计数器方法是解决分频问题最根本的办法。无论多少次分频,都可以使用这种方法来解决。

通过观察题目的波形图我们可以看出,clk_out2是每经历一个完整周期就要翻转一次,clk_out4是每经历两个完整周期就要翻转一次,clk_out8是每经历4个完整周期就要翻转一次。

如果能考虑到上面的点,那么思路就很清晰了。接下来就只是一些细节问题。

代码

`timescale 1ns/1ns
module even_div
    (
    input     wire rst ,
    input     wire clk_in,
    output    wire clk_out2,
    output    wire clk_out4,
    output    wire clk_out8
    );
//*************code***********//
	reg clk_out2_r=0,clk_out4_r=0,clk_out8_r=0;
	reg [2:0]cnt;
	always @(posedge clk_in or negedge rst) begin
		if (!rst)begin
            cnt=0;
        end
		else begin
            if (cnt==3'd3)cnt<=0;
			else cnt<=cnt+1;
            // cnt=cnt+1;
		end
	end

	always @(posedge clk_in or negedge rst)begin
		if (!rst)begin
			clk_out2_r=0;
			clk_out4_r=0;
			clk_out8_r=0;
		end
		else begin
			clk_out2_r=~clk_out2_r;
			if (cnt==0||cnt==3'b010)clk_out4_r<=~clk_out4_r;
			if (cnt==0)clk_out8_r=~clk_out8_r;
		end	
	end
	assign clk_out2=clk_out2_r;
	assign clk_out4=clk_out4_r;
	assign clk_out8=clk_out8_r;
//*************code***********//
endmodule








细节问题:

实不相瞒。小编做这道题目时,花了大量时间。因为clk_out4的时钟一直对不上。究其原因,还是小编太菜了,呜呜呜呜,哭晕在厕所了。。。。。

  1. 如何做到三个clk最开始都是高

观察波形图不难发现,当rst为1后的第一个clk_in上升沿,三个clk_outx都是1。所以如何做到最开始三个clk_outx都是1呢?很简单,当cnt计数到0时,就让它们翻转。

2.为何计数器是cnt<=cnt+1;

最开始小编写的是cnt=cnt+1,但最后一直通不过【小编也是因为这花费了很多时间。。。】。小编去问cha老师,cha老师说,用cnt=cnt+1也是可以的,但是会有一些问题,如下:

咱也不知道会有啥逻辑错误和难以调试的问题。反正为了保险,咱还是统一全部用cnt<=cnt+1吧。

3.为何clk_out4_r是在cnt=0或cnt=2时变化?而不是在cnt=0或cnt=1时变化?

这个问题就要看看此代码的波形图:

发现没?clk_out4是在cnt为0或者为2时翻转的。咱小伙伴就要问了,明明从0开始计数,为什么不在0和1处翻转,而在0和2呀?原因是,rst为0时,cnt就为0了,当rst为1后的第一次clk_in上升沿时,cnt此时变成1了。所以第一轮的cnt计数不是从0开始的,而是从1开始计数的。

全部评论

相关推荐

吃不饱的肱二头肌很想退休:tnnd 我以为选妹子呢,亏我兴高采烈的冲进来😠
投递快手等公司10个岗位
点赞 评论 收藏
分享
ArisRobert:统一解释一下,第4点的意思是,公司按需通知员工,没被通知到的员工是没法去上班的,所以只要没被通知到,就自动离职。就是一种比较抽象的裁员。
点赞 评论 收藏
分享
点赞 收藏 评论
分享
牛客网
牛客企业服务