一种思路,大部分借鉴前辈的优秀题解

`timescale 1ns/1ns
module signal_generator(
	input clk,
	input rst_n,
	input [1:0] wave_choise,
	output reg [4:0]wave
	);
    //
    reg [5:0] count;          //这里的计数只有矩形脉冲使用,其余两种wave本身可以用来计数
    reg flag;                 //flag信号用来表征三角脉冲的上升下降状态,高为上升,低为下降
    always@(posedge clk or negedge rst_n) begin
        if(!rst_n) begin
            wave<='d0;
            count<='d0;
            flag<=0;          //这里的复位解释了为什么题干中锯齿波转三角波时是先下降,因为flag初始状态就是0
        end
        else begin
            case(wave_choise)
                2'b00: begin               //这里需要额外引入计数,因为矩形波wave只有两种值,不能用来计数
                    if(count=='d9) begin
                        wave<='d20;        //三种波形最大值都为20
                        count<=count+1;end
                    else if(count=='d19) begin   //翻转
                        wave<='d0;
                        count<='d0;end
                    else begin
                        wave<=wave;               //count不是9和19,wave就保持原态
                        count<=count+1;end
                end
                2'b01: begin                   //锯齿波
                    if(wave=='d20)             //wave本身充当计数位
                        wave<='d0;
                    else 
                        wave<=wave+1;
                end
                2'b10: begin                   //三角波
                    if(flag) begin             //判断上升状态内的逻辑,这样写不容易遗漏
                        if(wave<'d20) begin    //在上升状态,只需要考虑wave什么时候下降,并给出flag=0即可
                            flag<=flag;
                            wave<=wave+1;
                        end
                        else if(wave=='d20) begin  //wave在其为20时就需要给出flag=0
                            flag<=~flag;
                            wave<=wave-1;      //时序逻辑要提前给出下一状态,wave为20时下一个状态就是19
                        end
                    end
                    else begin                  //同理,下降状态,只需要考虑wave为什么值时需要给出flag=1即可
                        if(wave>'d0) begin   
                            flag<=flag;
                            wave<=wave-1;  
                        end
                        else if(wave=='d0) begin //wave此时没有退步空间了(*__*),给出flag=1,上升
                            flag<=~flag;
                            wave<=wave+1;        //wave为0时,下一状态就是1
                        end
                    end
                        
                end
            endcase     
        end
    end
  
endmodule