使用matlab生成含正弦波表数据ROM

写在前面

本篇是对DDS和ADDA实验的补充,就不完全公开了


一、matlab程序

例:使用matlab的DDS ROM生成代码,生成7位输入,16位输出的rom

function generate_DDS_rom()
clc;
close all;
disp('##########################################');
disp('# generate_DDS_rom() RUN');
disp('##########################################');

%%///
%   set your rom config here
rom_word_len = 16;  % rom data word length in bit
rom_addr_len = 7;  % 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;
index = [0:rom_vec_len-1] .';
rom_data_vec_float = sin(2*pi*index/rom_vec_len);
figure; plot(rom_data_vec_float);    % for debug
rom_data_vec_int = fix(rom_data_vec_float * (2^(rom_word_len-1) - 1));
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(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()

其生成的Verilog为:

// ************************************************************** //
// FILE    : DDS_CORE_ROM.v 
// DSCP    : DDS CORE ROM FILE
// ABOUT   : auto generated rom file by gen_rom_rtl.m
// DATE    : 23-Jul-2021 14:15:54 
// ************************************************************** //
// module DDS_CORE_ROM()
module DDS_CORE_ROM(
  CLK    ,           // clock
  RA     ,           // read address
  RD     );          // read data
input          CLK;
input  [6  :0] RA;
output [15 :0] RD;
reg    [15 :0] RD;
always @ (posedge CLK)
  case(RA)
     7 'd 0     :RD = #1 16'b 0000000000000000; //      0 0x0 
     7 'd 1     :RD = #1 16'b 0000011001000111; //   1607 0x647 
     7 'd 2     :RD = #1 16'b 0000110010001011; //   3211 0xC8B 
     7 'd 3     :RD = #1 16'b 0001001011000111; //   4807 0x12C7 
     7 'd 4     :RD = #1 16'b 0001100011111000; //   6392 0x18F8 
     7 'd 5     :RD = #1 16'b 0001111100011001; //   7961 0x1F19 
     7 'd 6     :RD = #1 16'b 0010010100100111; //   9511 0x2527 
     7 'd 7     :RD = #1 16'b 0010101100011110; //  11038 0x2B1E 
     7 'd 8     :RD = #1 16'b 0011000011111011; //  12539 0x30FB 
     7 'd 9     :RD = #1 16'b 0011011010111001; //  14009 0x36B9 
     7 'd 10    :RD = #1 16'b 0011110001010110; //  15446 0x3C56 
     7 'd 11    :RD = #1 16'b 0100000111001101; //  16845 0x41CD 
     7 'd 12    :RD = #1 16'b 0100011100011100; //  18204 0x471C 
     7 'd 13    :RD = #1 16'b 0100110000111111; //  19519 0x4C3F 
     7 'd 14    :RD = #1 16'b 0101000100110011; //  20787 0x5133 
     7 'd 15    :RD = #1 16'b 0101010111110100; //  22004 0x55F4 
     7 'd 16    :RD = #1 16'b 0101101010000001; //  23169 0x5A81 
     7 'd 17    :RD = #1 16'b 0101111011010110; //  24278 0x5ED6 
     7 'd 18    :RD = #1 16'b 0110001011110001; //  25329 0x62F1 
     7 'd 19    :RD = #1 16'b 0110011011001110; //  26318 0x66CE 
     7 'd 20    :RD = #1 16'b 0110101001101100; //  27244 0x6A6C 
     7 'd 21    :RD = #1 16'b 0110110111001001; //  28105 0x6DC9 
     7 'd 22    :RD = #1 16'b 0111000011100001; //  28897 0x70E1 
     7 'd 23    :RD = #1 16'b 0111001110110101; //  29621 0x73B5 
     7 'd 24    :RD = #1 16'b 0111011001000000; //  30272 0x7640 
     7 'd 25    :RD = #1 16'b 0111100010000011; //  30851 0x7883 
     7 'd 26    :RD = #1 16'b 0111101001111100; //  31356 0x7A7C 
     7 'd 27    :RD = #1 16'b 0111110000101001; //  31785 0x7C29 
     7 'd 28    :RD = #1 16'b 0111110110001001; //  32137 0x7D89 
     7 'd 29    :RD = #1 16'b 0111111010011100; //  32412 0x7E9C 
     7 'd 30    :RD = #1 16'b 0111111101100001; //  32609 0x7F61 
     7 'd 31    :RD = #1 16'b 0111111111010111; //  32727 0x7FD7 
     7 'd 32    :RD = #1 16'b 0111111111111111; //  32767 0x7FFF 
     7 'd 33    :RD = #1 16'b 0111111111010111; //  32727 0x7FD7 
     7 'd 34    :RD = #1 16'b 0111111101100001; //  32609 0x7F61 
     7 'd 35    :RD = #1 16'b 0111111010011100; //  32412 0x7E9C 
     7 'd 36    :RD = #1 16'b 0111110110001001; //  32137 0x7D89 
     7 'd 37    :RD = #1 16'b 0111110000101001; //  31785 0x7C29 
     7 'd 38    :RD = #1 16'b 0111101001111100; //  31356 0x7A7C 
     7 'd 39    :RD = #1 16'b 0111100010000011; //  30851 0x7883 
     7 'd 40    :RD = #1 16'b 0111011001000000; //  30272 0x7640 
     7 'd 41    :RD = #1 16'b 0111001110110101; //  29621 0x73B5 
     7 'd 42    :RD = #1 16'b 0111000011100001; //  28897 0x70E1 
     7 'd 43    :RD = #1 16'b 0110110111001001; //  28105 0x6DC9 
     7 'd 44    :RD = #1 16'b 0110101001101100; //  27244 0x6A6C 
     7 'd 45    :RD = #1 16'b 0110011011001110; //  26318 0x66CE 
     7 'd 46    :RD = #1 16'b 0110001011110001; //  25329 0x62F1 
     7 'd 47    :RD = #1 16'b 0101111011010110; //  24278 0x5ED6 
     7 'd 48    :RD = #1 16'b 0101101010000001; //  23169 0x5A81 
     7 'd 49    :RD = #1 16'b 0101010111110100; //  22004 0x55F4 
     7 'd 50    :RD = #1 16'b 0101000100110011; //  20787 0x5133 
     7 'd 51    :RD = #1 16'b 0100110000111111; //  19519 0x4C3F 
     7 'd 52    :RD = #1 16'b 0100011100011100; //  18204 0x471C 
     7 'd 53    :RD = #1 16'b 0100000111001101; //  16845 0x41CD 
     7 'd 54    :RD = #1 16'b 0011110001010110; //  15446 0x3C56 
     7 'd 55    :RD = #1 16'b 0011011010111001; //  14009 0x36B9 
     7 'd 56    :RD = #1 16'b 0011000011111011; //  12539 0x30FB 
     7 'd 57    :RD = #1 16'b 0010101100011110; //  11038 0x2B1E 
     7 'd 58    :RD = #1 16'b 0010010100100111; //   9511 0x2527 
     7 'd 59    :RD = #1 16'b 0001111100011001; //   7961 0x1F19 
     7 'd 60    :RD = #1 16'b 0001100011111000; //   6392 0x18F8 
     7 'd 61    :RD = #1 16'b 0001001011000111; //   4807 0x12C7 
     7 'd 62    :RD = #1 16'b 0000110010001011; //   3211 0xC8B 
     7 'd 63    :RD = #1 16'b 0000011001000111; //   1607 0x647 
     7 'd 64    :RD = #1 16'b 0000000000000000; //      0 0x0 
     7 'd 65    :RD = #1 16'b 1111100110111001; //  -1607 0xF9B9 
     7 'd 66    :RD = #1 16'b 1111001101110101; //  -3211 0xF375 
     7 'd 67    :RD = #1 16'b 1110110100111001; //  -4807 0xED39 
     7 'd 68    :RD = #1 16'b 1110011100001000; //  -6392 0xE708 
     7 'd 69    :RD = #1 16'b 1110000011100111; //  -7961 0xE0E7 
     7 'd 70    :RD = #1 16'b 1101101011011001; //  -9511 0xDAD9 
     7 'd 71    :RD = #1 16'b 1101010011100010; // -11038 0xD4E2 
     7 'd 72    :RD = #1 16'b 1100111100000101; // -12539 0xCF05 
     7 'd 73    :RD = #1 16'b 1100100101000111; // -14009 0xC947 
     7 'd 74    :RD = #1 16'b 1100001110101010; // -15446 0xC3AA 
     7 'd 75    :RD = #1 16'b 1011111000110011; // -16845 0xBE33 
     7 'd 76    :RD = #1 16'b 1011100011100100; // -18204 0xB8E4 
     7 'd 77    :RD = #1 16'b 1011001111000001; // -19519 0xB3C1 
     7 'd 78    :RD = #1 16'b 1010111011001101; // -20787 0xAECD 
     7 'd 79    :RD = #1 16'b 1010101000001100; // -22004 0xAA0C 
     7 'd 80    :RD = #1 16'b 1010010101111111; // -23169 0xA57F 
     7 'd 81    :RD = #1 16'b 1010000100101010; // -24278 0xA12A 
     7 'd 82    :RD = #1 16'b 1001110100001111; // -25329 0x9D0F 
     7 'd 83    :RD = #1 16'b 1001100100110010; // -26318 0x9932 
     7 'd 84    :RD = #1 16'b 1001010110010100; // -27244 0x9594 
     7 'd 85    :RD = #1 16'b 1001001000110111; // -28105 0x9237 
     7 'd 86    :RD = #1 16'b 1000111100011111; // -28897 0x8F1F 
     7 'd 87    :RD = #1 16'b 1000110001001011; // -29621 0x8C4B 
     7 'd 88    :RD = #1 16'b 1000100111000000; // -30272 0x89C0 
     7 'd 89    :RD = #1 16'b 1000011101111101; // -30851 0x877D 
     7 'd 90    :RD = #1 16'b 1000010110000100; // -31356 0x8584 
     7 'd 91    :RD = #1 16'b 1000001111010111; // -31785 0x83D7 
     7 'd 92    :RD = #1 16'b 1000001001110111; // -32137 0x8277 
     7 'd 93    :RD = #1 16'b 1000000101100100; // -32412 0x8164 
     7 'd 94    :RD = #1 16'b 1000000010011111; // -32609 0x809F 
     7 'd 95    :RD = #1 16'b 1000000000101001; // -32727 0x8029 
     7 'd 96    :RD = #1 16'b 1000000000000001; // -32767 0x8001 
     7 'd 97    :RD = #1 16'b 1000000000101001; // -32727 0x8029 
     7 'd 98    :RD = #1 16'b 1000000010011111; // -32609 0x809F 
     7 'd 99    :RD = #1 16'b 1000000101100100; // -32412 0x8164 
     7 'd 100   :RD = #1 16'b 1000001001110111; // -32137 0x8277 
     7 'd 101   :RD = #1 16'b 1000001111010111; // -31785 0x83D7 
     7 'd 102   :RD = #1 16'b 1000010110000100; // -31356 0x8584 
     7 'd 103   :RD = #1 16'b 1000011101111101; // -30851 0x877D 
     7 'd 104   :RD = #1 16'b 1000100111000000; // -30272 0x89C0 
     7 'd 105   :RD = #1 16'b 1000110001001011; // -29621 0x8C4B 
     7 'd 106   :RD = #1 16'b 1000111100011111; // -28897 0x8F1F 
     7 'd 107   :RD = #1 16'b 1001001000110111; // -28105 0x9237 
     7 'd 108   :RD = #1 16'b 1001010110010100; // -27244 0x9594 
     7 'd 109   :RD = #1 16'b 1001100100110010; // -26318 0x9932 
     7 'd 110   :RD = #1 16'b 1001110100001111; // -25329 0x9D0F 
     7 'd 111   :RD = #1 16'b 1010000100101010; // -24278 0xA12A 
     7 'd 112   :RD = #1 16'b 1010010101111111; // -23169 0xA57F 
     7 'd 113   :RD = #1 16'b 1010101000001100; // -22004 0xAA0C 
     7 'd 114   :RD = #1 16'b 1010111011001101; // -20787 0xAECD 
     7 'd 115   :RD = #1 16'b 1011001111000001; // -19519 0xB3C1 
     7 'd 116   :RD = #1 16'b 1011100011100100; // -18204 0xB8E4 
     7 'd 117   :RD = #1 16'b 1011111000110011; // -16845 0xBE33 
     7 'd 118   :RD = #1 16'b 1100001110101010; // -15446 0xC3AA 
     7 'd 119   :RD = #1 16'b 1100100101000111; // -14009 0xC947 
     7 'd 120   :RD = #1 16'b 1100111100000101; // -12539 0xCF05 
     7 'd 121   :RD = #1 16'b 1101010011100010; // -11038 0xD4E2 
     7 'd 122   :RD = #1 16'b 1101101011011001; //  -9511 0xDAD9 
     7 'd 123   :RD = #1 16'b 1110000011100111; //  -7961 0xE0E7 
     7 'd 124   :RD = #1 16'b 1110011100001000; //  -6392 0xE708 
     7 'd 125   :RD = #1 16'b 1110110100111001; //  -4807 0xED39 
     7 'd 126   :RD = #1 16'b 1111001101110101; //  -3211 0xF375 
     7 'd 127   :RD = #1 16'b 1111100110111001; //  -1607 0xF9B9 
  default : RD = #1 0;
  endcase
endmodule 

二、使用方法

按照所需要ROM的输入、输出位数,更改matlab代码中的rom_word_len和rom_addr_len这两个变量,然后运行即可。

(参考老师的程序,这玩意要是本人自己写,打死我也写不出来。)


OVER结束

  • 2
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值