DDS作业(作业3)

  • 手绘RTL图
    DDS作业(作业3)_第1张图片
  • 系统生成的RTL图
    DDS作业(作业3)_第2张图片
    DDS作业(作业3)_第3张图片
    DDS作业(作业3)_第4张图片
    最后一张RTL的图片因为有32位的输入,图片比较大,只截取了一部分。
  • SignalTap抓取的波形
    这里写图片描述
    500KHz波形
    这里写图片描述
    1MHz波形
    这里写图片描述
    3MHz波形
    基本原理:一个周期内有1024 个采样点,基本的时钟周期为50MHz;为使输出的波形频率发生变化,可以改变输出的间隔即每隔K个点输出一个采样数据,此时输出的波形频率与K之间的关系为:

    =K1024

    当输出的频率为500KHz时,计算的K≈10,以此为基准1MHz的输出K=20,3MHz的输出,K=60。

  • 代码块
    VerilogHDL代码

module addr_cnt(
    CLK,         //时钟
    sw_fq,       //频率选择控制
    Address,     //输出间隔
    ROMadd);     //ROM表地址
input CLK;
input [1 : 0] sw_fq;
output reg [31 : 0] Address;
output reg [9 : 0] ROMadd;
reg [5 :0] K;       //最大为60,五位二进制数的最大表示为63.
always @ (posedge CLK)
begin 
    case(sw_fq)
    2'd00 : Address <= 10;   //输出500KHz
    2'd01 : Address <= 20;   //输出1MHz
    2'd10 : Address <= 60;   //输出3MHz
    default Address <= 10;
    endcase
end
always @ (posedge CLK)
begin 
    ROMadd <= Address + ROMadd;   //ROM表步进间隔输出
end
endmodule

生成ROM表的MatLab程序是使用杜大大的程序:

function generate_DDS_rom()
clc;
close all;
disp('# generate_DDS_rom() Running~');

%%///////////////////////////////////////////////////
%   set your rom config here
rom_word_len = 12;  % rom data word length in bit
rom_addr_len = 10;  % rom address word length in bit
rom_file_name = 'DDS_CORE_ROM.v';  % rom file name
rom_file_dir  = './';  % rom file dir path
description   = 'DDS CORE ROM FILE' ;% rom description
%%///////////////////////////////////////////////////

rom_vec_len = 2^rom_addr_len;   %2^10=1024
index = (0:rom_vec_len-1) ;     %0~1023
rom_data_vec_float = sin(2*pi*index/rom_vec_len);   %最大值为11024点正弦波
figure; plot(rom_data_vec_float);    % for debug
rom_data_vec_int = fix(rom_data_vec_float * (2^(rom_word_len-1) - 1));  %最大值为2047,为了保证最高位为符号位
figure; plot(rom_data_vec_int);      % for debug

rom_cfg.rom_word_len  = rom_word_len   ;
rom_cfg.rom_file_name = rom_file_name  ;
rom_cfg.rom_file_dir  = rom_file_dir   ;
rom_cfg.description   = description    ;
gen_rom_rtl(rom_cfg, rom_data_vec_int);


end % generate_DDS_rom()

