当前位置: 首页 > ops >正文

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次2'b01:beginaddress <= address + 1;if( cnt == freq_reg - 1 )cnt <= 0;elsecnt <= cnt + 1;end2'b10: 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次2'b01:beginaddress <= address + 1;if( cnt == freq_reg - 1 )cnt <= 0;elsecnt <= cnt + 1;end2'b10: 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次2'b01:beginaddress <= address + 1;if( cnt == freq_reg - 1 )cnt <= 0;elsecnt <= cnt + 1;end2'b10: 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次2'b01:beginaddress <= address + 1;if( cnt == freq_reg - 1 )cnt <= 0;elsecnt <= cnt + 1;end2'b10: 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信号发生器。

http://www.xdnf.cn/news/17046.html

相关文章:

  • Cisco 3750X交换机更新到IOS 15.2后无法启动 提示:Boot process failed...
  • 内部排序算法总结(考研向)
  • VS2019c++环境下OPCUA+Kepserver+open62541实现与三菱plc通信
  • 机器学习Adaboost算法----SAMME算法和SAMME.R算法
  • 【2025年8月5日】将运行一段时间的单机MongoDB平滑迁移至副本集集群
  • LeetCode算法日记 - Day 2: 快乐数、盛水最多容器
  • 计算机常用英语词汇大全
  • 【unitrix】1.1 readme.md
  • Erdős–Rényi (ER) 模型
  • Android10 系统休眠调试相关
  • 文件编译、调试及库制作
  • 视频水印技术中的变换域嵌入方法对比分析
  • 从 “看懂图” 到 “读懂视频”:多模态技术如何用文本反哺视觉?
  • FPGA实现Aurora 8B10B视频点对点传输,基于GTP高速收发器,提供4套工程源码和技术支持
  • RC和RR的区别
  • 关于npx react-native run-android下载进程缓慢以及进程卡壳等问题的解决方案。
  • iouring系统调用及示例
  • 16核32G硬件服务器租用需要多少钱
  • 【安卓][Mac/Windows】永久理论免费 无限ip代理池 - 适合临时快速作战
  • 【数字图像处理系列笔记】Ch01:绪论
  • Vue2项目—基于路由守卫实现钉钉小程序动态更新标题
  • 20250805
  • GitCode新手使用教程
  • 初学docker
  • 基于k8s环境下的pulsar常用命令(上)
  • 【Lua】题目小练8
  • nflsoi 8.2 题解
  • Druid与JdbcTemplate基本使用
  • vscode 关闭自动更新
  • 从达梦到 StarRocks:国产数据库实时入仓实践