赞
踩
代码规范:Verilog 代码规范_verilog代码编写规范-CSDN博客
开发流程:FPGA基础知识----第二章 FPGA 开发流程_fpga 一个项目的整个流程-CSDN博客
源码下载:GitHub - Redamancy785/FPGA-Learning-Record: 项目博客:https://blog.csdn.net/weixin_51460407
这段代码是一个Verilog模块,名为
dds_ad9767
,它实现了一个双通道的直接数字频率合成器(DDS)系统。DDS是一种用于生成模拟波形(如正弦波、方波等)的电子技术,广泛应用于信号发生器、通信系统等领域。这个模块特别为与AD9767这类数字信号处理器(DSP)芯片协同工作而设计。
- /*
- Tips:
- 1、可分别于A、B通道同时输出两路波形
- 2、每次按下 f_switch_button_a_i , 通道A输出频率在预设的四种情况切换;通道B同理。
- 3、每次按下 p_switch_button_a_i , 通道A输出相位在预设的两种情况切换;通道B同理。
- */
- module dds_ad9767(
- reset_n_i,
- clk_i,
- mode_switch_button_a_i,
- f_switch_button_a_i,
- p_switch_button_a_i,
- mode_switch_button_b_i,
- f_switch_button_b_i,
- p_switch_button_b_i,
- data_a_o,
- data_b_o
- );
-
- input reset_n_i,clk_i;
- input [1:0]mode_switch_button_a_i,mode_switch_button_b_i;
- input f_switch_button_a_i,p_switch_button_a_i,f_switch_button_b_i,p_switch_button_b_i;
- output [13:0] data_a_o;
- output [13:0] data_b_o;
-
- // A通道dds例化
- reg [31:0] u_f_word_a;
- reg [11:0] u_p_word_a;
-
- dds U_dds_a(
- .reset_n_i(reset_n_i),
- .clk_i(clk_i),
- .f_word_i(u_f_word_a),
- .p_word_i(u_p_word_a),
- .mode_i(mode_switch_button_a_i),
- .data_o(data_a_o)
- );
-
- // A通道频率切换
- wire f_switch_button_a_press_key_flag;
- key_filter U_f_switch_button_a_i(
- .clk_i(clk_i),
- .reset_n_i(reset_n_i),
- .key_i(f_switch_button_a_i),
- .press_key_flag_o(f_switch_button_a_press_key_flag)
- );
-
- reg [1:0] f_switch_cnt_a;
-
- always@(posedge clk_i or negedge reset_n_i)
- if(!reset_n_i)
- f_switch_cnt_a <= 0;
- else if(f_switch_button_a_press_key_flag == 1)
- f_switch_cnt_a <= f_switch_cnt_a + 1;
-
- always@(*)
- case(f_switch_cnt_a)
- 0 : u_f_word_a <= 65536;
- 1 : u_f_word_a <= 65536*2;
- 2 : u_f_word_a <= 65536*3;
- 3 : u_f_word_a <= 65536*4;
- endcase
-
- // A通道相位切换
- wire p_switch_button_a_press_key_flag;
- key_filter U_p_switch_button_a_i(
- .clk_i(clk_i),
- .reset_n_i(reset_n_i),
- .key_i(p_switch_button_a_i),
- .press_key_flag_o(p_switch_button_a_press_key_flag)
- );
-
- reg p_switch_cnt_a;
-
- always@(posedge clk_i or negedge reset_n_i)
- if(!reset_n_i)
- p_switch_cnt_a <= 0;
- else if(p_switch_button_a_press_key_flag == 1)
- p_switch_cnt_a <= p_switch_cnt_a + 1;
- always@(*)
- case(p_switch_cnt_a)
- 0 : u_p_word_a <= 0;
- 1 : u_p_word_a <= 1024;
- endcase
-
- // B通道dds例化
- reg [31:0] u_f_word_b;
- reg [11:0] u_p_word_b;
- dds U_dds_b(
- .reset_n_i(reset_n_i),
- .clk_i(clk_i),
- .f_word_i(u_f_word_b),
- .p_word_i(u_p_word_b),
- .mode_i(mode_switch_button_b_i),
- .data_o(data_b_o)
- );
-
- // B通道频率切换
- wire f_switch_button_b_press_key_flag;
- key_filter U_f_switch_button_b_i(
- .clk_i(clk_i),
- .reset_n_i(reset_n_i),
- .key_i(f_switch_button_b_i),
- .press_key_flag_o(f_switch_button_b_press_key_flag)
- );
-
- reg [1:0] f_switch_cnt_b;
-
- always@(posedge clk_i or negedge reset_n_i)
- if(!reset_n_i)
- f_switch_cnt_b <= 0;
- else if(f_switch_button_b_press_key_flag == 1)
- f_switch_cnt_b <= f_switch_cnt_b + 1;
- always@(*)
- case(f_switch_cnt_b)
- 0 : u_f_word_b <= 65536;
- 1 : u_f_word_b <= 65536*2;
- 2 : u_f_word_b <= 65536*3;
- 3 : u_f_word_b <= 65536*4;
- endcase
-
- // B通道相位切换
- wire p_switch_button_b_press_key_flag;
- key_filter U_p_switch_button_b_i(
- .clk_i(clk_i),
- .reset_n_i(reset_n_i),
- .key_i(p_switch_button_b_i),
- .press_key_flag_o(p_switch_button_b_press_key_flag)
- );
-
- reg p_switch_cnt_b;
-
- always@(posedge clk_i or negedge reset_n_i)
- if(!reset_n_i)
- p_switch_cnt_b <= 0;
- else if(p_switch_button_b_press_key_flag == 1)
- p_switch_cnt_b <= p_switch_cnt_b + 1;
- always@(*)
- case(p_switch_cnt_b)
- 0 : u_p_word_b <= 0;
- 1 : u_p_word_b <= 1024;
- endcase
-
- endmodule
这段代码是一个Verilog模块,名为
dds
,它实现了一个直接数字频率合成器(DDS)的功能。DDS是一种电子系统,能够通过数字技术生成模拟波形,如正弦波、方波和三角波等。这个模块通过接收频率字(f_word_i
)和相位字(p_word_i
)输入,以及模式选择信号(mode_i
),来输出相应的波形数据。
- /*
- Tips:
- 1、修改 mode_i 可以切换三种不同的输出波形
- 2、f_word_i 频率字输入,当等于典型值2^16=65536时,dds输出的波形频率在738Hz左右
- 3、p_word_i 相位字输入,当等于典型值1024时,dds输出的波形起始相位为90°
- */
- module dds(
- reset_n_i,
- clk_i,
- f_word_i,
- p_word_i,
- mode_i,
- data_o
- );
-
- input [1:0] mode_i;
- input reset_n_i,clk_i;
- input [31:0]f_word_i;
- input [11:0]p_word_i;
- output reg [13:0] data_o;
-
- // 频率字输入寄存器 r_f_word_i
- reg [31:0] r_f_word_i;
- always@(posedge clk_i)
- r_f_word_i <= f_word_i;
-
- // 相位字输入寄存器 r_f_word_i
- reg [11:0] r_p_word_i;
- always@(posedge clk_i)
- r_p_word_i <= p_word_i;
-
- // 相位累加器 phase_accumulator
- reg [31:0] phase_accumulator;
- always@(posedge clk_i or negedge reset_n_i)
- if(!reset_n_i)
- phase_accumulator <= 0;
- else
- phase_accumulator <= phase_accumulator + r_f_word_i;
-
- // 波形数据表地址 rom_addr
- reg [11:0] rom_addr;
- always@(posedge clk_i or negedge reset_n_i)
- if(!reset_n_i)
- rom_addr <= 0;
- else
- rom_addr <= r_p_word_i + phase_accumulator[31:20];
- // sine波形
- wire [13:0] sine_data_o;
- sine_rom U_sine_rom (
- .clka(clk_i), // input wire clka
- .addra(rom_addr), // input wire [11 : 0] addra
- .douta(sine_data_o) // output wire [13 : 0] douta
- );
-
- // square波形
- wire [13:0] square_data_o;
- square_rom U_square_rom (
- .clka(clk_i), // input wire clka
- .addra(rom_addr), // input wire [11 : 0] addra
- .douta(square_data_o) // output wire [13 : 0] douta
- );
-
- // triangular波形
- wire [13:0] triangular_data_o;
- triangular_rom U_triangular_rom (
- .clka(clk_i), // input wire clka
- .addra(rom_addr), // input wire [11 : 0] addra
- .douta(triangular_data_o) // output wire [13 : 0] douta
- );
-
- // 模式选择
- always@(*)
- case(mode_i)
- 0 : data_o = sine_data_o;
- 1 : data_o = square_data_o;
- 2 : data_o = triangular_data_o;
- 3 : data_o = 8192;
- endcase
-
-
- endmodule
这段代码是一个Verilog模块,名为
key_filter
,它实现了一个按键滤波器的功能。该模块用于检测按键的按下和释放,并确保按键动作至少持续20毫秒。模块提供了按键按下和释放的输出标志,以及当前按键的状态。
- /*
- Tips:
- 1、检测到按键按下,会产生一个周期的 press_key_flag_o 提示信号
- 2、按键按下时间需要持续20ms
- */
- module key_filter(
- clk_i,
- reset_n_i,
- key_i,
- press_key_flag_o,
- release_key_flag_o,
- key_state_o
- );
-
- input clk_i,reset_n_i,key_i;
- output press_key_flag_o,release_key_flag_o,key_state_o;
-
- reg press_key_flag_o,release_key_flag_o;
- reg [1:0] state;
- wire time_20ms_reached;
- reg key_state_o;
- localparam IDLE = 0;
- localparam PRESS_FILTER = 1;
- localparam WAIT = 2;
- localparam RELEASE_FILTER = 3;
-
- // 输入 key_i 同步处理 消除亚稳态
- reg r_key_i,sync_d_0_key_i,sync_d_1_key_i;
- wire nedge_key,pedge_key;
- always@(posedge clk_i)
- sync_d_0_key_i <= key_i;
- always@(posedge clk_i)
- sync_d_1_key_i <= sync_d_0_key_i;
- always@(posedge clk_i)
- r_key_i <= sync_d_1_key_i;
-
- assign nedge_key = r_key_i & (~sync_d_1_key_i);
- assign pedge_key = ~r_key_i & sync_d_1_key_i;
-
- // 状态机
- always@(posedge clk_i or negedge reset_n_i)
- if(!reset_n_i) begin
- release_key_flag_o <= 0;
- press_key_flag_o <= 0;
- state <= IDLE;
- key_state_o <= 1;
- end
- else begin
- case(state)
- IDLE :
- begin
- release_key_flag_o <= 0;
- if(nedge_key)
- state <= PRESS_FILTER;
- else
- state <= IDLE;
- end
-
- PRESS_FILTER :
- if(time_20ms_reached) begin
- state <= WAIT;
- press_key_flag_o <= 1;
- key_state_o <= 0;
- end
- else if(pedge_key)
- state <= IDLE;
- else
- state <= PRESS_FILTER;
-
- WAIT :
- begin
- press_key_flag_o <= 0;
- if(pedge_key)
- state <= RELEASE_FILTER;
- else
- state <= WAIT;
- end
-
- RELEASE_FILTER :
- if(time_20ms_reached) begin
- state <= IDLE;
- release_key_flag_o <= 1;
- key_state_o <= 1;
- end
- else if(nedge_key)
- state <= WAIT;
- else
- state <= RELEASE_FILTER;
- endcase
- end
-
- // time_20ms_reached
- parameter MCNT = 1000_000;
- reg [29:0] counter;
- always@(posedge clk_i or negedge reset_n_i)
- if(!reset_n_i)
- counter <= 0;
- else if(state == RELEASE_FILTER || state == PRESS_FILTER)
- counter <= counter + 1;
- else
- counter <= 0;
-
- assign time_20ms_reached = ( counter >= (MCNT - 1) );
-
- endmodule
这段代码是一个Verilog测试平台(testbench),名为
dds_ad9767_tb
,用于模拟和测试dds_ad9767
模块的行为。测试平台没有物理硬件,它通过模拟输入信号来验证dds_ad9767
模块的功能是否符合预期。
- `timescale 1ns / 1ps
-
- module dds_ad9767_tb();
- reg u_reset_n_i,u_clk_i;
- reg [1:0] u_mode_switch_button_a_i,u_mode_switch_button_b_i;
- reg u_f_switch_button_a_i,u_p_switch_button_a_i,u_f_switch_button_b_i,u_p_switch_button_b_i;
- wire [13:0] u_data_a_o;
- wire [13:0] u_data_b_o;
-
- dds_ad9767 U_dds_ad9767(
- .reset_n_i(u_reset_n_i),
- .clk_i(u_clk_i),
- .mode_switch_button_a_i(u_mode_switch_button_a_i),
- .f_switch_button_a_i(u_f_switch_button_a_i),
- .p_switch_button_a_i(u_p_switch_button_a_i),
- .mode_switch_button_b_i(u_mode_switch_button_b_i),
- .f_switch_button_b_i(u_f_switch_button_b_i),
- .p_switch_button_b_i(u_p_switch_button_b_i),
- .data_a_o(u_data_a_o),
- .data_b_o(u_data_b_o)
- );
-
- initial u_clk_i = 1;
- always #10 u_clk_i = ~u_clk_i; // 50MHz
-
- initial begin
- u_reset_n_i = 0;
- u_f_switch_button_a_i = 1;
- u_f_switch_button_b_i = 1;
- u_p_switch_button_a_i = 1;
- u_p_switch_button_b_i = 1;
-
- // 通道 波形类型 频率倍数 相位
- // a sine x1 0 \ b square x1 0
- u_mode_switch_button_a_i = 0;
- u_mode_switch_button_b_i = 1;
- #201;
- u_reset_n_i = 1;
- #10_000_000;
-
- // a square x1 0 \ b square x1 0
- u_mode_switch_button_a_i = 1;
-
- // a square x2 0 \ b square x1 0
- u_f_switch_button_a_i = 0;
- #20_000_000;
- u_f_switch_button_a_i = 1;
- #10_000_000;
-
- // a square x2 90 \ b square x1 0
- u_p_switch_button_a_i = 0;
- #20_000_000;
- u_p_switch_button_a_i = 1;
- #10_000_000;
-
- // a square x2 90 \ b square x1 90
- u_p_switch_button_b_i = 0;
- #20_000_000;
- u_p_switch_button_b_i = 1;
- #10_000_000;
-
- // a square x2 90 \ b triangular x1 90
- u_mode_switch_button_b_i = 2;
-
- // a square x2 90 \ b triangular x2 90
- u_f_switch_button_a_i = 0;
- #20_000_000;
- u_f_switch_button_a_i = 1;
- #10_000_000;
-
- $stop;
- end
- endmodule
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。