FPGA SDR(15)EP2C5T144 AMラジオ


2018/07/07 追記:自作FIRフィルタ自作ATAN2が完成したのでEP2C5T144 AM/FMラジオを作りました。FET一段の高周波増幅回路を追加したのでノイズも小さくなっています。

 

自作CICフィルタ自作NCOができたので、EP2C5T144でもラジオを作ることができます。ところがQuartus II Web Edition 13.0sp1 MegaWizardにALTERA CORDICが見つかりません。FM復調のためのAtan2が使えません。諦めてAM専用ラジオにしました。

DAC以降のアナログ回路で高域を大分落とす必要があります。早く自作FIRフィルタを完成させたいです。評価版IPを使っていないのでダウンロードケーブルを外せます。するとかなりノイズが減ります。

`define CYCLE_1SEC 50000000


module SPIbridge
(
	input wire RST_N,
	input wire CLK,
	
	input wire SPI_NSS,
	input wire SPI_SCLK,
	output wire SPI_MISO,
	input wire SPI_MOSI,
	
	output wire [2:0] LED,
	
	input wire [7:0] ADC,
	output wire ENCODE,
	
	output reg [9:0] DAC,
	output wire DACCLK
);


	localparam CIC_WIDTH = 17;	


	wire clk;

	wire [31:0] pio0;
	wire [31:0] pio1;

	reg [9:0] uadc_r;
	wire signed [9:0] adc;

	wire signed [9:0] sin;
	wire signed [9:0] cos;

	wire signed [19:0] i;
	wire signed [19:0] q;

	wire signed [CIC_WIDTH-1:0] icic;
	wire icic_valid;
	wire signed [CIC_WIDTH-1:0] qcic;
	wire qcic_valid;

	wire signed [33:0] i2q2;
	wire signed [15:0] mag;

	wire [9:0] dac;
	reg [2:0] dacclk;


	pll pll_inst (
		.inclk0 (CLK),
		.c0 (clk)
	);	

	QsysCore QsysCore_inst (
		.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                                                                (pio0),
		.pio_1_external_connection_export                                                                (pio1)
	);

	assign LED = ~pio0[2:0];
	
	always @(posedge clk) begin
		uadc_r <= { ADC, 2'b00 };
	end
	assign ENCODE = clk;
	assign adc = (uadc_r[9] == 0) ? uadc_r + 10'h200 : uadc_r - 10'h200;

	MyNCO nco_inst (
		.clk       (clk),
		.reset_n   (RST_N),
		.clken     (1'b1),
		.phi_inc_i (pio1),
		.fsin_o    (sin),
		.fcos_o    (cos),
		.out_valid ()
		);

	altmul altmul_inst_i (
		.aclr0 (1'b0),
		.clock0 (clk),
		.dataa_0 (adc),
		.datab_0 (cos),
		.result (i)
		);

	altmul altmul_inst_q (
		.aclr0 (1'b0),
		.clock0 (clk),
		.dataa_0 (adc),
		.datab_0 (sin),
		.result (q)
		);

	MyCIC cic_inst_i (
		.clk       (clk),
		.reset_n   (RST_N),
		.rate      (2048),
		.in_error  (2'b00),
		.in_valid  (1'b1),
		.in_ready  (),
		.in_data   (i),
		.out_data  (icic),
		.out_error (),
		.out_valid (icic_valid),
		.out_ready (1'b1)
	);

	MyCIC cic_inst_q (
		.clk       (clk),
		.reset_n   (RST_N),
		.rate      (2048),
		.in_error  (2'b00),
		.in_valid  (1'b1),
		.in_ready  (),
		.in_data   (q),
		.out_data  (qcic),
		.out_error (),
		.out_valid (qcic_valid),
		.out_ready (1'b1)
	);
 
	altmultadd altmultadd_inst (
		.clock0 (clk),
		.dataa_0 (icic),
		.dataa_1 (qcic),
		.datab_0 (icic),
		.datab_1 (qcic),
		.ena0 (icic_valid),
		.result (i2q2)
	);
	
	sqrt	sqrt_inst (
		.radical (i2q2[33 -: 32]),
		.q (mag),
		.remainder ()
	);	

	assign dac = (pio1 == 0) ? 0 : mag[9:0];
	always @(posedge clk) begin
		if (icic_valid) begin
			DAC <= (dac[9] == 0) ? dac + 10'h200 : dac - 10'h200;
		end
		
		dacclk = { dacclk[1:0], icic_valid };
	end
	assign DACCLK = dacclk[2] | dacclk[1] | dacclk[0] | icic_valid;


endmodule

使用するリソースはこんな感じで、FIRフィルタも入れられそうです。