EP2C5T144+ESP-32(8)任意波形出力+周波数可変


前回、FIFOにインクリメンタルパターンを書き込んでR-2R DACから出力しました。FPGA SPI Bridge Console for Avalon BusにCos+Sinパターンを追加したのでサイン波形を出力してみます。FIFOに書き込むパターンを変更すれば任意波形を出力できます。ついでに出力波形の周波数を変える仕組みも追加します。

波形をループさせるFIFOの入出力はAvalon-STなので、そのValidとReadyをNクロック中1回だけ1にするようにして、FIFOの動作をN分の1に遅くします。さらにFIFOに書き込む波形の長さを変更することでより細かく出力波形の周波数を調整できます。

前回までに作ったFIFO Controllerコンポーネントに、N分の1のNを設定するために入力loop_divと、FIFOのループ動作を許可・禁止するloop_enを追加します。div_counterが0のときだけFIFOが動作します。

// fifo_controller.v

// This file was auto-generated as a prototype implementation of a module
// created in component editor.  It ties off all outputs to ground and
// ignores all inputs.  It needs to be edited to make it do something
// useful.
// 
// This file will not be automatically regenerated.  You should check it in
// to your version control system if you want to keep it.

`timescale 1 ps / 1 ps
module fifo_controller #(
		parameter AUTO_CLK_CLOCK_RATE = "-1"
	) (
		input  wire        clk,            //         clk.clk
		input  wire        rst,            //         rst.reset
		input  wire [31:0] fifo_in_data,   //     fifo_in.data
		input  wire        fifo_in_valid,  //            .valid
		output wire        fifo_in_ready,  //            .ready
		output wire [31:0] fifo_out_data,  //    fifo_out.data
		output wire        fifo_out_valid, //            .valid
		input  wire        fifo_out_ready, //            .ready
		input  wire [31:0] loop_in_data,   //     loop_in.data
		input  wire        loop_in_valid,  //            .valid
		output wire        loop_in_ready,  //            .ready
		output wire [31:0] loop_out_data,  //    loop_out.data
		output wire        loop_out_valid, //            .valid
		input  wire        loop_out_ready, //            .ready
		input  wire        fifo_in_en,     //  fifo_in_en.export
		input  wire        fifo_out_en,    // fifo_out_en.export
		output wire [31:0] monitor_out,    // monitor_out.export
		input  wire        loop_en,        //     loop_en.export
		input  wire [15:0] loop_div        //    loop_div.export
	);

	reg [15:0] div_counter;
	wire loop_div_en;
	
	always@(posedge clk or posedge rst)
	begin
		if (rst)
			div_counter <= 16'h0000;
		else
		begin
			if (div_counter == 16'h0000)
				div_counter <= loop_div;
			else
				div_counter <= div_counter - 1;
		end
	end
	
	assign fifo_in_ready = fifo_in_en == 1'b1 ? loop_out_ready : 1'b1;
	assign fifo_out_valid = fifo_out_en == 1'b1 ? loop_in_valid : 1'b1;
	assign fifo_out_data = fifo_out_en == 1'b1 ? loop_in_data : 32'h00000000;
	
	assign loop_in_ready = fifo_out_en == 1'b1 ? fifo_out_ready : loop_div_en;
	assign loop_out_valid = fifo_in_en == 1'b1 ? fifo_in_valid : loop_div_en;
	assign loop_out_data = fifo_in_en == 1'b1 ? fifo_in_data : loop_in_data;
	
	assign monitor_out = loop_out_data;
	
	assign loop_div_en = div_counter == 16'h0000 ? loop_en : 1'b0;

endmodule

QsysにもN分の1のNを設定するためにPIOコンポーネントを追加します。

Top-levelのVerilogでPIOコンポーネントとFIFO Controllerコンポーネントに繋ぎます。

module ledtest (
	RST_N,
	CLK,
	
	SPI_NSS,
	SPI_SCLK,
	SPI_MISO,
	SPI_MOSI,
	
	LED2,
	LED4,
	LED5,
	
	DAC
);

input CLK, RST_N;
input SPI_NSS, SPI_SCLK, SPI_MOSI;
output SPI_MISO;
output LED2, LED4, LED5;
output [11:0] DAC;
wire [2:0] leds_sig;
wire [31:0] monitor_out;
wire [31:0] loop_div;

spi_master u0 (
	.clk_clk                                                                                         (CLK),
	.reset_reset_n                                                                                   (RST_N),
	.spi_slave_to_avalon_mm_master_bridge_0_export_0_mosi_to_the_spislave_inst_for_spichain          (SPI_MOSI),
	.spi_slave_to_avalon_mm_master_bridge_0_export_0_nss_to_the_spislave_inst_for_spichain           (SPI_NSS),
	.spi_slave_to_avalon_mm_master_bridge_0_export_0_miso_to_and_from_the_spislave_inst_for_spichain (SPI_MISO),
	.spi_slave_to_avalon_mm_master_bridge_0_export_0_sclk_to_the_spislave_inst_for_spichain          (SPI_SCLK),
	.pio_0_external_connection_export                                                                (leds_sig),
   .fifo_controller_0_monitor_out_export                                                            (monitor_out),
   .fifo_controller_0_fifo_in_en_export                                                             (leds_sig[0]),
   .fifo_controller_0_fifo_out_en_export                                                            (leds_sig[1]),
   .fifo_controller_0_loop_en_export                                                                (leds_sig[2]),
   .fifo_controller_0_loop_div_export                                                               (loop_div[15:0]),
   .pio_1_external_connection_export                                                                (loop_div)
);

assign LED2 = ! leds_sig[0];
assign LED4 = ! leds_sig[1];
assign LED5 = ! leds_sig[2];

assign DAC = monitor_out[15:4];

endmodule

FPGA SPI Bridge Console for Avalon Busを使ってFIFOからサイン波形を出力します。

  • アドレス0に5(loop_en=1、fifo_out_en=0、fifo_in_en=1)を書いて、FIFOを空にします。
  • アドレス0に1(loop_en=0、fifo_out_en=0、fifo_in_en=1)を書いて、FIFO書き込みモードにします。
  • アドレス10000に1000ワードのCos=Sinパターンを書き込みます。
  • アドレス0に4(loop_en=1、fifo_out_en=0、fifo_in_en=0)を書いて、FIFOをループモードにします。

クロック50MHzで1周期1000ワードなので、50KHzのサイン波形が出力されます。

FPGA SPI Bridge Console for Avalon Busを使ってサイン波形の周波数を変更します。

  • 10分の1の5kHzにするに、アドレス10に9(10-1)を書きます。
  • 100分の1の500Hzにするに、アドレス10に99(100-1)を書きます。
  • 1000分の1の50Hzにするに、アドレス10に999(1000-1)を書きます。