目錄
一、任務
二、分析
三、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信號發生器。