FPGA学习笔记——简易的DDS信号发生器
目录
一、任务
二、分析
三、ROM IP核配置
四、Visio图
五、代码
(1).v代码
(2)仿真代码
六、仿真
七、实验现象
一、任务
用串口模块,用上位机发送指令,FPGA接收,然后输出对应的波形;其中指令用FE+波形+类型+频率+相位+幅度+EE。
波形:选择哪个波形
类型:频率缩小还是放大
二、分析
首先要有串口模块rx和tx,还要有四个单端口ROM模块,分别存储四种不同的波形,然后还要对指令处理的模块,将处理后的指令给各个模块使用。
三、ROM IP核配置
四、Visio图
这里我就用RTL Viewer代替了。
五、代码
(1).v代码
top.v
module top (
input wire clk ,
input wire rst_n ,
input wire rx ,
input wire key ,
output wire led ,
output wire tx
);
//key
wire key_out;
//tx
wire [7:0] data_tx;
wire start ;
wire done_tx;
//rx
wire [7:0] data_rx;
wire done_rx;
//ctrl_rom1
wire [7:0] data_wave1;
wire done_wave1;//ctrl_rom2
wire [7:0] data_wave2;
wire done_wave2;//ctrl_rom3
wire [7:0] data_wave3;
wire done_wave3;//ctrl_rom4
wire [7:0] data_wave4;
wire done_wave4;//cmd
wire [7:0] wave ;
wire [1:0] mode ;
wire [7:0] freq ;
wire [7:0] phas ;
wire [7:0] ampl ;
wire done_cmd;
//select_wave
wire [7:0] data_wave;
wire done_wave;cmd cmd_u(
. clk (clk ) ,
. rst_n (rst_n ) ,
. key_out ( key_out ) ,
. data_rx (data_rx ) ,//并行数据 ,其它模块用
. done_rx (done_rx ) ,
. led (led ) ,
. wave (wave ) ,//波形
. mode (mode ) ,//01:除法;10:乘法
. freq (freq ) ,//频率
. phas (phas ) ,//相位
. ampl (ampl ) ,//赋值
. done_cmd (done_cmd) //命令解析完成
);rx rx_u(
. clk (clk ) ,
. rst_n (rst_n ) ,
. rx (rx ) ,//数据接收信号线
. data_rx (data_rx) ,//并行数据 ,其它模块用
. done_rx (done_rx) //握手信号 ,接收结束信号 , 结束成功信号
);tx tx_u(
. clk (clk ) ,
. rst_n (rst_n ) ,
. data_tx (data_wave) ,//并行输入 --- 变化
. start (done_wave) ,//数据有效信号
. tx (tx ) , //串行输出
. done_tx (done_tx ) //字节传输完成
);ctrl_rom1 ctrl_rom1_u(
. clk (clk ) ,
. rst_n (rst_n ) ,
. wave (wave ) ,//波形
. mode (mode ) ,//01:除法( );10:乘法( )
. freq (freq ) ,//频率
. done_tx (done_tx ) ,
. phas (phas ) ,//相位
. ampl (ampl ) ,//幅值
. done_cmd (done_cmd ) ,//命令解析完成
. data_wave1 (data_wave1) ,
. done_wave1 (done_wave1)
);ctrl_rom2 ctrl_rom2_u(
. clk (clk ) ,
. rst_n (rst_n ) ,
. wave (wave ) ,//波形
. mode (mode ) ,//01:除法( );10:乘法( )
. freq (freq ) ,//频率
. done_tx (done_tx ) ,
. phas (phas ) ,//相位
. ampl (ampl ) ,//幅值
. done_cmd (done_cmd ) ,//命令解析完成
. data_wave2 (data_wave2) ,
. done_wave2 (done_wave2)
);ctrl_rom3 ctrl_rom3_u(
. clk (clk ) ,
. rst_n (rst_n ) ,
. wave (wave ) ,//波形
. mode (mode ) ,//01:除法( );10:乘法( )
. freq (freq ) ,//频率
. done_tx (done_tx ) ,
. phas (phas ) ,//相位
. ampl (ampl ) ,//幅值
. done_cmd (done_cmd ) ,//命令解析完成
. data_wave3 (data_wave3) ,
. done_wave3 (done_wave3)
);ctrl_rom4 ctrl_rom4_u(
. clk (clk ) ,
. rst_n (rst_n ) ,
. wave (wave ) ,//波形
. mode (mode ) ,//01:除法( );10:乘法( )
. freq (freq ) ,//频率
. done_tx (done_tx ) ,
. phas (phas ) ,//相位
. ampl (ampl ) ,//幅值
. done_cmd (done_cmd ) ,//命令解析完成
. data_wave4 (data_wave4) ,
. done_wave4 (done_wave4)
);select_wave select_wave_u(
. clk (clk ) ,
. rst_n (rst_n ) ,
. done_cmd (done_cmd ) ,//命令解析完成
. wave (wave ) ,//波形
. data_wave1 (data_wave1) ,
. done_wave1 (done_wave1) ,
. data_wave2 (data_wave2) ,
. done_wave2 (done_wave2) ,
. data_wave3 (data_wave3) ,
. done_wave3 (done_wave3) ,
. data_wave4 (data_wave4) ,
. done_wave4 (done_wave4) ,
. data_wave (data_wave ) ,
. done_wave (done_wave )
);key key_u(
. clk (clk ) ,
. rst_n (rst_n ) ,
. key (key ) ,
. key_out (key_out)
);endmodule
cmd.v
module cmd (
input wire clk ,
input wire rst_n ,
input wire key_out ,
input wire [7:0] data_rx ,//并行数据 ,其它模块用
input wire done_rx ,
output reg led ,
output reg [7:0] wave ,//波形
output reg [1:0] mode ,//01:除法;10:乘法
output reg [7:0] freq ,//频率
output reg [7:0] phas ,//相位
output reg [7:0] ampl ,//幅值
output reg done_cmd //命令解析完成
);
//指令处理localparam IDLE = 8'b0000_0001,START = 8'b0000_0010,WAVE = 8'b0000_0100, MODE = 8'b0000_1000, FREQ = 8'b0001_0000,PHAS = 8'b0010_0000,AMPL = 8'b0100_0000,STOP = 8'b1000_0000;
reg [7:0] cur_state ,next_state ;always @(posedge clk) beginif(!rst_n)cur_state <= IDLE;elsecur_state <= next_state;
endalways @(*) beginif(!rst_n)next_state = IDLE;elsecase (cur_state)IDLE :beginif(key_out)next_state = START;elsenext_state = cur_state;endSTART:begin //包头if( data_rx == 8'hFE && done_rx )next_state = WAVE;else if( data_rx != 8'hFE && done_rx )next_state = IDLE;elsenext_state = cur_state;endWAVE :begin //波形if( done_rx )next_state = MODE;elsenext_state = cur_state;endMODE :begin //if( done_rx )next_state = FREQ;elsenext_state = cur_state;endFREQ :begin //if( done_rx )next_state = PHAS;elsenext_state = cur_state;endPHAS :begin //if( done_rx )next_state = AMPL;elsenext_state = cur_state;endAMPL :begin //if( done_rx )next_state = STOP;elsenext_state = cur_state;endSTOP : begin //包尾if( done_rx && data_rx == 8'hEE)next_state = START;else if(done_rx && data_rx != 8'hEE)next_state = IDLE;elsenext_state = cur_state;enddefault: next_state = IDLE;endcase
endalways @(posedge clk) beginif(!rst_n) beginled <= 0;wave <= 0;mode <= 0;freq <= 0;phas <= 0;ampl <= 0;done_cmd <= 0;end elsecase (cur_state)IDLE :beginled <= 1;wave <= 0;mode <= 0;freq <= 0;phas <= 0;ampl <= 0;done_cmd <= 0;end START:beginled <= 0;wave <= wave ;mode <= mode ;freq <= freq ;phas <= phas ;ampl <= ampl ;done_cmd <= 0;end WAVE :beginif(done_rx)wave <= data_rx; endMODE :beginif(done_rx)mode <= data_rx; endFREQ :beginif(done_rx)freq <= data_rx; endPHAS :beginif(done_rx)phas <= data_rx; endAMPL :beginif(done_rx)ampl <= data_rx; endSTOP : beginif(done_rx && data_rx == 8'hEE)done_cmd <= 1; elsedone_cmd <= 0; enddefault: beginled <= 0;wave <= 0;mode <= 0;freq <= 0;phas <= 0;ampl <= 0;done_cmd <= 0;end endcase
endendmodule
ctrl_rom1.v
module ctrl_rom1 (
input wire clk ,
input wire rst_n ,
input wire [7:0] wave ,//波形
input wire [1:0] mode ,//01:除法( );10:乘法( )
input wire [7:0] freq ,//频率
input wire done_tx ,
input wire [7:0] phas ,//相位
input wire [7:0] ampl ,//幅值
input wire done_cmd ,//命令解析完成
output reg [7:0] data_wave1 ,
output reg done_wave1
);
//rom1
wire [7:0] q;
reg [7:0] address;
reg [7:0] q_reg ;//幅度计算寄存器//------------信号寄存---------//
reg done_cmd_reg;
reg [7:0] wave_reg;
reg [1:0] mode_reg;
reg [7:0] freq_reg;
reg [7:0] phas_reg;
reg [7:0] ampl_reg;always @(posedge clk) beginif(!rst_n) beginwave_reg <= 0;mode_reg <= 0;freq_reg <= 0;phas_reg <= 0;ampl_reg <= 0;done_cmd_reg <= 0;endelse if ( done_cmd ) beginwave_reg <= wave;mode_reg <= mode;freq_reg <= freq;phas_reg <= phas;ampl_reg <= ampl;done_cmd_reg <=done_cmd;endelsedone_cmd_reg <= 0;
end//状态机--------------------//
localparam IDLE = 7'b0000001, //等待key_outWAVE = 7'b0000010, //波形判断PHAS = 7'b0000100, //相位:rom地址起始值FREQ = 7'b0001000, //频率:01:隔n个地址取一次数据,10:同一个地址数据取n次AMPL = 7'b0010000, //计算幅值DATA = 7'b0100000, //输出波形 + doneSTOP = 7'b1000000; //等待done_tx 构成循环
reg [6:0] cur_state , next_state;
reg [3:0] cnt;//
always @(posedge clk) beginif(!rst_n)cur_state <= IDLE;elsecur_state <= next_state;
endalways @(*) beginif(!rst_n) beginnext_state = IDLE;endelsecase (cur_state)IDLE: beginif(done_cmd_reg)next_state = WAVE;elsenext_state = cur_state;endWAVE: beginif(wave_reg == 8'h01)next_state = PHAS;else if (wave_reg != 8'h01)next_state = IDLE;elsenext_state = cur_state;endPHAS:beginif(done_cmd_reg)next_state = WAVE;elsenext_state = FREQ;endFREQ:beginif(done_cmd_reg)next_state = WAVE;else if( cnt == freq_reg - 1 && mode_reg == 2'b01 )next_state = AMPL;else if( mode_reg == 2'b10 )next_state = AMPL;elsenext_state = cur_state;endAMPL:beginif(done_cmd_reg)next_state = WAVE;elsenext_state = DATA;endDATA:beginif(done_cmd_reg)next_state = WAVE;elsenext_state = STOP;endSTOP: beginif(done_cmd_reg)next_state = WAVE;else if( done_tx )next_state = FREQ;elsenext_state = cur_state;enddefault: next_state = IDLE;endcase
endalways @(posedge clk) beginif(!rst_n) begindata_wave1 <= 0;done_wave1 <= 0;address <= 0;cnt <= 0;q_reg <= 0;endelsecase (cur_state)IDLE:begindata_wave1 <= 0;done_wave1 <= 0;address <= 0;cnt <= 0;q_reg <= 0;endWAVE:begindata_wave1 <= 0;done_wave1 <= 0;address <= 0;cnt <= 0;q_reg <= 0;endPHAS:begin//rom起始地址address <= phas_reg;endFREQ:begincase (mode) //频率:01:隔n个地址取一次数据,10:同一个地址数据取n次01:beginaddress <= address + 1;if( cnt == freq_reg - 1 )cnt <= 0;elsecnt <= cnt + 1;end10: beginif( cnt == freq_reg - 1 ) begincnt <= 0;address <= address + 1;endelsecnt <= cnt + 1;enddefault: beginaddress <= 0;cnt <= 0;endendcaseendAMPL:beginq_reg <= q/ampl_reg;endDATA:begindata_wave1 <= q_reg;done_wave1 <= 1; //短信号endSTOP: begindata_wave1 <= 0;done_wave1 <= 0;q_reg <= 0;enddefault: begindata_wave1 <= 0;done_wave1 <= 0;address <= 0;cnt <= 0;q_reg <= 0;endendcase
end//rom1
rom1 rom1_inst (.aclr ( !rst_n ),.address ( address ),.clock ( clk ),.q ( q ));endmodule
ctrl_rom2.v
module ctrl_rom2 (
input wire clk ,
input wire rst_n ,
input wire [7:0] wave ,//波形
input wire [1:0] mode ,//01:除法( );10:乘法( )
input wire [7:0] freq ,//频率
input wire done_tx ,
input wire [7:0] phas ,//相位
input wire [7:0] ampl ,//幅值
input wire done_cmd ,//命令解析完成
output reg [7:0] data_wave2 ,
output reg done_wave2
);
//rom1
wire [7:0] q;
reg [7:0] address;
reg [7:0] q_reg ;//幅度计算寄存器//------------信号寄存---------//
reg done_cmd_reg;
reg [7:0] wave_reg;
reg [1:0] mode_reg;
reg [7:0] freq_reg;
reg [7:0] phas_reg;
reg [7:0] ampl_reg;always @(posedge clk) beginif(!rst_n) beginwave_reg <= 0;mode_reg <= 0;freq_reg <= 0;phas_reg <= 0;ampl_reg <= 0;done_cmd_reg <= 0;endelse if ( done_cmd ) beginwave_reg <= wave;mode_reg <= mode;freq_reg <= freq;phas_reg <= phas;ampl_reg <= ampl;done_cmd_reg <=done_cmd;endelsedone_cmd_reg <= 0;
end//状态机--------------------//
localparam IDLE = 7'b0000001, //等待key_outWAVE = 7'b0000010, //波形判断PHAS = 7'b0000100, //相位:rom地址起始值FREQ = 7'b0001000, //频率:01:隔n个地址取一次数据,10:同一个地址数据取n次AMPL = 7'b0010000, //计算幅值DATA = 7'b0100000, //输出波形 + doneSTOP = 7'b1000000; //等待done_tx 构成循环
reg [6:0] cur_state , next_state;
reg [3:0] cnt;//
always @(posedge clk) beginif(!rst_n)cur_state <= IDLE;elsecur_state <= next_state;
endalways @(*) beginif(!rst_n) beginnext_state = IDLE;endelsecase (cur_state)IDLE: beginif(done_cmd_reg)next_state = WAVE;elsenext_state = cur_state;endWAVE: beginif(wave_reg == 8'h02)next_state = PHAS;else if (wave_reg != 8'h02)next_state = IDLE;elsenext_state = cur_state;endPHAS:beginif(done_cmd_reg)next_state = WAVE;elsenext_state = FREQ;endFREQ:beginif(done_cmd_reg)next_state = WAVE;else if( cnt == freq_reg - 1 && mode_reg == 2'b01 )next_state = AMPL;else if( mode_reg == 2'b10 )next_state = AMPL;elsenext_state = cur_state;endAMPL:beginif(done_cmd_reg)next_state = WAVE;elsenext_state = DATA;endDATA:beginif(done_cmd_reg)next_state = WAVE;elsenext_state = STOP;endSTOP: beginif(done_cmd_reg)next_state = WAVE;else if( done_tx )next_state = FREQ;elsenext_state = cur_state;enddefault: next_state = IDLE;endcase
endalways @(posedge clk) beginif(!rst_n) begindata_wave2 <= 0;done_wave2 <= 0;address <= 0;cnt <= 0;q_reg <= 0;endelsecase (cur_state)IDLE:begindata_wave2 <= 0;done_wave2 <= 0;address <= 0;cnt <= 0;q_reg <= 0;endWAVE:begindata_wave2 <= 0;done_wave2 <= 0;address <= 0;cnt <= 0;q_reg <= 0;endPHAS:begin//rom起始地址address <= phas_reg;endFREQ:begincase (mode) //频率:01:隔n个地址取一次数据,10:同一个地址数据取n次01:beginaddress <= address + 1;if( cnt == freq_reg - 1 )cnt <= 0;elsecnt <= cnt + 1;end10: beginif( cnt == freq_reg - 1 ) begincnt <= 0;address <= address + 1;endelsecnt <= cnt + 1;enddefault: beginaddress <= 0;cnt <= 0;endendcaseendAMPL:beginq_reg <= q/ampl_reg;endDATA:begindata_wave2 <= q_reg;done_wave2 <= 1; //短信号endSTOP: begindata_wave2 <= 0;done_wave2 <= 0;q_reg <= 0;enddefault: begindata_wave2 <= 0;done_wave2 <= 0;address <= 0;cnt <= 0;q_reg <= 0;endendcase
end//rom2
rom2 rom2_inst (.aclr ( !rst_n ),.address ( address ),.clock ( clk ),.q ( q ));endmodule
ctrl_rom3.v
module ctrl_rom3 (
input wire clk ,
input wire rst_n ,
input wire [7:0] wave ,//波形
input wire [1:0] mode ,//01:除法( );10:乘法( )
input wire [7:0] freq ,//频率
input wire done_tx ,
input wire [7:0] phas ,//相位
input wire [7:0] ampl ,//幅值
input wire done_cmd ,//命令解析完成
output reg [7:0] data_wave3 ,
output reg done_wave3
);
//rom1
wire [7:0] q;
reg [7:0] address;
reg [7:0] q_reg ;//幅度计算寄存器//------------信号寄存---------//
reg done_cmd_reg;
reg [7:0] wave_reg;
reg [1:0] mode_reg;
reg [7:0] freq_reg;
reg [7:0] phas_reg;
reg [7:0] ampl_reg;always @(posedge clk) beginif(!rst_n) beginwave_reg <= 0;mode_reg <= 0;freq_reg <= 0;phas_reg <= 0;ampl_reg <= 0;done_cmd_reg <= 0;endelse if ( done_cmd ) beginwave_reg <= wave;mode_reg <= mode;freq_reg <= freq;phas_reg <= phas;ampl_reg <= ampl;done_cmd_reg <=done_cmd;endelsedone_cmd_reg <= 0;
end//状态机--------------------//
localparam IDLE = 7'b0000001, //等待key_outWAVE = 7'b0000010, //波形判断PHAS = 7'b0000100, //相位:rom地址起始值FREQ = 7'b0001000, //频率:01:隔n个地址取一次数据,10:同一个地址数据取n次AMPL = 7'b0010000, //计算幅值DATA = 7'b0100000, //输出波形 + doneSTOP = 7'b1000000; //等待done_tx 构成循环
reg [6:0] cur_state , next_state;
reg [3:0] cnt;//
always @(posedge clk) beginif(!rst_n)cur_state <= IDLE;elsecur_state <= next_state;
endalways @(*) beginif(!rst_n) beginnext_state = IDLE;endelsecase (cur_state)IDLE: beginif(done_cmd_reg)next_state = WAVE;elsenext_state = cur_state;endWAVE: beginif(wave_reg == 8'h03)next_state = PHAS;else if (wave_reg != 8'h03)next_state = IDLE;elsenext_state = cur_state;endPHAS:beginif(done_cmd_reg)next_state = WAVE;elsenext_state = FREQ;endFREQ:beginif(done_cmd_reg)next_state = WAVE;else if( cnt == freq_reg - 1 && mode_reg == 2'b01 )next_state = AMPL;else if( mode_reg == 2'b10 )next_state = AMPL;elsenext_state = cur_state;endAMPL:beginif(done_cmd_reg)next_state = WAVE;elsenext_state = DATA;endDATA:beginif(done_cmd_reg)next_state = WAVE;elsenext_state = STOP;endSTOP: beginif(done_cmd_reg)next_state = WAVE;else if( done_tx )next_state = FREQ;elsenext_state = cur_state;enddefault: next_state = IDLE;endcase
endalways @(posedge clk) beginif(!rst_n) begindata_wave3 <= 0;done_wave3 <= 0;address <= 0;cnt <= 0;q_reg <= 0;endelsecase (cur_state)IDLE:begindata_wave3 <= 0;done_wave3 <= 0;address <= 0;cnt <= 0;q_reg <= 0;endWAVE:begindata_wave3 <= 0;done_wave3 <= 0;address <= 0;cnt <= 0;q_reg <= 0;endPHAS:begin//rom起始地址address <= phas_reg;endFREQ:begincase (mode) //频率:01:隔n个地址取一次数据,10:同一个地址数据取n次01:beginaddress <= address + 1;if( cnt == freq_reg - 1 )cnt <= 0;elsecnt <= cnt + 1;end10: beginif( cnt == freq_reg - 1 ) begincnt <= 0;address <= address + 1;endelsecnt <= cnt + 1;enddefault: beginaddress <= 0;cnt <= 0;endendcaseendAMPL:beginq_reg <= q/ampl_reg;endDATA:begindata_wave3 <= q_reg;done_wave3 <= 1; //短信号endSTOP: begindata_wave3 <= 0;done_wave3 <= 0;q_reg <= 0;enddefault: begindata_wave3 <= 0;done_wave3 <= 0;address <= 0;cnt <= 0;q_reg <= 0;endendcase
end//rom3
rom3 rom3_inst (.aclr ( !rst_n ),.address ( address ),.clock ( clk ),.q ( q ));endmodule
ctrl_rom4.v
module ctrl_rom4 (
input wire clk ,
input wire rst_n ,
input wire [7:0] wave ,//波形
input wire [1:0] mode ,//01:除法( );10:乘法( )
input wire [7:0] freq ,//频率
input wire done_tx ,
input wire [7:0] phas ,//相位
input wire [7:0] ampl ,//幅值
input wire done_cmd ,//命令解析完成
output reg [7:0] data_wave4 ,
output reg done_wave4
);
//rom1
wire [7:0] q;
reg [7:0] address;
reg [7:0] q_reg ;//幅度计算寄存器//------------信号寄存---------//
reg done_cmd_reg;
reg [7:0] wave_reg;
reg [1:0] mode_reg;
reg [7:0] freq_reg;
reg [7:0] phas_reg;
reg [7:0] ampl_reg;always @(posedge clk) beginif(!rst_n) beginwave_reg <= 0;mode_reg <= 0;freq_reg <= 0;phas_reg <= 0;ampl_reg <= 0;done_cmd_reg <= 0;endelse if ( done_cmd ) beginwave_reg <= wave;mode_reg <= mode;freq_reg <= freq;phas_reg <= phas;ampl_reg <= ampl;done_cmd_reg <=done_cmd;endelsedone_cmd_reg <= 0;
end//状态机--------------------//
localparam IDLE = 7'b0000001, //等待key_outWAVE = 7'b0000010, //波形判断PHAS = 7'b0000100, //相位:rom地址起始值FREQ = 7'b0001000, //频率:01:隔n个地址取一次数据,10:同一个地址数据取n次AMPL = 7'b0010000, //计算幅值DATA = 7'b0100000, //输出波形 + doneSTOP = 7'b1000000; //等待done_tx 构成循环
reg [6:0] cur_state , next_state;
reg [3:0] cnt;//
always @(posedge clk) beginif(!rst_n)cur_state <= IDLE;elsecur_state <= next_state;
endalways @(*) beginif(!rst_n) beginnext_state = IDLE;endelsecase (cur_state)IDLE: beginif(done_cmd_reg)next_state = WAVE;elsenext_state = cur_state;endWAVE: beginif(wave_reg == 8'h04)next_state = PHAS;else if (wave_reg != 8'h04)next_state = IDLE;elsenext_state = cur_state;endPHAS:beginif(done_cmd_reg)next_state = WAVE;elsenext_state = FREQ;endFREQ:beginif(done_cmd_reg)next_state = WAVE;else if( cnt == freq_reg - 1 && mode_reg == 2'b01 )next_state = AMPL;else if( mode_reg == 2'b10 )next_state = AMPL;elsenext_state = cur_state;endAMPL:beginif(done_cmd_reg)next_state = WAVE;elsenext_state = DATA;endDATA:beginif(done_cmd_reg)next_state = WAVE;elsenext_state = STOP;endSTOP: beginif(done_cmd_reg)next_state = WAVE;else if( done_tx )next_state = FREQ;elsenext_state = cur_state;enddefault: next_state = IDLE;endcase
endalways @(posedge clk) beginif(!rst_n) begindata_wave4 <= 0;done_wave4 <= 0;address <= 0;cnt <= 0;q_reg <= 0;endelsecase (cur_state)IDLE:begindata_wave4 <= 0;done_wave4 <= 0;address <= 0;cnt <= 0;q_reg <= 0;endWAVE:begindata_wave4 <= 0;done_wave4 <= 0;address <= 0;cnt <= 0;q_reg <= 0;endPHAS:begin//rom起始地址address <= phas_reg;endFREQ:begincase (mode) //频率:01:隔n个地址取一次数据,10:同一个地址数据取n次01:beginaddress <= address + 1;if( cnt == freq_reg - 1 )cnt <= 0;elsecnt <= cnt + 1;end10: beginif( cnt == freq_reg - 1 ) begincnt <= 0;address <= address + 1;endelsecnt <= cnt + 1;enddefault: beginaddress <= 0;cnt <= 0;endendcaseendAMPL:beginq_reg <= q/ampl_reg;endDATA:begindata_wave4 <= q_reg;done_wave4 <= 1; //短信号endSTOP: begindata_wave4 <= 0;done_wave4 <= 0;q_reg <= 0;enddefault: begindata_wave4 <= 0;done_wave4 <= 0;address <= 0;cnt <= 0;q_reg <= 0;endendcase
end//rom4
rom4 rom4_inst (.aclr ( !rst_n ),.address ( address ),.clock ( clk ),.q ( q ));endmodule
select_wave.v
module select_wave (
input wire clk ,
input wire rst_n ,
input wire done_cmd ,//命令解析完成
input wire [7:0] wave ,//波形
input wire [7:0] data_wave1 ,
input wire done_wave1 ,
input wire [7:0] data_wave2 ,
input wire done_wave2 ,
input wire [7:0] data_wave3 ,
input wire done_wave3 ,
input wire [7:0] data_wave4 ,
input wire done_wave4 ,
output reg [7:0] data_wave ,
output reg done_wave
);
reg [7:0] wave_reg;always @(posedge clk) beginif(!rst_n)wave_reg <= 0;elsewave_reg <= wave;
endalways @(*) beginif(!rst_n) begindata_wave = 0;done_wave = 0;endelsecase (wave_reg )8'h01:beginif( done_wave1 ) begindata_wave = data_wave1;done_wave = done_wave1;endelsebegindata_wave = 0;done_wave = 0;endend8'h02: beginif( done_wave2 ) begindata_wave = data_wave2;done_wave = done_wave2;endelse begindata_wave = 0;done_wave = 0;endend8'h03: beginif( done_wave3 ) begindata_wave = data_wave3;done_wave = done_wave3;endelse begindata_wave = 0;done_wave = 0;endend8'h04: beginif( done_wave4 ) begindata_wave = data_wave4;done_wave = done_wave4;endelse begindata_wave = 0;done_wave = 0;endenddefault: begindata_wave = 0;done_wave = 0;endendcase
endendmodule
串口发送模块和按键模块可以去我的其它学习笔记找,这里就不发了。
(2)仿真代码
tb文件
`timescale 1ns/1ns
module tb();
parameter sysclk = 50_000_000 ,//系统时钟下:1sbps = 115200 , //波特率delay = sysclk / bps * 20;//1bit工作周期reg clk ;
reg rst_n ;
reg rx ;
reg key ;
wire [7:0] data_rx;
wire done_rx;
wire key_out;always #10 clk = ~clk;initial beginclk = 0;rst_n = 0;rx = 1;key = 1;#100rst_n = 1;key = 0;#200key = 1;send_data(8'hFE);#200send_data(8'h01);#200send_data(8'h01);#200send_data(8'h01);#200send_data(8'h01);#200send_data(8'h01);#200send_data(8'hee);
endtask send_data ;input [7:0] data ;
beginrx = 1;#100 //空闲rx = 0; #delay //起始位rx = data[0]; #delay //数据位 rx = data[1]; #delay //数据位rx = data[2]; #delay //数据位rx = data[3]; #delay //数据位rx = data[4]; #delay //数据位rx = data[5]; #delay //数据位rx = data[6]; #delay //数据位rx = data[7]; #delay //数据位rx = 1; #delay; //停止位
endendtaskrx rx_u(
. clk (clk ) ,
. rst_n (rst_n ) ,
. rx (rx ) ,//数据接收信号线
. data_rx (data_rx) ,//并行数据 ,其它模块用
. done_rx (done_rx) //握手信号 ,接收结束信号 , 结束成功信号
);top top_u(
. clk (clk ) ,
. rst_n (rst_n) ,
. rx (rx ) ,
. key (key ) ,
. led (led )
);key key_u(
. clk (clk ) ,
. rst_n (rst_n ) ,
. key (key ) ,
. key_out (key_out)
);endmodule
六、仿真
这里就列举波形一的,其它的,可以自己尝试尝试。
七、实验现象
波形一
波形二
波形三
波形四
以上就是简易DDS信号发生器。