検索
連載

マイコンに搭載されているセンターアラインPWMって何?Q&Aで学ぶマイコン講座(87)(6/6 ページ)

マイコンユーザーのさまざまな疑問に対し、マイコンメーカーのエンジニアがお答えしていく本連載。今回は、中級者の方からよく質問される「マイコンに搭載されているセンターアラインPWMって何?」についてです。

Share
Tweet
LINE
Hatena
前のページへ |       

付録〜シミュレーションで使用したコード〜

 シミュレーションで使用したコードを参考に掲載します。

エッジアラインPWMコントローラーのverilogコード

// Code your design here
module edge_aligned_pwm
	#(parameter BITS = 8)
	(
		input clk,
		input rst,
		input [BITS -1 : 0] period,
		input [BITS -1 : 0] compare,
		output [BITS -1 : 0] count,
		output pwm_out
	);
	
	//state registers
	reg	pwm_ff;
	reg [BITS -1 : 0] count_reg;
	assign pwm_next = (count_reg <= compare);
	always @(posedge clk or posedge rst)
		begin
			if(rst) begin
				pwm_ff <= 0;
				count_reg <= 0;
			end else begin
				if(count_reg < period) begin
					count_reg <= count_reg + 1;
                  end else begin
					count_reg <= 0;
				end
              pwm_ff <= pwm_next;
			end
		end
	
	// output	
	assign pwm_out = pwm_ff;
	assign count = count_reg;
		
endmodule
edge_aligned_pwm.sv
// Code your testbench here
// or browse Examples
module test;
	parameter BITS = 8;
	reg clk,rst;
	reg [BITS-1:0] period;
	reg [BITS-1:0] compare;
	wire pwm_out;
	wire [BITS-1:0] count;
	// Initiatiate pwm module
	edge_aligned_pwm pwm1(.clk(clk),
		.rst(rst),
		.period(period),
		.compare(compare),
		.pwm_out(pwm_out),
                          .count(count));
	initial begin
	// Dump waveform
	$dumpfile("dump.vcd");
	$dumpvars(1, test);
	
	clk = 0;
	rst = 1;
	#1
	rst = 0;
	#1
	period =5;
	compare =3;
      repeat(40) begin
		#1 clk = ~clk;
	end
	$finish;
    end
endmodule
testbench_edge_aligned_pwm.sv

センターアラインPWMコントローラーのverilogコード

module center_aligned_pwm
	#(parameter BITS = 8)
	(
		input clk,
		input rst,
		input [BITS -1 : 0] period,
		input [BITS -1 : 0] compare,
		output [BITS -1 : 0] count,
		output pwm_out,
      	output dir
	);
	
	//state registers
	reg	pwm_ff;
	reg dir_ff;
	reg [BITS -1 : 0] count_reg;
	assign pwm_next = (count_reg <= compare);
	assign count_inc = count_reg + 1;
	assign count_dec = count_reg - 1;
	
	always @(posedge clk or posedge rst)
		begin
			if(rst) begin
				pwm_ff <= 0;
				count_reg <= 0;
				dir_ff <= 0;
			end else begin
				if((count_reg == period) && (dir_ff == 0)) begin
					dir_ff <= 1;
					count_reg <= count_reg - 1;
                end else if ((count_reg == 0) && (dir_ff == 1)) begin
					dir_ff <= 0;
					count_reg <= count_reg + 1;
				end else if ((count_reg < period) && (dir_ff==0)) begin
					count_reg <= count_reg + 1;
				end else if ((count_reg > 0) && (dir_ff==1)) begin
					count_reg <= count_reg - 1;
				end
				pwm_ff <= pwm_next;
			end
		end
	
	// output	
	assign pwm_out = pwm_ff;
	assign count = count_reg;
	assign dir =dir_ff;
endmodule
center_aligned_pwm.sv
module test;
	parameter BITS = 8;
	reg clk,rst;
	reg [BITS-1:0] period;
	reg [BITS-1:0] compare;
	wire pwm_out;
	wire [BITS-1:0] count;
	wire dir;
	// Initiatiate pwm module
	center_aligned_pwm pwm1(.clk(clk),
		.rst(rst),
		.period(period),
		.compare(compare),
		.pwm_out(pwm_out),
		.count(count),
		.dir(dir));
	initial begin
	// Dump waveform
	$dumpfile("dump.vcd");
	$dumpvars(1, test);
	
	clk = 0;
	rst = 1;
	#1
	rst = 0;
	#1
	period =5;
	compare =3;
	repeat(40) begin
		#1 clk = ~clk;
	end
	$finish;
    end
endmodule
testbench_center_aligned_pwm.sv

⇒次の記事を読む

Q&Aで学ぶマイコン講座:過去の質問一覧はこちら

Copyright © ITmedia, Inc. All Rights Reserved.

前のページへ |       
ページトップに戻る