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.pswp.cn/diannao/94910.shtml
繁体地址,请注明出处:http://hk.pswp.cn/diannao/94910.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

在NVIDIA Orin上用TensorRT对YOLO12进行多路加速并行推理时内存泄漏 (中)

接上篇 在NVIDIA Orin上用TensorRT对YOLO12进行多路加速并行推理时内存泄漏&#xff08;上&#xff09; 通过上篇的分析&#xff0c;发现问题在采集数据到传入GPU之前的阶段。但随着新一轮长时间测试发现&#xff0c;问题依然存在。 如上图&#xff0c;在运行20多分钟内存开始…

计数组合学7.17(Murnaghan–Nakayama 规则 )

7.17 Murnaghan–Nakayama 规则 我们已经成功地用基 mλm_\lambdamλ​、hλh_\lambdahλ​ 和 eλe_\lambdaeλ​ 表示了 Schur 函数 sλs_\lambdasλ​。本节我们将考虑幂和对称函数 pλp_\lambdapλ​。一个斜分划 λ/μ\lambda / \muλ/μ 是连通的&#xff0c;如果其分拆图…

使用 jlink 构建轻巧的自定义JRE

从 JDK 9 开始&#xff0c;Oracle JDK 和 OpenJDK 不再默认包含独立的 JRE 目录&#xff0c;而是提供了 jlink 工具&#xff08;Java 链接器&#xff09;&#xff0c;允许你根据需求自定义生成最小化的 JRE&#xff08;包含必要的模块&#xff09;。以下是使用 jlink 生成 JRE …

[IOMMU]面向芯片/SoC验证工程的IOMMU全景速览

面向芯片/SoC验证工程的IOMMU全景速览 摘要:面向芯片/SoC 验证工程的 IOMMU 全景速览:包含基础概念、主流架构要点(ARM SMMU、Intel VT‑d、RISC‑V IOMMU),Linux 软件栈关系,SoC 上的验证方法(功能、错误、性能、系统化流程和覆盖),以及一个可用的“通用 IOMM…

Jenkins全链路教程——Jenkins用户权限矩阵配置

在企业级CI/CD场景中&#xff0c;“权限混乱”往往比“构建失败”更致命——测试员误删生产流水线、实习生修改关键插件配置、多团队共用账号导致责任无法追溯……这些问题&#xff0c;99%都能用权限矩阵彻底解决&#xff01;今天&#xff0c;我们不仅会拆解权限矩阵的底层逻辑…

库函数蜂鸣器的使用(STC8)

使用库函数控制蜂鸣器&#xff08;STC8&#xff09; 在STC8系列单片机中&#xff0c;可以通过库函数或直接操作寄存器来控制蜂鸣器。以下是基于STC8库函数的常用方法&#xff1a; GPIO板蜂鸣器 #include "GPIO.h" #include "Delay.h"void GPIO_config()…

redis8.0.3部署于mac

macOS11因版本过低&#xff0c;安装redis时&#xff0c;Homebrew和源码编译两种方式都无法成功。将操作系统升级至macOS15再安装。Redis&#xff08;Remote Dictionary Server&#xff09;是一个开源的内存数据库&#xff0c;遵守 BSD 协议&#xff0c;它提供了一个高性能的键值…

【和春笋一起学C++】(三十三)名称空间的其他特性

目录 嵌套式名称空间 拓展——未命名的名称空间 嵌套式名称空间 示例代码1&#xff1a; namespace electronicEquipment {namespace computer{double price 4999.0;string modelNumber;string name;}namespace ElectronicWatch{double price 99.0;string modelNumber;stri…

异步电动机负载运行特性全解析

异步电动机负载运行特性详解 ——从空载到负载的完整分析一、为什么需要再谈“负载运行” 在上一篇《感应电动机空载特性深度剖析》中&#xff0c;我们已经看到&#xff1a;空载时&#xff0c;若定子加额定电压&#xff0c;转子转速 $n \approx n_s$&#xff08;同步转速&#…

使用 Ansys Discovery 进行动态设计和分析

Ansys Discovery 是一款多功能工具&#xff0c;为创建模型、探索仿真设计和分析解决方案提供了一个单一的交互式工作区。它允许用户使用直接建模技术创建和修改几何结构&#xff0c;定义仿真并与结果实时交互。Discovery 支持结构、流体流动、热和电磁设计&#xff0c;提供直观…

