题解 | #信号发生器#

信号发生器

http://www.nowcoder.com/practice/39f6766689cc448e928a0921d1d1f858

简析

这道题比较难,想了很久才写出满意的程序。首先,方波的周期是20,锯齿波的周期是21,三角波的周期是40,且wave的最大值是20。题目没有明确告知,我是从其他人的题解中知道的。下面分别分析一下三种波形如何产生。

方波

方波模式需注意wave在什么时候翻转。设置一个计数器cnt,计数范围是0-19。该计数器仅在方波模式也就是wave_choise==0时工作。

// 仅在方波模式工作的计数器
always@(posedge clk or negedge rst_n) begin
    if(~rst_n)
      cnt <= 0;
    else
      cnt <= wave_choise!=0 ? 0:
             cnt        ==19? 0:
             cnt + 1;
end

cnt值在0~9时,wave==20;当cnt值在10~19时,wave==0。也就是wave应在cnt==10时从0变为20。但由于非阻塞赋值,cnt==10时,wave应对cnt==9是否成立进行判断。cnt==19也是同样原因。

wave <= cnt ==9 ? 20: 
        cnt ==19? 0 :
        wave;

锯齿波

锯齿波比较简单。wave产生锯齿波时,需要从0增加到20,所以周期是21。 当wave增加到20时,清零。

wave <= wave==20? 0: wave+1;

三角波

三角波模式需要设置一个标志位flagflag仅在三角波模式也就是wave_chosie==2时工作。当flag==0时,wave减少;当flag==1时,wave增加。

wave <= flag==0 ? wave-1: wave+1;

alt
由波形图得知,刚进入三角波模式时,wave是下降的,所以flag的默认值是0。wave在最小值0和最大值20时,flag应进行翻转。同样由于是非阻塞赋值,所以wave上升到19时,flag从1到0,也就是flag <= wave==19&&flag==1? 0: flagwave下降到1时,flag从0到1,也就是flag <= wave==1&&flag==0? 1: flag

    always@(posedge clk or negedge rst_n) begin
        if(~rst_n)
            flag <= 0;
        else
            flag <= wave_choise!=2 ? 0:
                    wave       ==1 ? 1:    
                    // wave==1&&flag==0 ? 1: // 等价
                    wave       ==19? 0:    
                    // wave==19&&flag==1 ? 0: // 等价
                    flag;
    end

代码

`timescale 1ns/1ns
module signal_generator(
	input clk,
	input rst_n,
	input [1:0] wave_choise,
	output reg [4:0]wave
	);

    reg [4:0] cnt;
    reg flag;
    
  	// 方波模式下,计数器控制
    always@(posedge clk or negedge rst_n) begin
        if(~rst_n)
            cnt <= 0;
        else
            cnt <= wave_choise!=0 ? 0:
                   cnt        ==19? 0:
                   cnt + 1;
    end
    
  	// 三角波模式下,标志位控制
    always@(posedge clk or negedge rst_n) begin
        if(~rst_n)
            flag <= 0;
        else
            flag <= wave_choise!=2 ? 0:
                    wave       ==1 ? 1:
                    wave       ==19? 0:
                    flag;
    end
    
  
  	// 更新wave信号
    always@(posedge clk or negedge rst_n) begin
        if(~rst_n) 
            wave <= 0;
        else 
            case(wave_choise)
                0      : wave <= cnt == 9? 20    : 
                                 cnt ==19? 0     :
                                 wave;
                1      : wave <= wave==20? 0     : wave+1;
                2      : wave <= flag==0 ? wave-1: wave+1;
                default: wave <= 0;
            endcase
    end
endmodule
Verilog篇题解 文章被收录于专栏

本人对牛客网verilog篇题目一些理解

全部评论
当wave是0的时候,wave_choice变成2,这个是时候flag是不是有问题?三角波形没法上升。
4 回复 分享
发布于 2022-06-18 15:51
这个不太严谨,对这道题的tb倒是可以 在0和20时都可能出问题
1 回复 分享
发布于 2022-07-05 16:26
为啥没有tb文件呀
点赞 回复 分享
发布于 2022-05-11 17:27
三目运算符的嵌套,厉害
点赞 回复 分享
发布于 2022-05-18 16:43
兄弟,你这个我倒是可以看懂,但是我理解的cnt在10和0的时候wave变换,而不是9和19.可以点我一下吗?
点赞 回复 分享
发布于 2023-10-08 13:02 安徽

相关推荐

10-30 23:23
已编辑
中山大学 Web前端
去B座二楼砸水泥地:这无论是个人素质还是专业素质都👇拉满了吧
点赞 评论 收藏
分享
我也曾抱有希望:说的好直白
点赞 评论 收藏
分享
58 4 评论
分享
牛客网
牛客企业服务