前言
本章主要跟大家介绍如何生成音频数据,我们借助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)
三、输出图示

594

被折叠的 条评论
为什么被折叠?



