基于Matlab和verilog实现任意频率DDS输出功能


前言

本章主要跟大家介绍如何生成音频数据,我们借助Matlab生成一段音频,再通过verilog实现输出;这里的DDS主要就是正弦波,余弦波就是正弦波偏移90°的相位。

一、Matlab实现任意频率dds波形输出

% 采样频率
fs = 48000; 
% 信号时长
t = 0:1/fs:1; 
% 信号频率
f = 2000; 
% 生成正弦波
y = sin(2*pi*f*t); 

% 将正弦波信号量化为 16 位有符号整数
y_quantized = int16(y * (2^15 - 1));

% MIF 文件路径
mif_file = 'sine_wave.mif';

% 打开 MIF 文件进行写入
fid = fopen(mif_file, 'w');

% 写入 MIF 文件头部信息
fprintf(fid, 'DEPTH = %d;\n', length(y_quantized));
fprintf(fid, 'WIDTH = 16;\n');
fprintf(fid, 'ADDRESS_RADIX = DEC;\n');
fprintf(fid, 'DATA_RADIX = DEC;\n');
fprintf(fid, 'CONTENT BEGIN\n');

% 写入数据
for i = 1:length(y_quantized)
    fprintf(fid, '%d : %d;\n', i-1, y_quantized(i));
end

% 写入 MIF 文件尾部信息
fprintf(fid, 'END;\n');

% 关闭文件
fclose(fid);

% 绘制正弦波
plot(t, y);
xlabel('时间 (s)');
ylabel('幅度');
title('2kHz 正弦波');    

二、verilog实现

在上一篇中,我们用Matlab生成了sine_wave.mif文件,在verilog中,我们可以使用ROM或者RAM去读取调用,代码如下:

module sine_dds #
(
   parameter    DWID           = 24
)
(
   input                       clk ,
   input                       reset,
   input        [23:0]         fcw,
   
   input                       dds_din,
   output reg                  dds_ena,
   output signed[DWID-1:0]     dds_sin
);
reg signed [DWID-1:0] rom_memory [1023:0];

initial begin
   $readmemh("sine_wave.mif", rom_memory);
end

reg   [23:0]   accu = 0;
wire  [9:0]    lut_index;

//process for phase accumulator
always@(posedge clk)
begin
   if(reset == 1'b1)         
      accu <= 0; //synchronous reset
   else if(dds_din == 1'b1)
      accu <= accu + fcw;
end

//10 msb's of the phase accumulator are used to index the sinewave lookup-table
assign lut_index = accu[23:14];

//sine value from lookup table
assign dds_sin = rom_memory[lut_index][DWID-1-:DWID];

always @ ( posedge clk )
begin
   dds_ena <= dds_din ;
end



endmodule

其中fcw为频率调节字,其公式如下: fcw == 2^(音频有效bit,这里为16bit) * f(正弦波信号频率,单位khz)/音频采样频率(这里是48,单位khz)

三、输出图示

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值