verilog PWM moduleの作成、IP化 Quartus

初めに

みなさんこんにちは、Keymaleです。なかなか書く気が起きず、放置していたのですが、AWSのサーバー代がもったいないので書こうと思います。

VerilogでPWMを生成

今回はverilogでPWMのコードを書きたいと思います。
早速ですが以下にソースコードを載せます。

 

module pwm_module #(
parameter period_cnt = 8,
parameter high_cnt = 3
)(
input clk,
input reset,
output reg out = 0
);

reg[15:0]cnt;
initial begin
cnt = 16'd0;
out = 0;
end
always@(posedge clk)begin
if(reset)begin
out <= 0;
cnt <= 15'd0;
end else begin
cnt <= cnt + 8'd1;
if(cnt == period_cnt-1)begin
cnt <= 15'd0;
end else if(cnt < high_cnt)begin
out <= 1'b1;
end else begin
out <= 0;
end
end
end
endmodule

こんな感じですね。入力のclkをカウントして、PWMのピリオドとHighの時間をパラメータで設定できるようにしています。今回はclkに50MHzを入れます。50MHzは1周期20nsecです。ピリオドを8カウントにすると、1周期が20×8=160nsecのPWMとなります。Highのカウントを3にすると20×3=60nsecがHighの時間となり、100nsecがLowの時間となります。

ModelSimで波形を確認

上記で作成したmoduleをModelSimで確認してみます。

ピリオドが8カウント分、Highの時間が3カウント分になっていますね。

実際にこんなに早いPWMを使うことはないと思います。例えば10kHzのPWMを作りたい場合はピリオドカウントを50M÷10k=5000とします。Duty比が50%の時はHighのカウントを2500としてください。

以上がverilogでのPWM生成となります。最後まで見てくださってあります。