对于高速ADC采样,可以使用可编程逻辑器件,以有限状态机的方式进行设计。要设计控制AD采样模块的有限状态机,首先要了解其工作时序,然后根据工作时序,画出状态转移图,并用Verilog HDL实现。下图是ADC0809的转换时序图。
ADC0809是一个8通道输入的ADC,ADDA、ADDB及ADDC是八路输入IN0~IN7的选择信号;端口ALE为模拟信号输入选通端口地址锁存信号,上升沿有效;START为转换启动信号,高电平有效。当START有效后,转换信号EOC立即变为低电平,表示正在进行ADC转换,转换时间为100us;转换结束后,EOC变为高电平;控制器根据EOC信号了解转换状态;控制器可以通过控制输出使能端OE,通过8位并行数据总线D[7:0]来读取转换 定义:初始化状态S0、启动ADC状态S1、等待ADC转换结束状态S2、 转换数据读取状态S3;以上状态转换在时钟上升沿变化;在S2状态下,根据EOC的不同转向不同状态;
模块代码:
module adc0809 (
input clk, reset,//状态机工作时钟和系统复位控制
input eoc, //AADC转换启动信号和转换结束标志信号
input [7:0] data,//来自ADC的数据总线
output reg start,
output [2:0] addr,//ADC输入通道选择地址
output reg ale,//模拟通道地址输入锁存信号
output reg oe //ADC数据输出使能
) ;
localparam[ 1: 0 ] //定义各状态
s0 = 2'b00 ,
s1 = 2'b01 ,
s2 = 2'b10,
s3 = 2'b11;
reg [ 1:0 ] state_reg , state_next ; // 状态声明
// 状态转移
always @ (posedge clk , negedge reset )
if ( !reset )
state_reg <= s0 ;
else
state_reg <= state_next ;
assign addr = 3'b001; //输入通道设定为通道0
// 次态逻辑和输出逻辑
always @*
begin
case( state_reg )
s0 : state_next = s1;
s1 : state_next = s2;
s2 :
if (eoc == 1'b1) state_next = s3; //转换结束
else state_next = s2; //转换未结束,继续等待
s3 :
state_next = s0;
endcase
end
always @*
begin
case( state_reg )
s0 :
begin ale = 0; start = 0;oe = 0; end
s1 :
begin ale = 1; start = 1;oe = 0; end
s2 :
begin ale = 0; start = 0;oe = 0; end
s3 :
begin ale = 0; start = 0;oe = 1; end
endcase
end
endmodule
激励仿真代码
`include "adc0809.v"
module adc0809_tb( );
reg clk,reset; //状态机工作时钟和系统复位控制
reg eoc; //AADC转换启动信号和转换结束标志信号
reg [7:0] data; //来自ADC的数据总线
wire start;
wire [2:0] addr; //ADC输入通道选择地址
wire ale; //模拟通道地址输入锁存信号
wire oe; //ADC数据输出使能
// 调用adc0809模块
adc0809 u1(
.clk(clk),
.reset(reset),
.eoc(eoc),
.data(data),
.start(start),
.addr(addr),
.ale(ale),
.oe(oe)
);
parameter period=10;
initial begin
data=8'b10101101;
clk = 1'b0;
reset = 1'b0;
eoc = 1'b1;
#10 reset = 1'b1;
end
//当adc0809模块拉高start信号,仿真激励开始拉低eoc信号并延时一段时间重新拉高eoc
always @(posedge start)
begin
eoc <= 1'b0;
#40 eoc <= 1'b1;
end
// 生成占空比50%的时钟波形
always #(period/2) clk = ~clk;