差别
这里会显示出您选择的修订版和当前版本之间的差别。
两侧同时换到之前的修订记录 前一修订版 后一修订版 | 前一修订版 | ||
steptrainingboardddsacode [2020/03/23 22:40] gongyu |
steptrainingboardddsacode [2021/02/02 12:38] (当前版本) gongyusu |
||
---|---|---|---|
行 1: | 行 1: | ||
- | ##用于小脚丫FPGA综合技能训练板的DDS培训代码 | + | ##用于小脚丫FPGA综合技能训练板的DDS代码 |
### DDS主程序 | ### DDS主程序 | ||
行 12: | 行 12: | ||
output pwm_out; // 用以产生PWM波形,进而可以产生直流或任意波形,取决于外接的低通滤波器的参数 | output pwm_out; // 用以产生PWM波形,进而可以产生直流或任意波形,取决于外接的低通滤波器的参数 | ||
- | reg [23:0] cnt; // 自由运行的计数器,共计24位,最低频率为cnt[23]的12MHz/2^24= 0.75Hz | + | reg [23:0] cnt; // 自由运行的计数器,共计24位,最低频率为cnt[23]的12MHz/2^24= 0.7Hz |
- | always@(posedge clk_in) cnt <= cnt +1'b1; | + | always@(posedge clk_in) cnt <= cnt + 1'b1; |
assign led= cnt[22]; //12MHz/2^23 ~ 1.5Hz, 接近心跳频率 | assign led= cnt[22]; //12MHz/2^23 ~ 1.5Hz, 接近心跳频率 | ||
行 24: | 行 24: | ||
//assign dac_data = cnt[10] ? ~cnt[9:0] : cnt[9:0]; // 三角波形,频率 = Fclk/2^11 | //assign dac_data = cnt[10] ? ~cnt[9:0] : cnt[9:0]; // 三角波形,频率 = Fclk/2^11 | ||
- | + | reg [23:0] phase_acc; | |
- | //wire clk_internal; // 内部高倍时钟的名字96MHz | + | always @(posedge clk_in) phase_acc <= phase_acc + 24'd27962; //主时钟为12MHz,产生20KHz的正弦波信号 |
- | //CLK_96M u5(.CLKI(clk_in), .CLKOP(clk_internal)); // 以Lattice的IPCore为例产生高速内部时钟 | + | lookup_tables u_lookup_tables(.phase(phase_acc[23:16]), .sine_data(dac_data)); |
- | // 从12MHz产生96MHz,用以内部的逻辑以及DAC转换 | + | |
- | wire [23:0] next_phase; | + | |
- | wire [7:0] phase; | + | |
- | reg [23:0] accumulator; | + | |
- | + | ||
- | assign next_phase = 24'H0DA7 + accumulator; | + | |
- | + | ||
- | always @(posedge clk_in) | + | |
- | //always @(posedge clk_internal) // 使用PLL产生的高倍时钟 ~ 96MHz | + | |
- | accumulator <= #1 next_phase; | + | |
- | + | ||
- | assign phase = accumulator[23:16]; // 相位取其高8位,用来做LUT的地址 | + | |
- | + | ||
- | wire [9:0] sine_data; | + | |
- | + | ||
- | lookup_tables u_lookup_tables(clk_internal, phase, sine_data); | + | |
- | + | ||
- | //LUT_sine_table U_lut_sine_table(.Clock(~clk_internal), .ClkEn(1'b1), .Reset(1'b0), .Theta(phase), .Sine(sine_data)); | + | |
- | + | ||
- | assign dac_data = sine_data[9:0] + 10'h1ff ; | + | |
- | + | ||
wire [9:0] PWM_in; | wire [9:0] PWM_in; | ||
行 56: | 行 34: | ||
reg [10:0] PWM_DDS_accumulator; | reg [10:0] PWM_DDS_accumulator; | ||
- | always @(posedge clk_internal) PWM_DDS_accumulator <= PWM_DDS_accumulator[9:0] + PWM_in; | + | always @(posedge clk_in) PWM_DDS_accumulator <= PWM_DDS_accumulator[9:0] + PWM_in; |
assign pwm_out = PWM_DDS_accumulator[10]; | assign pwm_out = PWM_DDS_accumulator[10]; | ||
+ | |||
+ | // 可以通过内部PLL产生更高频率的时钟信号,比如120MHz,如下面的例子,只需要将上述代码中的clk_in都改为PLL产生的时钟,比如clk_120m就可以了 | ||
+ | //wire clk_120m; // 内部高倍时钟的名字 | ||
+ | //CLK_PLL u5(.CLKI(clk_in), .CLKOP(clk_120m)); // 以Lattice的IPCore为例产生高速内部时钟 | ||
+ | // 从12MHz产生120MHz,用以内部的逻辑以及DAC转换 | ||
行 69: | 行 52: | ||
/* lookup_tables.v */ | /* lookup_tables.v */ | ||
- | module lookup_tables(clk, phase, sin_out); | + | module lookup_tables(phase, sin_out); |
input [7:0] phase; | input [7:0] phase; | ||
output [9:0] sin_out; | output [9:0] sin_out; | ||
行 112: | 行 95: | ||
endmodule | endmodule | ||
- | / | ||
module sin_table(address,sin); | module sin_table(address,sin); | ||
output [8:0] sin; | output [8:0] sin; | ||
行 192: | 行 174: | ||
</code> | </code> | ||
- | ### 正弦波表数据参考 | + | ### 10位地址、12位分辨率的正弦波表数据参考 |
- | [[sine_tables|]] | + | * [[sine_tables|10位地址、12位分辨率的正弦波表Verilog代码]] |
+ | * {{:sinetable.xlsx|10位地址、14位分辨率/10位地址、12位分辨率/10位地址、10位分辨率/8位地址、10位分辨率的正弦波表xls格式的文件}} |