国产荔枝糖FPGA开发板实现FM发射

之前在ZEDBOARD上实现了FM发射,移植到荔枝糖FPGA开发板上,运行异常,抓波形看,波形紊乱,由于最高时钟为450M,估计是荔枝糖FPGA开发板跑不了这么高,那就降频吧,降到18M果然可以发射了
top代码如下:

module top(
    output [2 : 0] rgb_led_o,
    input clk24mhz,
    input reset,
    output fm_tx
 );

wire ireset;
wire lock;
wire clk90MHz;
wire iclk20MHz;
wire [15:0] in_factor;
wire [7:0] addr;

reg clk_audio;
reg [11:0] cnt;
reg [14:0] music_cnt; 

always @(posedge iclk20MHz)
begin
if (!reset)
    begin
        cnt <= 0;
        clk_audio <= 0;
    end
else
    begin
        if (cnt == 453)//22.1KHz sample rate
            begin
                clk_audio <= !clk_audio;
                cnt <= 0;
            end
        else
            cnt <= cnt + 1;
    end
end

always @(posedge clk_audio)
begin
if (!reset)
    begin
        music_cnt <= 0;
    end
else
    music_cnt <= music_cnt + 1;
end

clk u1(
    .refclk(clk24mhz), 
    .reset(ireset),
    .stdby(),
    .extlock(lock),
    .clk0_out(iclk20MHz),
    .clk1_out(clk90MHz)
 );

divider u2(
    .clk_in(clk90MHz),
    .nreset(reset),
    .in_factor(in_factor), 
    .nclk(fm_tx)
);

music u3(
    .doa(addr),
    .addra(music_cnt),
    .clka(clk_audio),
    .rsta(ireset)
);

blk_mem u4(
    .doa(in_factor),
    .addra(addr),
    .clka(iclk20MHz),
    .rsta(ireset)   
);

assign ireset = !reset;
assign rgb_led_o[0] = !lock;
assign rgb_led_o[1] = 1;
assign rgb_led_o[2] = 1;
endmodule

divider代码如下:


module divider(
    input wire clk_in,
    input wire nreset,
    input wire [15:0]in_factor,
    output wire nclk
);

reg r0, r1, r2, r3, r4;

reg [15:0]factor=0;
reg [15:0]fcnt;
reg short;
reg short_f;

always @(posedge clk_in or negedge nreset)
begin
    if(~nreset)
        begin
            r0 <= 0;
            r1 <= 0;
            r2 <= 0;
            r3 <= 0;
            r4 <= 1;
        end
    else
        begin
            r0 <= r1;
            r1 <= r2;
            r2 <= r3;
            if(short)
                r3 <= r0;
            else
                r3 <= r4;
            if(~short)
                r4 <= r0;
        end
end

assign nclk = r0;

always @(posedge clk_in or negedge nreset)
    if(~nreset)
    begin
        fcnt <= 0;
        short <= 0;
        short_f <= 0;
    end
    else
    begin
        if(r0)
            fcnt <= short ? 0 : fcnt +1;
        if(r2)
            short <= (fcnt == factor);

        if(r0)
            short_f <= short;

        if(r0 & short_f)
            factor <= in_factor;
    end

endmodule

u4的fm_tx_rom初始化mif文件生成matlab代码如下:

clear all;
close all;
clc;

BASE_FREQ = 90000000;
CARRIER = 18000000;
BAND = 50000;

fid_s = fopen('fm_tx_rom.mif', 'wt');
fprintf(fid_s, '%s\n', 'DEPTH=256;');
fprintf(fid_s, '%s\n', 'WIDTH=16;');
fprintf(fid_s, '%s\n', 'ADDRESS_RADIX=UNS;');%UNS表示为十进制
fprintf(fid_s, '%s\n', 'DATA_RADIX=UNS;');
fprintf(fid_s, '%s\n', 'CONTENT BEGIN');

for (i=1:256)
    freq_wish = CARRIER + BAND*(i-1)/256;
    divider = BASE_FREQ / freq_wish;
    m=(divider-4)/(5-divider); 
    fprintf(fid_s, '%03d', i-1);
    fprintf(fid_s, '%s', ' : ');
    fprintf(fid_s, '%d', round(m));
    fprintf(fid_s, '%s\n', ';');
end
fclose(fid_s);
disp('===================转换完成=========================');

测试音频rom文件初始化mif文件生成matlab代码如下:

fs = 44100/2; %采样频率
T = 1/fs; %采样周期
time1 = 0.7; %第一个声音片段的总时长
time2 = 0.1;
time3 = 0.686;
freq1 = 261; %第一个声音片段的频率(音调)
freq2 = 0;
freq3 = 1000;
vol1 = 127; %第一个声音片段的音量
vol2 = 0;
vol3 = 100;

tone1 = 128+sin(2*pi*freq1*(0:T:time1))*(vol1); %生成第一个声音片段,注意需要用db2mag()函数把dB转换成magnitude。
tone2 = sin(2*pi*freq2*(0:T:time2))*(db2mag(vol2));
tone3 = 128+sin(2*pi*freq3*(0:T:time3))*(vol3);
Tone = [round(tone1), round(tone2), round(tone3)]; %组合所有声音片段
sound(Tone,fs) %可以播放声音的函数 sound()

fid_s = fopen('music_rom.mif', 'wt');
fprintf(fid_s, '%s\n', 'DEPTH=32768;');
fprintf(fid_s, '%s\n', 'WIDTH=8;');
fprintf(fid_s, '%s\n', 'ADDRESS_RADIX=UNS;');%UNS表示为十进制
fprintf(fid_s, '%s\n', 'DATA_RADIX=UNS;');
fprintf(fid_s, '%s\n', 'CONTENT BEGIN');

for (i=1:32768)
    fprintf(fid_s, '%05d', i-1);
    fprintf(fid_s, '%s', ' : ');
    fprintf(fid_s, '%d', Tone(i));
    fprintf(fid_s, '%s\n', ';');
end

你可能感兴趣的:(FPGA)