暂时先把源码和TestBench文件和仿真结果贴出来,原理介绍咱们下次再补上哈。
【Verilog代码】:
module PWM2(
input clk,
input rst,
input [1:0] flag,
output pwm_signal,
output reg [2:0] cnt1,
output reg [2:0] cnt2);
//Requirements: every five clock cycles to a flag
//reg [2:0] cnt1;
//reg [2:0] cnt2;
parameter MAX_COUNT = 5;
always@(posedge clk or negedge rst)
begin
if(!rst)
cnt1 <= 3'd0;
else begin
if(cnt1 >= MAX_COUNT - 1)
cnt1 <= 3'd1;
else
cnt1 <= cnt1 + 3'd1;
end
end
always@(posedge clk or negedge rst)
begin
if(!rst)
cnt2 <= 3'd0;
else begin
if(cnt1 == MAX_COUNT-1) begin
case(flag)
2'b11: cnt2 <= 3'd1;
2'b10: cnt2 <= 3'd2;
2'b01: cnt2 <= 3'd3;
2'b00: cnt2 <= 3'd4;
default: cnt2 <= 3'd1;
endcase
end
else
cnt2 <= cnt2;
end
end
assign pwm_signal = (cnt1 < cnt2)?1'b0:1'b1;
endmodule
【TestBench】
`timescale 1ns/1ns
module tb_pwm2();
reg clk;
reg rst;
reg [1:0] flag;
wire [2:0] cnt1;
wire [2:0] cnt2;
parameter T = 20;
initial begin
clk = 1'b0;
rst = 1'b0;
#(T/2) rst = 1'b1;
flag = 2'b00;
#(4*T) flag = 2'b01;
#(4*T) flag = 2'b11;
#(4*T) flag = 2'b00;
#(4*T) flag = 2'b00;
#(4*T) flag = 2'b01;
#(4*T) flag = 2'b10;
#(4*T) flag = 2'b11;
#(4*T) flag = 2'b01;
#(4*T) flag = 2'b00;
#(4*T) flag = 2'b11;
#(4*T) flag = 2'b00;
#(4*T) flag = 2'b10;
#(4*T) flag = 2'b11;
#(4*T) flag = 2'b01;
#(4*T) flag = 2'b00;
#(4*T) flag = 2'b11;
#(4*T) flag = 2'b01;
#(4*T) flag = 2'b00;
#(4*T) flag = 2'b11;
end
always#(T/2) clk = ~clk;
PWM2 u0(
.clk(clk),
.rst(rst),
.flag(flag),
.pwm_signal(pwm_signal),
.cnt1(cnt1),
.cnt2(cnt2));
endmodule