力扣热题100-----118.杨辉三角

案例 给定一个非负整数 numRows&#xff0c;生成「杨辉三角」的前 numRows 行。 在「杨辉三角」中&#xff0c;每个数是它左上方和右上方的数的和。 示例 1: 输入: numRows 5 输出: [[1],[1,1],[1,2,1],[1,3,3,1],[1,4,6,4,1]] 示例 2: 输入: numRows 1 输出: [[1]] 提示: 1 …

NTP /Chrony 网络时间协议

一、NTP&#xff08;network time protocol&#xff09;网络时间协议&#xff1a;实现时间同步&#xff0c;让设备时间与国际标准时间保持一致设备日志、服务日志需要记录时间分布式系统&#xff08;分布式数据库、分布式缓存、分布式储存、消息队列&#xff09;时间戳&#xf…

VSCode 刷 LeetCode 算法题配置教程

LeetCode 在线刷题地址&#xff1a;https://leetcode-cn.com/ 一、安装 Node.js 环境 LeetCode 插件依赖 node.js 运行环境&#xff0c;因此必须先安装&#xff1a; 前往官网下载安装&#xff1a;https://nodejs.cn/download/下载好的压缩包解压&#xff0c;可以看到当前文件…

非常简单!从零学习如何免费制作一个lofi视频

想必大家在网上会看到如下类似的音乐频道&#xff0c;这类频道都只是上传简单的Lo-Fi音乐带着循环播放的背景就可以赚钱。 那么上面的效果如何实现的呢&#xff1f;今天做一个可以免费制作lo-Fi音乐的教程。 Lo-Fi音乐&#xff1a; Lo-Fi音乐是一种以低保真度和模拟音色为特点…

基于 RAUC 的 Jetson OTA 升级全攻略

&#x1f4d6; 推荐阅读&#xff1a;《Yocto项目实战教程:高效定制嵌入式Linux系统》 &#x1f3a5; 更多学习视频请关注 B 站&#xff1a;嵌入式Jerry 基于 RAUC 的 Jetson OTA 升级全攻略 0. 引子&#xff1a;常见问题 在 Jetson 平台做 OTA 升级时&#xff0c;你可能会问&…

MySQL 主备(Master-Slave)复制 的搭建

一、主备架构简介 Master&#xff08;主库&#xff09;&#xff1a;负责处理所有写操作&#xff08;INSERT/UPDATE/DELETE&#xff09;&#xff0c;并记录二进制日志&#xff08;binlog&#xff09;。Slave&#xff08;备库&#xff09;&#xff1a;从主库拉取 binlog&#xff…

【三个数绝对值排序】2022-10-10

缘由绝对值比较&#xff0c;总是跑不过怎么办-编程语言-CSDN问答 template <class 形参> inline void 算交换(形参& a, 形参& b){ 形参 ab a - b; a - ab; b ab; } template <class 形参> void 三个升序(形参& a, 形参& b, 形参& c) {if (a…

【LoRA模型训练】Stable Diffusion LoRA 模型秋叶训练器详细教程

一、工具简介与安装指南 1.1 秋叶 LoRA 训练器概述 秋叶 LoRA 训练器&#xff08;基于 Akegarasu/lora-scripts 项目&#xff09;是针对 Stable Diffusion 模型的轻量化微调工具&#xff0c;通过低秩适应&#xff08;LoRA&#xff09;技术实现高效参数微调。其核心优势在于&a…

C++2024 年一级

1 单选题 (每题 2 分,共 30 分) 12 ⽉ 题号 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 答案 C C D B B D B C C C D C D B D 第 1 题 2024年10⽉8⽇ &#xff0c;诺贝尔物理学奖“意外地”颁给了两位计算机科学家约翰霍普菲尔德&#xff08;John J. Hopfield&#xff09;和杰 弗⾥⾟…

react-window

下面&#xff0c;我们来系统的梳理关于 React 虚拟化列表&#xff1a;react-window 的基本知识点&#xff1a;一、虚拟化列表核心概念 1.1 什么是虚拟化列表&#xff1f; 虚拟化列表&#xff08;也称为窗口化&#xff09;是一种只渲染当前可见区域列表项的技术&#xff0c;而不…