FPGA基础实验:用计数器读取ROM数据产生信号波形(直接数字频率合成DDS)

FPGA基础实验:用计数器生成地址、读取ROM数据产生信号波形(直接数字频率合成DDS)

这里写图片描述

一、带可变增量的计数器

对于计数器的设计参考前面几个实验的设计思路。在本实验中,主要是通过计数器以不同的增量进行计数,用来读取ROM中以计数值为地址对应的存储数据。另外,对本计数器添加了能通过输入来控制计数增量的设计。电路例化程序如下:

////////// 带计数增量输入的计数器  /////////////
module cnt_incr(            
  CLK   ,   // clock
  INCR  ,   // counter increase value 
  CNTVAL);  // counter value
input CLK;
input  [10-1:0] INCR;
output [10-1:0] CNTVAL;

reg [10-1:0] CNTVAL;

always @ (posedge CLK) begin
  CNTVAL <= INCR + CNTVAL;
end
endmodule  

例化后的原理图:

这里写图片描述

二、ROM

设计一个地址深度为128、数据宽度为8的ROM,并在对应地址单元中存储能产生正弦波形的数据。
例化程序如下:

// module sine_rom()
module sine_rom(
  CLK    ,           // clock
  RA     ,           // read address
  RD     );          // read data
input          CLK;
input  [6  :0] RA;
output [7  :0] RD;
reg    [7  :0] RD;
always @ (posedge CLK)
  case(RA)
     7 'd 0     :RD = #1 8 'b 00000000; //      0 0x0 
     7 'd 1     :RD = #1 8 'b 00000110; //      6 0x6 
     7 'd 2     :RD = #1 8 'b 00001100; //     12 0xC 
     7 'd 3     :RD = #1 8 'b 00010010; //     18 0x12 
     7 'd 4     :RD = #1 8 'b 00011000; //     24 0x18 
     7 'd 5     :RD = #1 8 'b 00011110; //     30 0x1E 
     7 'd 6     :RD = #1 8 'b 00100100; //     36 0x24 
     7 'd 7     :RD = #1 8 'b 00101010; //     42 0x2A 
     7 'd 8     :RD = #1 8 'b 00110000; //     48 0x30 
     7 'd 9     :RD = #1 8 'b 00110110; //     54 0x36 
     7 'd 10    :RD = #1 8 'b 00111011; //     59 0x3B 
     7 'd 11    :RD = #1 8 'b 01000001; //     65 0x41 
     7 'd 12    :RD = #1 8 'b 01000110; //     70 0x46 
     7 'd 13    :RD = #1 8 'b 01001011; //     75 0x4B 
     7 'd 14    :RD = #1 8 'b 01010000; //     80 0x50 
     7 'd 15    :RD = #1 8 'b 01010101; //     85 0x55 
     7 'd 16    :RD = #1 8 'b 01011001; //     89 0x59 
     7 'd 17    :RD = #1 8 'b 01011110; //     94 0x5E 
     7 'd 18    :RD = #1 8 'b 01100010; //     98 0x62 
     7 'd 19    :RD = #1 8 'b 01100110; //    102 0x66 
     7 'd 20    :RD = #1 8 'b 01101001; //    105 0x69 
     7 'd 21    :RD = #1 8 'b 01101100; //    108 0x6C 
     7 'd 22    :RD = #1 8 'b 01110000; //    112 0x70 
     7 'd 23    :RD = #1 8 'b 01110010; //    114 0x72 
     7 'd 24    :RD = #1 8 'b 01110101; //    117 0x75 
     7 'd 25    :RD = #1 8 'b 01110111; //    119 0x77 
     7 'd 26    :RD = #1 8 'b 01111001; //    121 0x79 
     7 'd 27    :RD = #1 8 'b 01111011; //    123 0x7B 
     7 'd 28    :RD = #1 8 'b 01111100; //    124 0x7C 
     7 'd 29    :RD = #1 8 'b 01111101; //    125 0x7D 
     7 'd 30    :RD = #1 8 'b 01111110; //    126 0x7E 
     7 'd 31    :RD = #1 8 'b 01111110; //    126 0x7E 
     7 'd 32    :RD = #1 8 'b 01111111; //    127 0x7F 
     7 'd 33    :RD = #1 8 'b 01111110; //    126 0x7E 
     7 'd 34    :RD = #1 8 'b 01111110; //    126 0x7E 
     7 'd 35    :RD = #1 8 'b 01111101; //    125 0x7D 
     7 'd 36    :RD = #1 8 'b 01111100; //    124 0x7C 
     7 'd 37    :RD = #1 8 'b 01111011; //    123 0x7B 
     7 'd 38    :RD = #1 8 'b 01111001; //    121 0x79 
     7 'd 39    :RD = #1 8 'b 01110111; //    119 0x77 
     7 'd 40    :RD = #1 8 'b 01110101; //    117 0x75 
     7 'd 41    :RD = #1 8 'b 01110010; //    114 0x72 
     7 'd 42    :RD = #1 8 'b 01110000; //    112 0x70 
     7 'd 43    :RD = #1 8 'b 01101100; //    108 0x6C 
     7 'd 44    :RD = #1 8 'b 01101001; //    105 0x69 
     7 'd 45    :RD = #1 8 'b 01100110; //    102 0x66 
     7 'd 46    :RD = #1 8 'b 01100010; //     98 0x62 
     7 'd 47    :RD = #1 8 'b 01011110; //     94 0x5E 
     7 'd 48    :RD = #1 8 'b 01011001; //     89 0x59 
     7 'd 49    :RD = #1 8 'b 01010101; //     85 0x55 
     7 'd 50    :RD = #1 8 'b 01010000; //     80 0x50 
     7 'd 51    :RD = #1 8 'b 01001011; //     75 0x4B 
     7 'd 52    :RD = #1 8 'b 01000110; //     70 0x46 
     7 'd 53    :RD = #1 8 'b 01000001; //     65 0x41 
     7 'd 54    :RD = #1 8 'b 00111011; //     59 0x3B 
     7 'd 55    :RD = #1 8 'b 00110110; //     54 0x36 
     7 'd 56    :RD = #1 8 'b 00110000; //     48 0x30 
     7 'd 57    :RD = #1 8 'b 00101010; //     42 0x2A 
     7 'd 58    :RD = #1 8 'b 00100100; //     36 0x24 
     7 'd 59    :RD = #1 8 'b 00011110; //     30 0x1E 
     7 'd 60    :RD = #1 8 'b 00011000; //     24 0x18 
     7 'd 61    :RD = #1 8 'b 00010010; //     18 0x12 
     7 'd 62    :RD = #1 8 'b 00001100; //     12 0xC 
     7 'd 63    :RD = #1 8 'b 00000110; //      6 0x6 
     7 'd 64    :RD = #1 8 'b 00000000; //      0 0x0 
     7 'd 65    :RD = #1 8 'b 11111010; //     -6 0xFA 
     7 'd 66    :RD = #1 8 'b 11110100; //    -12 0xF4 
     7 'd 67    :RD = #1 8 'b 11101110; //    -18 0xEE 
     7 'd 68    :RD = #1 8 'b 11101000; //    -24 0xE8 
     7 'd 69    :RD = #1 8 'b 11100010; //    -30 0xE2 
     7 'd 70    :RD = #1 8 'b 11011100; //    -36 0xDC 
     7 'd 71    :RD = #1 8 'b 11010110; //    -42 0xD6 
     7 'd 72    :RD = #1 8 'b 11010000; //    -48 0xD0 
     7 'd 73    :RD = #1 8 'b 11001010; //    -54 0xCA 
     7 'd 74    :RD = #1 8 'b 11000101; //    -59 0xC5 
     7 'd 75    :RD = #1 8 'b 10111111; //    -65 0xBF 
     7 'd 76    :RD = #1 8 'b 10111010; //    -70 0xBA 
     7 'd 77    :RD = #1 8 'b 10110101; //    -75 0xB5 
     7 'd 78    :RD = #1 8 'b 10110000; //    -80 0xB0 
     7 'd 79    :RD = #1 8 'b 10101011; //    -85 0xAB 
     7 'd 80    :RD = #1 8 'b 10100111; //    -89 0xA7 
     7 'd 81    :RD = #1 8 'b 10100010; //    -94 0xA2 
     7 'd 82    :RD = #1 8 'b 10011110; //    -98 0x9E 
     7 'd 83    :RD = #1 8 'b 10011010; //   -102 0x9A 
     7 'd 84    :RD = #1 8 'b 10010111; //   -105 0x97 
     7 'd 85    :RD = #1 8 'b 10010100; //   -108 0x94 
     7 'd 86    :RD = #1 8 'b 10010000; //   -112 0x90 
     7 'd 87    :RD = #1 8 'b 10001110; //   -114 0x8E 
     7 'd 88    :RD = #1 8 'b 10001011; //   -117 0x8B 
     7 'd 89    :RD = #1 8 'b 10001001; //   -119 0x89 
     7 'd 90    :RD = #1 8 'b 10000111; //   -121 0x87 
     7 'd 91    :RD = #1 8 'b 10000101; //   -123 0x85 
     7 'd 92    :RD = #1 8 'b 10000100; //   -124 0x84 
     7 'd 93    :RD = #1 8 'b 10000011; //   -125 0x83 
     7 'd 94    :RD = #1 8 'b 10000010; //   -126 0x82 
     7 'd 95    :RD = #1 8 'b 10000010; //   -126 0x82 
     7 'd 96    :RD = #1 8 'b 10000001; //   -127 0x81 
     7 'd 97    :RD = #1 8 'b 10000010; //   -126 0x82 
     7 'd 98    :RD = #1 8 'b 10000010; //   -126 0x82 
     7 'd 99    :RD = #1 8 'b 10000011; //   -125 0x83 
     7 'd 100   :RD = #1 8 'b 10000100; //   -124 0x84 
     7 'd 101   :RD = #1 8 'b 10000101; //   -123 0x85 
     7 'd 102   :RD = #1 8 'b 10000111; //   -121 0x87 
     7 'd 103   :RD = #1 8 'b 10001001; //   -119 0x89 
     7 'd 104   :RD = #1 8 'b 10001011; //   -117 0x8B 
     7 'd 105   :RD = #1 8 'b 10001110; //   -114 0x8E 
     7 'd 106   :RD = #1 8 'b 10010000; //   -112 0x90 
     7 'd 107   :RD = #1 8 'b 10010100; //   -108 0x94 
     7 'd 108   :RD = #1 8 'b 10010111; //   -105 0x97 
     7 'd 109   :RD = #1 8 'b 10011010; //   -102 0x9A 
     7 'd 110   :RD = #1 8 'b 10011110; //    -98 0x9E 
     7 'd 111   :RD = #1 8 'b 10100010; //    -94 0xA2 
     7 'd 112   :RD = #1 8 'b 10100111; //    -89 0xA7 
     7 'd 113   :RD = #1 8 'b 10101011; //    -85 0xAB 
     7 'd 114   :RD = #1 8 'b 10110000; //    -80 0xB0 
     7 'd 115   :RD = #1 8 'b 10110101; //    -75 0xB5 
     7 'd 116   :RD = #1 8 'b 10111010; //    -70 0xBA 
     7 'd 117   :RD = #1 8 'b 10111111; //    -65 0xBF 
     7 'd 118   :RD = #1 8 'b 11000101; //    -59 0xC5 
     7 'd 119   :RD = #1 8 'b 11001010; //    -54 0xCA 
     7 'd 120   :RD = #1 8 'b 11010000; //    -48 0xD0 
     7 'd 121   :RD = #1 8 'b 11010110; //    -42 0xD6 
     7 'd 122   :RD = #1 8 'b 11011100; //    -36 0xDC 
     7 'd 123   :RD = #1 8 'b 11100010; //    -30 0xE2 
     7 'd 124   :RD = #1 8 'b 11101000; //    -24 0xE8  
     7 'd 125   :RD = #1 8 'b 11101110; //    -18 0xEE 
     7 'd 126   :RD = #1 8 'b 11110100; //    -12 0xF4
     7 'd 127   :RD = #1 8 'b 11111010; //     -6 0xFA 
  default : RD = #1 0;
  endcase
