文章目录
- 一,项目介绍
-
- 1.介绍
- 二,项目原理
-
- 2.1DDS原理
- 三,项目实现
-
- 3.1项目设计
- 3.2代码解析
- 四,项目代码
-
- 4.1order_analysis
- 4.2ctrl_rom1
- 4.3rom_ctrl
- 4.4ctrl_dac
一,项目介绍
1.介绍
通过Verilog语言在FPGA开发板上实现正弦波,三角波,方波,锯齿波信号的产生,并且可以通过调频,调幅,调相来控制信号。
二,项目原理
2.1DDS原理
DDS 是直接数字式频率合成器(Direct Digital Synthesizer)的英文缩写,是一项关键的数字化技术。与传统的频率合成器相比,DDS 具有低成本、低功耗、高分辨率和快速转换时间等优点,广泛使用在电信与电子仪器领域,是实现设备全数字化的一个关键技术。作为设计人员,我们习惯称它为信号发生器,一般用它产生正弦、锯齿、方波等不同波形或不同频率的信号波形,在电子设计和测试中得到广泛应用。

三,项目实现
3.1项目设计
使用Uart协议来输入控制信号,然后根据rom来存储四种波形输出,输出的数字信号经过DAC转化变为模拟信号,最后通过示波器输出展示
3.2代码解析
一个rx来输入控制信号,order_analysis控制命令解析模块,ctrl_rom波形控制模块来控制波形的种类,相位,频率,幅度,spi_m来传输dac的控制信号,ctrl_dac来控制dac转化
四,项目代码
4.1order_analysis
module order_analysis (
input clk ,
input rst_n ,
input [7:0] data_rx ,
input done_rx ,
output [7:0] wave ,
output [7:0] phas ,
output [7:0] freq ,
output [7:0] ampl ,
output done_cmd
);
localparam IDLE=1,
WAVA=2,
PHAS=3,
FREQ=4,
AMPL=5,
STOP=6;
reg [7:0] wave_reg;
reg [7:0] phas_reg;
reg [7:0] freq_reg;
reg [7:0] ampl_reg;
reg [3:0] c_state,n_state;
always @(posedge clk or negedge rst_n ) begin
if(!rst_n)
c_state<=IDLE;
else
c_state<=n_state;
end
always @(*) begin
if(!rst_n)
n_state=IDLE;
else
case (c_state)
IDLE:begin
if(done_rx&&data_rx==8'hfe)
n_state=WAVA;
else
n_state=c_state;
end
WAVA:begin
if(done_rx)
n_state=PHAS;
else
n_state=c_state;
end
PHAS:begin
if(done_rx)
n_state=FREQ;
else
n_state=c_state;
end
FREQ:begin
if(done_rx)
n_state=AMPL;
else
n_state=c_state;
end
AMPL:begin
if(done_rx)
n_state=STOP;
else
n_state=c_state;
end
STOP:n_state=IDLE;
default:n_state=IDLE;
endcase
end
always @(posedge clk or negedge rst_n) begin
if(!rst_n)begin
wave_reg<=0;
phas_reg<=0;
freq_reg<=0;
ampl_reg<=0;
end
else
case (c_state)
IDLE:begin
wave_reg<=wave_reg;
phas_reg<=phas_reg;
freq_reg<=freq_reg;
ampl_reg<=ampl_reg;
end
WAVA:begin
if(done_rx)
wave_reg<=data_rx;
phas_reg<=0;
freq_reg<=0;
ampl_reg<=0;
end
PHAS:begin
if(done_rx)
phas_reg<=data_rx;
freq_reg<=0;
ampl_reg<=0;
end
FREQ:begin
if(done_rx)
freq_reg<=data_rx;
ampl_reg<=0;
end
AMPL:begin
if(done_rx&&done_rx!=8'hee)
ampl_reg<=data_rx;
end
STOP:;
default: begin
wave_reg<=0;
phas_reg<=0;
freq_reg<=0;
ampl_reg<=0;
end
endcase
end
assign done_cmd=(c_state==STOP)?1:0;
assign wave =wave_reg;
assign phas =phas_reg;
assign freq =freq_reg;
assign ampl =ampl_reg;
endmodule
4.2ctrl_rom1
module ctrl_rom1 (
input clk ,
input rst_n ,
input [7:0] wave ,
input [7:0] phas ,
input [7:0] freq ,
input [7:0] ampl ,
input done_tx ,
input done_cmd,
output vali1 ,
output [7:0] data_tx1
);
localparam IDLE=1,
FLAG=2,
WAVA=3,
PHAS=4,
FREQ=5,
AMPL=6,
DATA=7,
WAIT=8;
reg [3:0] c_state,n_state;
reg [3:0] cnt_freq;
reg [7:0] wave_reg;
reg [7:0] phas_reg;
reg [7:0] freq_reg;
reg [7:0] ampl_reg;
reg [7:0] data_reg;
reg [9:0] address;
wire[7:0] q;
always @(posedge clk or negedge rst_n ) begin
if(!rst_n)
c_state<=IDLE;
else
c_state<=n_state;
end
always @(*) begin
if(!rst_n)
n_state=IDLE;
else
case (c_state)
IDLE:begin
if(done_cmd)
n_state=FLAG;
else
n_state=c_state;
end
FLAG:begin
n_state=WAVA;
end
WAVA:begin
if(done_cmd)
n_state=FLAG;
else
if(wave_reg!=8'h01)
n_state=IDLE;
else
n_state=PHAS;
end
PHAS:begin
if(done_cmd)
n_state=FLAG;
else
n_state=FREQ;
end
FREQ:begin
if(done_cmd)
n_state=FLAG;
else if((freq_reg[4]==0&&cnt_freq==freq_reg[3:0]-1)||freq_reg[4]==1)
n_state=AMPL;
else
n_state=c_state;
end
AMPL:begin
if(done_cmd)
n_state=FLAG;
else
n_state=DATA;
end
DATA:begin
if(done_cmd)
n_state=FLAG;
else
n_state=WAIT;
end
WAIT:begin
if(done_cmd)
n_state=FLAG;
else if(done_tx)
n_state=FREQ;
else
n_state=WAIT;
end
default: n_state=IDLE;
endcase
end
always @(posedge clk or negedge rst_n) begin
if(!rst_n)begin
wave_reg<=0;
phas_reg<=0;
freq_reg<=0;
ampl_reg<=0;
data_reg<=0;
address <=0;
cnt_freq<=0;
end
else
case (c_state)
IDLE:begin
wave_reg<=0;
phas_reg<=0;
freq_reg<=0;
ampl_reg<=0;
data_reg<=0;
address <=0;
cnt_freq<=0;
end
FLAG:begin
wave_reg<=wave;
phas_reg<=phas;
freq_reg<=freq;
ampl_reg<=ampl;
data_reg<=0;
address <=0;
cnt_freq<=0;
end
WAVA:begin
wave_reg<=wave_reg;
phas_reg<=phas_reg;
freq_reg<=freq_reg;
ampl_reg<=ampl_reg;
data_reg<=0;
address <=0;
cnt_freq<=0;
end
PHAS:
begin
data_reg<=0;
address <=phas;
cnt_freq<=0;
end
FREQ:begin
address<=address+1;
data_reg<=data_reg;
if(cnt_freq==freq_reg[3:0]-1)
cnt_freq<=0;
else
cnt_freq<=cnt_freq+1;
end
AMPL:begin
cnt_freq<=cnt_freq;
data_reg<=q/ampl_reg;
address<=address;
end
DATA:;
WAIT:;
default: begin
wave_reg<=0;
phas_reg<=0;
freq_reg<=0;
ampl_reg<=0;
data_reg<=0;
address <=0;
end
endcase
end
rom_waverom_wave_rom1 (
.aclr ( !rst_n ),
.address ( address ),
.clock ( clk ),
.q ( q )
);
assign data_tx1=data_reg;
assign vali1=(c_state==DATA)?1:0;
endmodule
4.3rom_ctrl
module rom_ctrl (
input clk ,
input rst_n ,
input [7:0] wave ,
input vali1 ,
input [7:0] data_tx1,
input vali2 ,
input [7:0] data_tx2,
input vali3 ,
input [7:0] data_tx3,
input vali4 ,
input [7:0] data_tx4,
output reg vali ,
output reg [7:0] data_tx
);
always @(posedge clk or negedge rst_n ) begin
if(!rst_n) begin
vali <= 0;
data_tx<= 0;
end
else begin
case (wave)
8'd1: begin vali <= vali1; data_tx <= data_tx1; end
8'd2: begin vali <= vali2; data_tx <= data_tx2; end
8'd3: begin vali <= vali3; data_tx <= data_tx3; end
8'd4: begin vali <= vali4; data_tx <= data_tx4; end
default: begin vali <= 0; data_tx <= 0; end
endcase
end
end
endmodule
4.4ctrl_dac
module ctrl_dac(
input clk ,
input rst_n ,
input vali ,
input [7:0] data_tx ,
input done_w ,
input done_spi ,
output start_spi_dac,
output [7:0] data_in_dac ,//输入数据
output [7:0] data_len_dac ,//总字节长度
output [7:0] wt_len_dac ,//写入字节长度
output done_dac
);
reg [15:0] data_reg;
reg start_reg;
reg [7:0] data_in_reg;
localparam IDLE = 1,
START= 2,
DATA1= 3,
DATA2= 4,
STOP = 5;
reg [2:0] c_state,
n_state;
assign start_spi_dac=start_reg ;
assign data_in_dac =data_in_reg;
assign data_len_dac =2;
assign wt_len_dac =2;
assign done_dac=(c_state==STOP&&done_spi)?1:0;
always @(posedge clk or negedge rst_n) begin
if(!rst_n)
c_state<=IDLE;
else
c_state<=n_state;
end
always @(*) begin
if(!rst_n)
n_state=IDLE;
else
case (c_state)
IDLE :n_state=START;
START:begin
if(vali)
n_state=DATA1;
else
n_state=c_state;
end
DATA1:begin
if(done_w)
n_state=DATA2;
else
n_state=c_state;
end
DATA2:begin
if(done_w)
n_state=STOP;
else
n_state=c_state;
end
STOP :begin
if(done_spi)
n_state=IDLE;
else
n_state=c_state;
end
default: n_state=IDLE;
endcase
end
always @(posedge clk or negedge rst_n) begin
if(!rst_n)begin
data_reg <=0;
start_reg <=0;
data_in_reg <=0;
end
else
case (c_state)
IDLE :begin
data_reg <=0;
start_reg <=0;
data_in_reg <=0;
end
START:begin
data_reg <={4'b0,data_tx[7:0],4'b0};
start_reg <=0;
data_in_reg <=0;
end
DATA1:begin
data_reg <=data_reg;
start_reg <=1;
data_in_reg <=data_reg[15:8];
end
DATA2:begin
data_reg <=data_reg;
start_reg <=0;
data_in_reg <=data_reg[7:0];
end
STOP :begin
data_reg <=0;
start_reg <=0;
data_in_reg <=0;
end
default:begin
data_reg <=0;
start_reg <=0;
data_in_reg <=0;
end
endcase
end
endmodule
网硕互联帮助中心

评论前必须登录!
注册