目录
[三、ROM IP核配置](#三、ROM IP核配置)
一、任务
用串口模块,用上位机发送指令,FPGA接收,然后输出对应的波形;其中指令用FE+波形+类型+频率+相位+幅度+EE。
波形:选择哪个波形
类型:频率缩小还是放大
二、分析
首先要有串口模块rx和tx,还要有四个单端口ROM模块,分别存储四种不同的波形,然后还要对指令处理的模块,将处理后的指令给各个模块使用。
三、ROM IP核配置

四、Visio图

这里我就用RTL Viewer代替了。
五、代码
(1).v代码
top.v
cpp
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
cpp
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) begin
if(!rst_n)
cur_state <= IDLE;
else
cur_state <= next_state;
end
always @(*) begin
if(!rst_n)
next_state = IDLE;
else
case (cur_state)
IDLE :begin
if(key_out)
next_state = START;
else
next_state = cur_state;
end
START:begin //包头
if( data_rx == 8'hFE && done_rx )
next_state = WAVE;
else if( data_rx != 8'hFE && done_rx )
next_state = IDLE;
else
next_state = cur_state;
end
WAVE :begin //波形
if( done_rx )
next_state = MODE;
else
next_state = cur_state;
end
MODE :begin //
if( done_rx )
next_state = FREQ;
else
next_state = cur_state;
end
FREQ :begin //
if( done_rx )
next_state = PHAS;
else
next_state = cur_state;
end
PHAS :begin //
if( done_rx )
next_state = AMPL;
else
next_state = cur_state;
end
AMPL :begin //
if( done_rx )
next_state = STOP;
else
next_state = cur_state;
end
STOP : begin //包尾
if( done_rx && data_rx == 8'hEE)
next_state = START;
else if(done_rx && data_rx != 8'hEE)
next_state = IDLE;
else
next_state = cur_state;
end
default: next_state = IDLE;
endcase
end
always @(posedge clk) begin
if(!rst_n) begin
led <= 0;
wave <= 0;
mode <= 0;
freq <= 0;
phas <= 0;
ampl <= 0;
done_cmd <= 0;
end
else
case (cur_state)
IDLE :begin
led <= 1;
wave <= 0;
mode <= 0;
freq <= 0;
phas <= 0;
ampl <= 0;
done_cmd <= 0;
end
START:begin
led <= 0;
wave <= wave ;
mode <= mode ;
freq <= freq ;
phas <= phas ;
ampl <= ampl ;
done_cmd <= 0;
end
WAVE :begin
if(done_rx)
wave <= data_rx;
end
MODE :begin
if(done_rx)
mode <= data_rx;
end
FREQ :begin
if(done_rx)
freq <= data_rx;
end
PHAS :begin
if(done_rx)
phas <= data_rx;
end
AMPL :begin
if(done_rx)
ampl <= data_rx;
end
STOP : begin
if(done_rx && data_rx == 8'hEE)
done_cmd <= 1;
else
done_cmd <= 0;
end
default: begin
led <= 0;
wave <= 0;
mode <= 0;
freq <= 0;
phas <= 0;
ampl <= 0;
done_cmd <= 0;
end
endcase
end
endmodule
ctrl_rom1.v
cpp
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) begin
if(!rst_n) begin
wave_reg <= 0;
mode_reg <= 0;
freq_reg <= 0;
phas_reg <= 0;
ampl_reg <= 0;
done_cmd_reg <= 0;
end
else if ( done_cmd ) begin
wave_reg <= wave;
mode_reg <= mode;
freq_reg <= freq;
phas_reg <= phas;
ampl_reg <= ampl;
done_cmd_reg <=done_cmd;
end
else
done_cmd_reg <= 0;
end
//状态机--------------------//
localparam IDLE = 7'b0000001, //等待key_out
WAVE = 7'b0000010, //波形判断
PHAS = 7'b0000100, //相位:rom地址起始值
FREQ = 7'b0001000, //频率:01:隔n个地址取一次数据,10:同一个地址数据取n次
AMPL = 7'b0010000, //计算幅值
DATA = 7'b0100000, //输出波形 + done
STOP = 7'b1000000; //等待done_tx 构成循环
reg [6:0] cur_state , next_state;
reg [3:0] cnt;
//
always @(posedge clk) begin
if(!rst_n)
cur_state <= IDLE;
else
cur_state <= next_state;
end
always @(*) begin
if(!rst_n) begin
next_state = IDLE;
end
else
case (cur_state)
IDLE: begin
if(done_cmd_reg)
next_state = WAVE;
else
next_state = cur_state;
end
WAVE: begin
if(wave_reg == 8'h01)
next_state = PHAS;
else if (wave_reg != 8'h01)
next_state = IDLE;
else
next_state = cur_state;
end
PHAS:begin
if(done_cmd_reg)
next_state = WAVE;
else
next_state = FREQ;
end
FREQ:begin
if(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;
else
next_state = cur_state;
end
AMPL:begin
if(done_cmd_reg)
next_state = WAVE;
else
next_state = DATA;
end
DATA:begin
if(done_cmd_reg)
next_state = WAVE;
else
next_state = STOP;
end
STOP: begin
if(done_cmd_reg)
next_state = WAVE;
else if( done_tx )
next_state = FREQ;
else
next_state = cur_state;
end
default: next_state = IDLE;
endcase
end
always @(posedge clk) begin
if(!rst_n) begin
data_wave1 <= 0;
done_wave1 <= 0;
address <= 0;
cnt <= 0;
q_reg <= 0;
end
else
case (cur_state)
IDLE:begin
data_wave1 <= 0;
done_wave1 <= 0;
address <= 0;
cnt <= 0;
q_reg <= 0;
end
WAVE:begin
data_wave1 <= 0;
done_wave1 <= 0;
address <= 0;
cnt <= 0;
q_reg <= 0;
end
PHAS:begin//rom起始地址
address <= phas_reg;
end
FREQ:begin
case (mode) //频率:01:隔n个地址取一次数据,10:同一个地址数据取n次
2'b01:begin
address <= address + 1;
if( cnt == freq_reg - 1 )
cnt <= 0;
else
cnt <= cnt + 1;
end
2'b10: begin
if( cnt == freq_reg - 1 ) begin
cnt <= 0;
address <= address + 1;
end
else
cnt <= cnt + 1;
end
default: begin
address <= 0;
cnt <= 0;
end
endcase
end
AMPL:begin
q_reg <= q/ampl_reg;
end
DATA:begin
data_wave1 <= q_reg;
done_wave1 <= 1; //短信号
end
STOP: begin
data_wave1 <= 0;
done_wave1 <= 0;
q_reg <= 0;
end
default: begin
data_wave1 <= 0;
done_wave1 <= 0;
address <= 0;
cnt <= 0;
q_reg <= 0;
end
endcase
end
//rom1
rom1 rom1_inst (
.aclr ( !rst_n ),
.address ( address ),
.clock ( clk ),
.q ( q )
);
endmodule
ctrl_rom2.v
cpp
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) begin
if(!rst_n) begin
wave_reg <= 0;
mode_reg <= 0;
freq_reg <= 0;
phas_reg <= 0;
ampl_reg <= 0;
done_cmd_reg <= 0;
end
else if ( done_cmd ) begin
wave_reg <= wave;
mode_reg <= mode;
freq_reg <= freq;
phas_reg <= phas;
ampl_reg <= ampl;
done_cmd_reg <=done_cmd;
end
else
done_cmd_reg <= 0;
end
//状态机--------------------//
localparam IDLE = 7'b0000001, //等待key_out
WAVE = 7'b0000010, //波形判断
PHAS = 7'b0000100, //相位:rom地址起始值
FREQ = 7'b0001000, //频率:01:隔n个地址取一次数据,10:同一个地址数据取n次
AMPL = 7'b0010000, //计算幅值
DATA = 7'b0100000, //输出波形 + done
STOP = 7'b1000000; //等待done_tx 构成循环
reg [6:0] cur_state , next_state;
reg [3:0] cnt;
//
always @(posedge clk) begin
if(!rst_n)
cur_state <= IDLE;
else
cur_state <= next_state;
end
always @(*) begin
if(!rst_n) begin
next_state = IDLE;
end
else
case (cur_state)
IDLE: begin
if(done_cmd_reg)
next_state = WAVE;
else
next_state = cur_state;
end
WAVE: begin
if(wave_reg == 8'h02)
next_state = PHAS;
else if (wave_reg != 8'h02)
next_state = IDLE;
else
next_state = cur_state;
end
PHAS:begin
if(done_cmd_reg)
next_state = WAVE;
else
next_state = FREQ;
end
FREQ:begin
if(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;
else
next_state = cur_state;
end
AMPL:begin
if(done_cmd_reg)
next_state = WAVE;
else
next_state = DATA;
end
DATA:begin
if(done_cmd_reg)
next_state = WAVE;
else
next_state = STOP;
end
STOP: begin
if(done_cmd_reg)
next_state = WAVE;
else if( done_tx )
next_state = FREQ;
else
next_state = cur_state;
end
default: next_state = IDLE;
endcase
end
always @(posedge clk) begin
if(!rst_n) begin
data_wave2 <= 0;
done_wave2 <= 0;
address <= 0;
cnt <= 0;
q_reg <= 0;
end
else
case (cur_state)
IDLE:begin
data_wave2 <= 0;
done_wave2 <= 0;
address <= 0;
cnt <= 0;
q_reg <= 0;
end
WAVE:begin
data_wave2 <= 0;
done_wave2 <= 0;
address <= 0;
cnt <= 0;
q_reg <= 0;
end
PHAS:begin//rom起始地址
address <= phas_reg;
end
FREQ:begin
case (mode) //频率:01:隔n个地址取一次数据,10:同一个地址数据取n次
2'b01:begin
address <= address + 1;
if( cnt == freq_reg - 1 )
cnt <= 0;
else
cnt <= cnt + 1;
end
2'b10: begin
if( cnt == freq_reg - 1 ) begin
cnt <= 0;
address <= address + 1;
end
else
cnt <= cnt + 1;
end
default: begin
address <= 0;
cnt <= 0;
end
endcase
end
AMPL:begin
q_reg <= q/ampl_reg;
end
DATA:begin
data_wave2 <= q_reg;
done_wave2 <= 1; //短信号
end
STOP: begin
data_wave2 <= 0;
done_wave2 <= 0;
q_reg <= 0;
end
default: begin
data_wave2 <= 0;
done_wave2 <= 0;
address <= 0;
cnt <= 0;
q_reg <= 0;
end
endcase
end
//rom2
rom2 rom2_inst (
.aclr ( !rst_n ),
.address ( address ),
.clock ( clk ),
.q ( q )
);
endmodule
ctrl_rom3.v
cpp
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) begin
if(!rst_n) begin
wave_reg <= 0;
mode_reg <= 0;
freq_reg <= 0;
phas_reg <= 0;
ampl_reg <= 0;
done_cmd_reg <= 0;
end
else if ( done_cmd ) begin
wave_reg <= wave;
mode_reg <= mode;
freq_reg <= freq;
phas_reg <= phas;
ampl_reg <= ampl;
done_cmd_reg <=done_cmd;
end
else
done_cmd_reg <= 0;
end
//状态机--------------------//
localparam IDLE = 7'b0000001, //等待key_out
WAVE = 7'b0000010, //波形判断
PHAS = 7'b0000100, //相位:rom地址起始值
FREQ = 7'b0001000, //频率:01:隔n个地址取一次数据,10:同一个地址数据取n次
AMPL = 7'b0010000, //计算幅值
DATA = 7'b0100000, //输出波形 + done
STOP = 7'b1000000; //等待done_tx 构成循环
reg [6:0] cur_state , next_state;
reg [3:0] cnt;
//
always @(posedge clk) begin
if(!rst_n)
cur_state <= IDLE;
else
cur_state <= next_state;
end
always @(*) begin
if(!rst_n) begin
next_state = IDLE;
end
else
case (cur_state)
IDLE: begin
if(done_cmd_reg)
next_state = WAVE;
else
next_state = cur_state;
end
WAVE: begin
if(wave_reg == 8'h03)
next_state = PHAS;
else if (wave_reg != 8'h03)
next_state = IDLE;
else
next_state = cur_state;
end
PHAS:begin
if(done_cmd_reg)
next_state = WAVE;
else
next_state = FREQ;
end
FREQ:begin
if(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;
else
next_state = cur_state;
end
AMPL:begin
if(done_cmd_reg)
next_state = WAVE;
else
next_state = DATA;
end
DATA:begin
if(done_cmd_reg)
next_state = WAVE;
else
next_state = STOP;
end
STOP: begin
if(done_cmd_reg)
next_state = WAVE;
else if( done_tx )
next_state = FREQ;
else
next_state = cur_state;
end
default: next_state = IDLE;
endcase
end
always @(posedge clk) begin
if(!rst_n) begin
data_wave3 <= 0;
done_wave3 <= 0;
address <= 0;
cnt <= 0;
q_reg <= 0;
end
else
case (cur_state)
IDLE:begin
data_wave3 <= 0;
done_wave3 <= 0;
address <= 0;
cnt <= 0;
q_reg <= 0;
end
WAVE:begin
data_wave3 <= 0;
done_wave3 <= 0;
address <= 0;
cnt <= 0;
q_reg <= 0;
end
PHAS:begin//rom起始地址
address <= phas_reg;
end
FREQ:begin
case (mode) //频率:01:隔n个地址取一次数据,10:同一个地址数据取n次
2'b01:begin
address <= address + 1;
if( cnt == freq_reg - 1 )
cnt <= 0;
else
cnt <= cnt + 1;
end
2'b10: begin
if( cnt == freq_reg - 1 ) begin
cnt <= 0;
address <= address + 1;
end
else
cnt <= cnt + 1;
end
default: begin
address <= 0;
cnt <= 0;
end
endcase
end
AMPL:begin
q_reg <= q/ampl_reg;
end
DATA:begin
data_wave3 <= q_reg;
done_wave3 <= 1; //短信号
end
STOP: begin
data_wave3 <= 0;
done_wave3 <= 0;
q_reg <= 0;
end
default: begin
data_wave3 <= 0;
done_wave3 <= 0;
address <= 0;
cnt <= 0;
q_reg <= 0;
end
endcase
end
//rom3
rom3 rom3_inst (
.aclr ( !rst_n ),
.address ( address ),
.clock ( clk ),
.q ( q )
);
endmodule
ctrl_rom4.v
cpp
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) begin
if(!rst_n) begin
wave_reg <= 0;
mode_reg <= 0;
freq_reg <= 0;
phas_reg <= 0;
ampl_reg <= 0;
done_cmd_reg <= 0;
end
else if ( done_cmd ) begin
wave_reg <= wave;
mode_reg <= mode;
freq_reg <= freq;
phas_reg <= phas;
ampl_reg <= ampl;
done_cmd_reg <=done_cmd;
end
else
done_cmd_reg <= 0;
end
//状态机--------------------//
localparam IDLE = 7'b0000001, //等待key_out
WAVE = 7'b0000010, //波形判断
PHAS = 7'b0000100, //相位:rom地址起始值
FREQ = 7'b0001000, //频率:01:隔n个地址取一次数据,10:同一个地址数据取n次
AMPL = 7'b0010000, //计算幅值
DATA = 7'b0100000, //输出波形 + done
STOP = 7'b1000000; //等待done_tx 构成循环
reg [6:0] cur_state , next_state;
reg [3:0] cnt;
//
always @(posedge clk) begin
if(!rst_n)
cur_state <= IDLE;
else
cur_state <= next_state;
end
always @(*) begin
if(!rst_n) begin
next_state = IDLE;
end
else
case (cur_state)
IDLE: begin
if(done_cmd_reg)
next_state = WAVE;
else
next_state = cur_state;
end
WAVE: begin
if(wave_reg == 8'h04)
next_state = PHAS;
else if (wave_reg != 8'h04)
next_state = IDLE;
else
next_state = cur_state;
end
PHAS:begin
if(done_cmd_reg)
next_state = WAVE;
else
next_state = FREQ;
end
FREQ:begin
if(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;
else
next_state = cur_state;
end
AMPL:begin
if(done_cmd_reg)
next_state = WAVE;
else
next_state = DATA;
end
DATA:begin
if(done_cmd_reg)
next_state = WAVE;
else
next_state = STOP;
end
STOP: begin
if(done_cmd_reg)
next_state = WAVE;
else if( done_tx )
next_state = FREQ;
else
next_state = cur_state;
end
default: next_state = IDLE;
endcase
end
always @(posedge clk) begin
if(!rst_n) begin
data_wave4 <= 0;
done_wave4 <= 0;
address <= 0;
cnt <= 0;
q_reg <= 0;
end
else
case (cur_state)
IDLE:begin
data_wave4 <= 0;
done_wave4 <= 0;
address <= 0;
cnt <= 0;
q_reg <= 0;
end
WAVE:begin
data_wave4 <= 0;
done_wave4 <= 0;
address <= 0;
cnt <= 0;
q_reg <= 0;
end
PHAS:begin//rom起始地址
address <= phas_reg;
end
FREQ:begin
case (mode) //频率:01:隔n个地址取一次数据,10:同一个地址数据取n次
2'b01:begin
address <= address + 1;
if( cnt == freq_reg - 1 )
cnt <= 0;
else
cnt <= cnt + 1;
end
2'b10: begin
if( cnt == freq_reg - 1 ) begin
cnt <= 0;
address <= address + 1;
end
else
cnt <= cnt + 1;
end
default: begin
address <= 0;
cnt <= 0;
end
endcase
end
AMPL:begin
q_reg <= q/ampl_reg;
end
DATA:begin
data_wave4 <= q_reg;
done_wave4 <= 1; //短信号
end
STOP: begin
data_wave4 <= 0;
done_wave4 <= 0;
q_reg <= 0;
end
default: begin
data_wave4 <= 0;
done_wave4 <= 0;
address <= 0;
cnt <= 0;
q_reg <= 0;
end
endcase
end
//rom4
rom4 rom4_inst (
.aclr ( !rst_n ),
.address ( address ),
.clock ( clk ),
.q ( q )
);
endmodule
select_wave.v
cpp
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) begin
if(!rst_n)
wave_reg <= 0;
else
wave_reg <= wave;
end
always @(*) begin
if(!rst_n) begin
data_wave = 0;
done_wave = 0;
end
else
case (wave_reg )
8'h01:begin
if( done_wave1 ) begin
data_wave = data_wave1;
done_wave = done_wave1;
end
else
begin
data_wave = 0;
done_wave = 0;
end
end
8'h02: begin
if( done_wave2 ) begin
data_wave = data_wave2;
done_wave = done_wave2;
end
else begin
data_wave = 0;
done_wave = 0;
end
end
8'h03: begin
if( done_wave3 ) begin
data_wave = data_wave3;
done_wave = done_wave3;
end
else begin
data_wave = 0;
done_wave = 0;
end
end
8'h04: begin
if( done_wave4 ) begin
data_wave = data_wave4;
done_wave = done_wave4;
end
else begin
data_wave = 0;
done_wave = 0;
end
end
default: begin
data_wave = 0;
done_wave = 0;
end
endcase
end
endmodule
串口发送模块和按键模块可以去我的其它学习笔记找,这里就不发了。
(2)仿真代码
tb文件
cpp
`timescale 1ns/1ns
module tb();
parameter sysclk = 50_000_000 ,//系统时钟下:1s
bps = 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 begin
clk = 0;
rst_n = 0;
rx = 1;
key = 1;
#100
rst_n = 1;
key = 0;
#200
key = 1;
send_data(8'hFE);
#200
send_data(8'h01);
#200
send_data(8'h01);
#200
send_data(8'h01);
#200
send_data(8'h01);
#200
send_data(8'h01);
#200
send_data(8'hee);
end
task send_data ;
input [7:0] data ;
begin
rx = 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; //停止位
end
endtask
rx 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信号发生器。