endmodule 

例化后的ROM:

这里写图片描述

创建BDF文件,添加例化元器件并连接,思考下面不同的设置会产生什么样的结果

这里写图片描述

以文本形式进行管脚配置,积累快速高效的设计经验

这里写图片描述

扫描二维码关注公众号,回复: 1677026 查看本文章

创建SignalTap文件,添加观测点进行硬件仿真观测

这里写图片描述

按照下面提示进行设置,观测结果

这里写图片描述

这里写图片描述

进行不同的设置,会得到不同的结果,思考产生的原因。

1、通过观测可以发现,正弦波的频率和计数器的增量是存在一定的关系,频率随着增量的增加而增加。
2、同样,计算出正弦波的最低频率f1约0.39 MHz(50MHz/128)
3、如果我们想得到更低频率的正弦波,(1)可以通过减小计数增量,(2)可以增大计数器数据位宽,并以高位作为ROM地址输入。【例如:count[9:0],把count高7位赋给RA[6:0]】

如果对计数器进行改动,修改计数增量信号为10比特,计数值信号为10比特

– 把计数增量输入信号分配到10个拨码开关上
– 把计数值信号的高7位分配为ROM的地址,低3位悬空不使用。
– 编译、下载电路,拨动拨码开关,观察最低频率有什么变化。

很明显,可以观测到的结果正好对应上述问题的第3个设置,增加位宽并把高位作为ROM地址输入,可以减小正弦波的频率。

这种电路有个好听的名字,叫做 直接数字频率合成(DDS)

更神奇的是:输出信号频率 和 电路工作时钟频率,计数器增量值,以及计数器数据位宽之间,存在一定关系:
这里写图片描述

猜你喜欢

转载自blog.csdn.net/sinat_29862967/article/details/78765326