列表

详情


VL29. 信号发生器

描述

题目描述:

请编写一个信号发生器模块,根据波形选择信号wave_choise发出相应的波形:wave_choice=0时,发出方波信号;wave_choice=1时,发出锯齿波信号;wave_choice=2时,发出三角波信号。

       模块的接口信号图如下:


       模块的时序图如下:


请使用Verilog HDL实现以上功能,并编写testbench验证模块的功能

输入描述

clk:系统时钟信号
rst_n:异步复位信号,低电平有效
wave_choise:2比特位宽的信号,根据该信号的取值不同,输出不同的波形信号

输出描述

wave:5比特位宽的信号,根据wave_choise的值,输出不同波形的信号

原站题解

Verilog 解法, 执行用时: 0ms, 内存消耗: 0KB, 提交时间: 2022-08-06

`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 cnt_add;
    always @(posedge clk or negedge rst_n)
        begin
            if(rst_n == 1'b0)
                begin
                    wave <= 5'd0;
                    cnt <= 5'd0;
                    cnt_add <= 1'b0;
                end
            else if(wave_choise == 2'd0)
                begin
                    if(wave > 5'd0 && wave < 5'd20)
                        begin
                            wave <= 5'd0;
                        end
                    else
                        begin
                            cnt <= cnt + 1'b1;
                            if(cnt == 5'd9)
                                begin 
                                    wave <= 5'd20;
                                end
                            else if(cnt == 5'd19)
                                begin
                                    wave <= 5'd0;
                                    cnt <= 5'd0;
                                end
                        end
                end
            else if(wave_choise == 2'd1)
                begin
                    cnt <= 5'd0;
                    if(wave == 5'd20)
                        wave <= 5'd0;
                    else
                        wave <= wave + 1'b1;
                end
            else if(wave_choise == 2'd2 )
                begin
                    cnt <= 5'd0;
                    if(wave == 5'd0)
                        begin
                            cnt_add <= 1'b1;
                            wave <= wave + 1'b1;
                        end
                    else if(wave == 5'd20)
                        begin
                            cnt_add <= 1'b0;
                            wave <= wave - 1'b1;
                        end
                    else
                        begin
                            if(cnt_add == 1'b0)
                                wave <= wave - 1'b1;
                            else
                                wave <= wave + 1'b1;
                        end
                end
            else
                wave <= 5'd0;
        end
endmodule 

Verilog 解法, 执行用时: 0ms, 内存消耗: 0KB, 提交时间: 2022-08-06

`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 <= 5'd0;
        else if(wave_choise == 2'd0)
            begin
                if(cnt == 5'd19)
                    cnt <= 5'd0;
                else
                    cnt <= cnt + 1'b1;
            end
        else
            cnt <= 5'd0;
    end
    
    always @(posedge clk or negedge rst_n)begin
        if(!rst_n)
            flag <= 1'b0;
        else if(wave_choise == 2'd2)
            begin
                if(wave == 5'd1)
                    flag <= 1'b1;
                else if(wave == 5'd19)
                    flag <= 1'b0;
                else
                    flag <= flag;
            end
        else
            flag <= 1'b0;
    end
    
    always @(posedge clk or negedge rst_n)begin
        if(!rst_n)
            wave <= 5'd0;
        else
            case(wave_choise)
                2'd0:
                    begin
                        if(cnt == 5'd9)
                            wave <= 5'd20;
                        else if(cnt == 5'd19)
                            wave <= 5'd0;
                        else
                            wave <= wave;
                    end
                2'd1:
                    begin
                        if(wave == 5'd20)
                            wave <= 5'd0;
                        else
                            wave <= wave + 1'b1;
                    end
                2'd2:
                    begin
                        if(flag == 1'b0)
                            wave <= wave - 1'b1;
                        else
                            wave <= wave + 1'b1;
                    end
                default:    wave <= 5'd0;
            endcase
    end

  
endmodule

Verilog 解法, 执行用时: 0ms, 内存消耗: 0KB, 提交时间: 2022-08-06

`timescale 1ns/1ns
module signal_generator(
	input clk,
	input rst_n,
    input [1:0] wave_choise,
	output reg [4:0]wave
	);
    
    reg [4:0] timer;
    always@(posedge clk or negedge rst_n) begin
        if(!rst_n) begin
            timer <= 'b0;
        end else begin
            case(wave_choise)
                'd0: timer <= timer == 'd19 ? 'd0 : timer + 1;
                default : timer <= 'b0;
            endcase
        end
    end
    
    reg flag;
    always@(posedge clk or negedge rst_n) begin
        if(!rst_n) begin
            flag <= 'b0;
        end else begin
            flag <= wave_choise != 2 ? 0 :
                    wave == 1 ? 1 :
                    wave == 19 ? 0 :
                    flag;
        end
    end
    
    
    always@(posedge clk or negedge rst_n) begin
        if(!rst_n) begin
            wave <= 'b0;
        end else begin
            case(wave_choise)
                'd0: wave <= timer == 9 ? 20 :
                             timer == 19 ? 0 :
                             wave;
                'd1: wave <= (wave == 'd20) ? 0 : wave + 1;
                'd2: wave <= flag ? wave + 1 : wave - 1;
            endcase
        end
    end
  
endmodule

Verilog 解法, 执行用时: 0ms, 内存消耗: 0KB, 提交时间: 2022-08-06

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

    reg [4:0] next_wave;
    reg wave_choise_r;
    reg inc_or_dec;
    reg [3:0] cnt;
    
    always @(posedge clk or negedge rst_n) begin
        if(~rst_n)
            cnt <= 4'd0;
        else if(wave_choise != 2'd0)
            cnt <= 4'd0;
        else if(cnt == 4'd9)
            cnt <= 4'd0;
        else
            cnt <= cnt + 1'b1;
    end
    
    always @(posedge clk or negedge rst_n) begin
        if(~rst_n)
            inc_or_dec <= 1'd1;
        else if(wave_choise != 2'd2 && |next_wave)
            inc_or_dec <= 1'd0;
        else if(wave_choise != 2'd2 && next_wave == 5'd0)
            inc_or_dec <= 1'd1;
        else if(next_wave == 5'd20)
            inc_or_dec <= 1'd0;
        else if(next_wave == 5'd0)
            inc_or_dec <= 1'd1;
        else
            inc_or_dec <= inc_or_dec;
    end
    
    always @(posedge clk or negedge rst_n) begin
        if(~rst_n)
            wave_choise_r <= 1'd0;
        else
            wave_choise_r <= wave_choise;
    end
    
    always @(*) begin
        if(wave_choise == 2'd0) begin
            if(wave_choise_r != 2'd0)
                next_wave = 5'd0;
            else if(cnt == 4'd9 && wave == 5'd0)
                next_wave = 5'd20;
            else if(cnt == 4'd9 && wave == 5'd20)
                next_wave = 5'd0;
            else
                next_wave = wave;
        end
        else if(wave_choise == 2'd2) begin
            if(inc_or_dec)
                next_wave = wave + 1'd1;
            else
                next_wave = wave - 1'd1;
        end
        else if(wave_choise == 2'd1) begin
            if(wave_choise_r != 2'd1)
                next_wave = 5'd0;
            else if(wave == 5'd20)
                next_wave = 5'd0;
            else
                next_wave = wave + 1'b1;
        end
    end
    
    always @(posedge clk or negedge rst_n) begin
        if(~rst_n)
            wave <= 5'd0;
        else
            wave <= next_wave;
    end
    
endmodule

Verilog 解法, 执行用时: 0ms, 内存消耗: 0KB, 提交时间: 2022-08-06

`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)begin
            cnt <= 5'b0;
        end
        else begin
            cnt <= wave_choise == 0 ?  cnt == 19 ? 0 : cnt + 1 : 0;
        end
    end
    //三角波模式下的标志位控制
        always@(posedge clk or negedge rst_n)begin
            if(!rst_n)begin
                flag <= 0;
            end
            else begin
                flag <= wave_choise != 2 ? 0 : (wave == 19 && flag == 1) ? 0 : wave == 1? 1 :flag ;
            end  //当wave 19 时,flag变成0,由于是非阻塞幅值,波形模块的flag仍为1,进而wave变为20.故在19的时候判断
        end
        //wave
        always@(posedge clk or negedge rst_n)begin
            if(!rst_n)begin
                wave <= 0;
            end
            else begin
                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
        end
        
endmodule

上一题