题解 | #信号发生器#

题目说明

1.方波的周期是20,至于为什么是20,原因如下:按理来说wave是5位的,方波应该在0~15是低电平(即0),在16~31是高电平(即1),但是这里是按0~9是低电平(即0),在10~19是高电平(即1),这是提交结果后发现wave的最大值为20,所以就变为了紫色字体所表示的范围;

always@(posedge clk or negedge rst_n) begin
    if(!rst_n)
        cnt <= 0;
    else
        cnt <= wave_choise != 0 ? 0 : (cnt == 5'd19) ? 5'b0 : cnt + 1'b1;
		// 当wave_choise变为除0以外的数值时,要让计数器cnt的值恢复为0,
		// 方便下次wave_choise变为0后,计数器可以从0开始进行计数;
end

2.锯齿波的实现原理很简单,就是让一个计数器从0累加到20,计数器等于20的下个上升沿变为0,之后继续累加到20,周而复始罢了

wave <= wave == 5'd20 ? 0 : wave + 1'b1;
// 当wave_choise从0变为1时,此时wave的值从20经一个时钟沿后变为0,这时可以让wave充当这个计数器的任务,
// 即为 --> 从0累加到20,wave等于20的下个上升沿变为0,之后继续累加到20,周而复始;

3.三角波的实现原理也很简单,就是当wave从0累加到20后就开始递减,当wave递减到0后,在下一个时钟上升沿到来后开始累加,周而复始,在C语言中,也就是设置一个标志位flag(初始化设置为0),当wave递减到0后,标志位flag置为1,wave开始累加,当wave累加到20后,标志位flag置为0,进行减法,直到wave递减为0后,标志位flag置为1,即标志位flag=1表示进行累加,标志位flag=0表示进行递减

always@(posedge clk or negedge rst_n)begin
	if(!rst_n)
		flag <= 1'b0;
	else if(wave_choise == 2'b10)begin
		if(wave == 5'd1)// 这里不是wave == 5'd0;是因为非阻塞赋值会延后一个周期才能收到更新后的值
			flag <= 1'b1;
		else if(wave == 5'd19)// 这里不是wave == 5'd20;是因为非阻塞赋值会延后一个周期才能收到更新后的值
			flag <= 1'b0;
		else
			flag <= flag;
	end
	else
		flag <= flag;
end

wave <= flag == 1'b0 ? wave - 1'b1 : wave + 1'b1;

最终verilog程序如下:

`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 == 5'd19) ? 5'b0 : cnt + 1'b1;
end
always@(posedge clk or negedge rst_n)begin
	if(!rst_n)
		flag <= 1'b0;
	else if(wave_choise == 2'b10)begin
		if(wave == 5'd1)
			flag <= 1'b1;
		else if(wave == 5'd19)
			flag <= 1'b0;
		else
			flag <= flag;
	end
	else
		flag <= flag;
end
always@(posedge clk or negedge rst_n)begin
	if(!rst_n)
		wave <= 5'b0;
	else
		case(wave_choise)
			2'b00	:	wave <= cnt == 5'd9 ? 5'd20 : cnt == 5'd19 ? 5'd0 : wave;
			2'b01	:	wave <= wave == 5'd20 ? 0 : wave + 1'b1;
			2'b10	:	wave <= flag == 1'b0 ? wave - 1'b1 : wave + 1'b1;
			default	:	wave <= 5'bx;
		endcase
end
endmodule
全部评论

相关推荐

跨考小白:本人宣布对美团施行单方面制裁,制裁一个月
投递美团等公司10个岗位
点赞 评论 收藏
分享
点赞 收藏 评论
分享
牛客网
牛客企业服务