简析
这道题比较难,想了很久才写出满意的程序。首先,方波的周期是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;
三角波
三角波模式需要设置一个标志位flag。flag仅在三角波模式也就是wave_chosie==2时工作。当flag==0时,wave减少;当flag==1时,wave增加。
wave <= flag==0 ? wave-1: wave+1;
由波形图得知,刚进入三角波模式时,wave是下降的,所以flag的默认值是0。wave在最小值0和最大值20时,flag应进行翻转。同样由于是非阻塞赋值,所以wave上升到19时,flag从1到0,也就是flag <= wave==19&&flag==1? 0: flag;wave下降到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

京公网安备 11010502036488号