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

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信号发生器。

http://www.lryc.cn/news/610648.html

相关文章:

  • pyspark中的kafka的读和写案例操作
  • RocketMq如何保证消息的顺序性
  • 基于deepSeek的流式数据自动化规则清洗案例【数据治理领域AI带来的改变】
  • SpringBoot3.x入门到精通系列:4.2 整合 Kafka 详解
  • NLP——BERT模型全面解析:从基础架构到优化演进
  • 家常菜点餐|基于java和小程序的家庭大厨家常菜点餐系统设计与实现(源码+数据库+文档)
  • 一次“无告警”的服务器宕机分析:从无迹可寻到精准定位
  • 一文掌握Bard机器翻译,以及用python调用的4种方式(现已升级为 Gemini)
  • vue3通过按钮实现横向滚动或鼠标滚动横坐标滚动
  • 用 Python 构建高质量的中文 Wikipedia 语料库:从原始 XML 到干净段落
  • 【taro react】 ---- useModel 数据双向绑定 hook 实现
  • 【乐企板式文件生成工程】关于乐企板式文件(PDF/OFD/XML)生成工程介绍
  • Taro Hooks 完整分类详解
  • wps创建编辑excel customHeight 属性不是标准 Excel Open XML导致比对异常
  • 云计算一阶段Ⅱ——11. Linux 防火墙管理
  • 《Node.js与 Elasticsearch的全文搜索架构解析》
  • Sentinel全面实战指南
  • 剑指offer第2版:字符串
  • Day34 GPU训练及类的call方法
  • Android audio之 AudioDeviceInventory
  • PCBA电子产品复制全攻略:从入门到精通
  • 【音视频】WebRTC 一对一通话-信令服
  • 强化学习_Paper_1991_Reinforcement learning is direct adaptive optimal control
  • 自然语言处理×第三卷:文本数据分析——她不再只是贴着你听,而开始学会分析你语言的结构
  • python+MySQL组合实现生成销售财务报告
  • 游戏画面总是卡顿怎么办 告别延迟畅玩游戏
  • 电脑搜索不到公司无线网络
  • 基于ARM+FPGA多通道超声信号采集与传输系统设计
  • NuGet03-私有仓库搭建
  • mac前端环境安装