题解 | #信号发生器#
信号发生器
https://www.nowcoder.com/practice/39f6766689cc448e928a0921d1d1f858
参考题解可知题目未给出的信息,其中的cnt只用于产生方波,注意三角波的flag转换时刻,编写代码如下(附上仿真):
// 方波的周期是20,锯齿波的周期是21,三角波的周期是40,且wave的最大值是20
`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,negedge rst_n)begin
if(!rst_n)begin
wave <= 0;
end
else begin
case(wave_choise)
0:wave <= ((cnt>=9)&&cnt!=19)?20:0;
1:wave <= wave<=19?wave+1:0;
2:wave <= flag?wave+1:wave-1;
default:wave <= 0;
endcase
end
end
always@(posedge clk,negedge rst_n)begin
if(!rst_n)begin
cnt <= 0;
flag<= 0;
end
else begin
cnt <= (wave_choise==0)?(cnt==19?0:cnt+1):0;
// flag<= (wave_choise==2) ? (((wave==1)&&(!flag)) ? 1 : (((wave==19)&&(flag))?0:flag)) : 0;
//三目运算太长就不如ifelse语句简洁明了
if (wave_choise==2) begin
if ((wave==1)&&(!flag)) begin
flag <= 1;
end
if ((wave==19)&&(flag)) begin
flag <= 0;
end
end
else begin
flag <= 0;
end
end
end
endmodule
`timescale 1ns / 1ps
module tb_signal_generator;
// signal_generator Parameters
parameter PERIOD = 10;
// signal_generator Inputs
reg clk = 0 ;
reg rst_n = 0 ;
reg [1:0] wave_choise = 0 ;
// signal_generator Outputs
wire [4:0] wave ;
initial
begin
forever #(PERIOD/2) clk=~clk;
end
initial
begin
$dumpfile ("HDL_bit_wave.vcd");
$dumpvars;
#(PERIOD*2) rst_n = 1;
end
signal_generator u_signal_generator (
.clk ( clk ),
.rst_n ( rst_n ),
.wave_choise ( wave_choise [1:0] ),
.wave ( wave [4:0] )
);
initial
begin
#(PERIOD*2);
#(PERIOD*52) wave_choise = 2'b00;
#(PERIOD*52) wave_choise = 2'b01;
#(PERIOD*52) wave_choise = 2'b10;
#(PERIOD*52) wave_choise = 2'b00;
#(PERIOD*52) wave_choise = 2'b11;
#(PERIOD*52);
$finish;
end
endmodule