% ///////////////////////////////////////////////////////////////////////////////
% gen_rom_rtl()
%   generate synthesizable rom  hdl code(need synthesizer support).
% ///////////////////////////////////////////////////////////////////////////////
% INPUT: 
%   data vector, must be integer value
%   rom word len
%   rom file dir string
%   rom file name string
% OUTPUT:
%   verilog format rom file, all data in 2's complement code format
function gen_rom_rtl(rom_cfg, data_vec)

  rom_word_len   = rom_cfg.rom_word_len  ;
  rom_file_name  = rom_cfg.rom_file_name ;
  rom_file_dir   = rom_cfg.rom_file_dir  ;

  description    = rom_cfg.description   ;
  data_vec_len = length(data_vec);
  addr_word_len  = ceil(log2(data_vec_len));

  % check input be integer value
  data_vec_fixed = fix(data_vec);
  diff_sum = sum(data_vec == data_vec_fixed);
  % all integer elements will cause the diff_sum be vector length 
  if(diff_sum < data_vec_len)
    fprintf(1,'# ERROR, gen_rom_rtl(), input data_vec must be integer value\n');
    return;
  end


  rom_file_dir_name = strcat(rom_file_dir, rom_file_name);

  data_vec_fixed_2c =  data_vec_fixed + (2^rom_word_len) .* (data_vec_fixed < 0);


  romNum        = 2^addr_word_len;
  data_str_cell  = cell(data_vec_len, 1);

  for idx = 1:data_vec_len 
   data_str_cell{idx} = Dec2BinStr(data_vec_fixed_2c(idx), rom_word_len);
  end % for(idx = 1:data_vec_len)

  if(romNum > data_vec_len)
    for idx = data_vec_len+1:romNum 
     data_str_cell{idx} = Dec2BinStr(0, rom_word_len); 
   end
  end

  fid_rom_file = fopen(rom_file_dir_name, 'w');
  if(fid_rom_file == -1)
    errMsg = strcat('ERROR, gen_rom_rtl(), create file',rom_file_dir_name, ',failed');
    fprintf(1, '%s\n', errMsg);
    return;
  end

  % rom data print 
  % get rom module name
  rom_name = rom_file_name;
  len_rom_file_name = length(rom_file_name);
  if(strcmp(rom_name(len_rom_file_name-1:len_rom_file_name), '.v'))
    rom_name(len_rom_file_name-1:len_rom_file_name) = [];
  else
    fprintf(1,'#WARNINIG, gen_rom_rtl(), rom_file_name may error, check it!\n');
  end
  fprintf(fid_rom_file,  ...
  '// ************************************************************** //\n');
  fprintf(fid_rom_file,  ...
  '// FILE    : %s \n', rom_file_name);
  fprintf(fid_rom_file,  ...
  '// DSCP    : %s\n', description);
  fprintf(fid_rom_file,  ...
  '// ABOUT   : auto generated rom file by gen_rom_rtl.m\n');
  fprintf(fid_rom_file,  ...
  '// DATE    : %s \n',  datestr(now));
  fprintf(fid_rom_file,  ...
  '// ************************************************************** //\n');
  % generate the crom module
  fprintf(fid_rom_file, ...
  '// module %s()\n', rom_name);
  fprintf(fid_rom_file, ...
  'module %s(\n', rom_name);
  fprintf(fid_rom_file, ...
  '  CLK    ,           // clock\n');
  fprintf(fid_rom_file, ...
  '  RA     ,           // read address\n');
  fprintf(fid_rom_file, ...
  '  RD     );          // read data\n');

  fprintf(fid_rom_file, ...
  'input          CLK;\n');
  fprintf(fid_rom_file, ...
  'input  [%-2d :0] RA;\n', addr_word_len-1); 
  fprintf(fid_rom_file, ...
  'output [%-2d :0] RD;\n', rom_word_len-1);
  fprintf(fid_rom_file, ...
  'reg    [%-2d :0] RD;\n', rom_word_len-1);

  fprintf(fid_rom_file, ...
  'always @ (posedge CLK)\n'); 
  fprintf(fid_rom_file, ...
  '  case(RA)\n');

  for addr = 0:1:data_vec_len-1
    fprintf(fid_rom_file, ... 
  '     %-2d''d %-6d:RD = #1 %-2d''b %s; ', ...
      addr_word_len,addr, rom_word_len, data_str_cell{addr+1});
    fprintf(fid_rom_file, ... 
  '// %6d 0x%s \n', ...
      data_vec_fixed(addr+1), dec2hex(data_vec_fixed_2c(addr+1)));

  end
  fprintf(fid_rom_file, ...
  '  default : RD = #1 0;\n');
  fprintf(fid_rom_file, ...
  '  endcase\n');

  fprintf(fid_rom_file, ...
  'endmodule \n');
  fclose(fid_rom_file);
  fprintf(1,'# File: %s written\n', rom_file_dir_name);

end % function gen_rom_rtl() 
% ///////////////////////////////////////////////////////////
function str = Dec2BinStr(data, word_len)
  str = '';
  for idx = word_len-1:-1:0 
    bit_val = bitand(1, bitshift(data, -idx));
    str = strcat(str, int2str(bit_val));
  end
end % function Dec2BinStr()
  • DDS输出的图像的频域分析
    DDS作业(作业3)_第5张图片
    500k波形时域图
    DDS作业(作业3)_第6张图片
    500k波形的频域分析
    DDS作业(作业3)_第7张图片
    1M波形的时域图
    DDS作业(作业3)_第8张图片
    1M波形的频域分析
    DDS作业(作业3)_第9张图片
    3M波形的时域图
    DDS作业(作业3)_第10张图片
    3M波形的频域图

用分析500k波形的MATLAB代码作为示例:

signal = transpose(VarName6) / 2048; %数据归一化处理
CLK = 50 * 1000000;
N = 512;
t=[0:1/CLK:(N-1)/CLK]; %持续时间
figure(1);plot(t,signal);
xlabel('时间(s)');ylabel('value');
title('时域图');%绘制时域图形
Y = fft(signal,N); %FFT变换
size = abs(Y); %取size=size/(N/2); %换算成实际的幅度
figure(2);
stem(F(1:N/2),size(1:N/2)); %fft频域图
axis([0 5E6 0 1.5]);
title('频谱图');
xlabel('频率(Hz)');ylabel('幅度');

将signal tap中的数据导入到MATLAB中分析的注意事项:
- 导出signal tap 中的数据有TXT和CSV两种文本格式,但是CSV的数据格式是带符号的二进制数据,用MATLAB分析需要先将其转换为十进制在分析。这个过程较为麻烦,TXT文本的数据是十进制可以用MATLAB的import data直接导入。
- 用TXT导入数据时,数据会被截断需要合并。
- 导入的数据要注意是文本格式还是Number。

你可能感兴趣的:(软件学习)