题解 | #信号发生器#
信号发生器
http://www.nowcoder.com/practice/39f6766689cc448e928a0921d1d1f858
只能说这道题的题目出的非常不详细,波形是看不出清楚了,波形最高值为5'd20是试错试出来的。周期嘛根据20这个值再结合波形可以大致得出。 方波的周期为20个clk,前10个clk为0,后10个clk为20,需要cnt计数; 锯齿波从0上升到20,每个时钟周期加1,wave本身在计数,cnt可以不动; 三角波从0上升到20,再从20下降到0,wave本身在计数,但需要一个标志flag记录是递增还是递减。 另外通过波形知道:
- 从方波转到锯齿波,采样到wave_choise为1后,wave直接置0;
- 从锯齿波转到三角波,如果此时wave不为0,需要将wave降为0之后再递增。 所以需要一个上一个choise的记录,如果是choise转换,需要设置各个choise的初始状态。
`timescale 1ns/1ns
module signal_generator(
input clk,
input rst_n,
input [1:0] wave_choise,
output reg [4:0]wave
);
reg flag; // for ++1/--1
reg [3:0] cnt;
reg [1:0] last_choise;
always @(posedge clk,negedge rst_n) begin
if (!rst_n)
last_choise <= 2'd0;
else
last_choise <= wave_choise;
end
always @(posedge clk, negedge rst_n) begin
if (!rst_n) begin
wave <= 5'd0;
cnt <=4'd0;
flag <= 1'b0;
end
else if (wave_choise==2'd0) begin
flag <= 1'b0;
if (last_choise!=2'd0) begin
cnt <= 4'd0;
wave = 5'd0;
end
else if (cnt==5'd9) begin
cnt <= 4'd0;
wave <= (wave==5'd0)?5'd20:5'd0;
end
else begin
cnt <= cnt + 1'b1;
wave <= wave;
end
end
else if (wave_choise==2'd1) begin
cnt <= cnt;
flag <= 1'b0;
if (last_choise!=2'd1)
wave = 5'd0;
else if (wave==5'd20)
wave <= 5'd0;
else
wave <= wave + 1'b1;
end
else if (wave_choise==2'd2) begin
cnt <= cnt;
if (last_choise!=2'd2) begin
if (wave!=5'd0) begin
wave = wave - 1'b1;
flag <= 1'b1;
end
else begin
wave = wave + 1'b1;
flag <= 1'b0;
end
end
else if (wave==5'd20) begin
wave <= wave - 1'b1;
flag <= 1'b1;
end
else if (wave==5'd0) begin
wave <= wave + 1'b1;
flag <= 1'b0;
end
else begin
wave <= flag?(wave - 1'b1):(wave + 1'b1);
flag <= flag;
end
end
end
endmodule