本帖最后由 jlgcumt 于 2013-3-12 23:56 编辑
//////////////////////////////////FSM///////////////////////////////////////
// 状态转换
always @ (posedge sys_clk or negedge rst_n)
begin
if(!rst_n)
cstate_ad <= 0;
else
cstate_ad <= nstate_ad;
end
// 下一状态生成
always @ (*)
begin
if(!rst_n)
begin
nstate_ad = 0;
end
else
begin
case(cstate_ad)
4'd0: // 判断当前ad是否使能,使能的话进入下一状态开始启动采集
begin
if(ADEn)
nstate_ad = 4'd1;
else
nstate_ad = 4'd0;
end
4'd1: // 此状态和下一状态用于AD7606采集的转换启动信号
begin
nstate_ad = 4'd2;
end
4'd2:
begin
nstate_ad = 4'd3;
end
4'd3: // 等待125ns,在启动信号和Busy信号有效之间延时最大为40ns(手册要求)
begin
nstate_ad = 4'd4;
end
4'd4:
begin
nstate_ad = 4'd5;
end
4'd5:
if(ad_busy) // 转换正在进行中
begin
nstate_ad = 4'd5;
end
else // 转换完成
begin
nstate_ad = 4'd6;
end
4'd6: // 开始采集
begin
if(ADSampNum < 4 ) // 当前8个通道采集值都已经读出来,进行下一次的采集
begin
nstate_ad = 4'd7;
end
else // 当前正在读取采集结果
begin
nstate_ad = 4'd0;
end
end
4'd7: // 启动SPI读取时钟
begin
nstate_ad = 4'd8;
end
4'd8:
begin
nstate_ad = 4'd9;
end
4'd9: // 多延时一次确保延时计数器已经开始工作
begin
nstate_ad = 4'd10;
end
4'd10:
begin
if(ADDelay_Cnt > 10) // 延时时间到
begin
nstate_ad = 4'd11;
end
else // 延时时间还没到,等待中
begin
nstate_ad = 4'd10;
end
end
4'd11:
begin
if(AD_FSM_State) //
begin
nstate_ad = 4'd11;
end
else
begin
nstate_ad = 4'd12; //
end
end
4'd12: // 将读到的数据记录下来
begin
nstate_ad = 4'd13;
end
4'd13: // 读取通道索引值加1,读取下一通道值
begin
nstate_ad = 4'd6;
end
// default:nstate_ad = 4'd0;
default: nstate_ad = 4'd0;
endcase
end
end
// 输出值实现
always @(posedge sys_clk or negedge rst_n)
begin
if(!rst_n)
begin
ADStart <= 0;
ad_convsta <= 1;
ADSampNum <= 0;
ad_samp_value[0][15:0] <= 0;
ad_samp_value[1][15:0] <= 0;
ad_samp_value[2][15:0] <= 0;
ad_samp_value[3][15:0] <= 0;
ad_samp_value[4][15:0] <= 0;
ad_samp_value[5][15:0] <= 0;
ad_samp_value[6][15:0] <= 0;
ad_samp_value[7][15:0] <= 0;
end
else
begin
case(cstate_ad)
4'd0:
begin
ad_convsta <= 1;
ADSampNum <= 0;
end
4'd1: // ad_convsta拉低62.5ns,大于手册要求的最小25ns的要求
begin
ad_convsta <= 0;
end
4'd2:
begin
ad_convsta <= 1;
end
4'd3:
begin
;
end
4'd4:
begin
;
end
4'd5:
begin
;
end
4'd6:
begin
;
end
4'd7: // 启动SPI时钟
begin
ADStart <= 1;
end
4'd8:
begin
ADStart <= 0;
end
4'd9:
begin
;
end
4'd10:
begin
;
end
4'd11:
begin
;
end
4'd12:
begin
ad_samp_value[ADSampNum][15:0] <= ad_samp_value_current_a[15:0];
ad_samp_value[ADSampNum+4][15:0] <= ad_samp_value_current_b[15:0];
end
4'd13:
begin
ADSampNum <= ADSampNum +1;
end
default: ;
endcase
end
end
// 延时计数器
reg [4:0] ADDelay_Cnt;
always @(posedge sys_clk or negedge rst_n)
begin
if(!rst_n)
begin
ADDelay_Cnt <= 0;
end
else
begin
if(ADStart)
ADDelay_Cnt <= 0;
else
begin
if( ADDelay_Cnt < 5'd21)
ADDelay_Cnt <= ADDelay_Cnt + 1;
else
ADDelay_Cnt <= ADDelay_Cnt;
end
end
end
//读取采样结果例化
ADSPI_RX ADRX(.clk_div(clk_div),.rst_n(rst_n),.spi_clk(ad_sclk),.ad_start(ADStart),.spi_en(ADEn),.spi_miso_a(ad_miso_a),.spi_miso_b(ad_miso_b),.spi_ncs(ad_cs_n),
.rx_value_a(ad_samp_value_current_a[15:0]),.rx_value_b(ad_samp_value_current_b[15:0]),.spi_state(AD_FSM_State));
|