|
提供一段AD采樣的FPGA程序
程序如下
Verilog源程序如下:
- //---------------------------------------------------------------------------
- //-- 文件名 : Ad_Module.v
- //-- 作者 : ZIRCON
- //-- 描述 : AD模塊
- //---------------------------------------------------------------------------
- `define AD_CLK_TIME 10'd49 //1.1M, 909ns,909 / (1 / 50M) = 45 =0x2D
- `define AD_CLK_TIME_HALF 10'd24 //909ns / 2 = 454.5ns 45 / 2 = 22
- module Ad_Module
- (
- //Input
- CLK_50M,RST_N,
- //Output
- AD_CS,AD_CLK,AD_DATA,data_out
- );
-
- //---------------------------------------------------------------------------
- //-- 外部端口聲明
- //---------------------------------------------------------------------------
- input CLK_50M; //時(shí)鐘的端口,開發(fā)板用的50M晶振
- input RST_N; //復(fù)位的端口,低電平復(fù)位
- input AD_DATA; //AD數(shù)據(jù)端口
- output AD_CS; //AD片選端口
- output AD_CLK; //AD時(shí)鐘端口,最大不超過1.1MHz
- output [ 7:0] data_out; //AD模數(shù)轉(zhuǎn)換完成的數(shù)據(jù)輸出
- //---------------------------------------------------------------------------
- //-- 內(nèi)部端口聲明
- //---------------------------------------------------------------------------
- reg AD_CS; //AD片選信號(hào)端口
- reg AD_CS_N; //AD_CS的下一個(gè)狀態(tài)
- reg AD_CLK; //AD時(shí)鐘,最大不超過1.1MHz
- reg AD_CLK_N; //AD_CLK的下一個(gè)狀態(tài)
- reg [ 2:0] ad_fsm_cs; //狀態(tài)機(jī)的當(dāng)前狀態(tài)
- reg [ 2:0] ad_fsm_ns; //狀態(tài)機(jī)的下一個(gè)狀態(tài)
- reg [ 5:0] time_cnt; //用于記錄一個(gè)時(shí)鐘所用時(shí)間的定時(shí)器
- reg [ 5:0] time_cnt_n; //time_cnt的下一個(gè)狀態(tài)
- reg [ 5:0] bit_cnt; //用來記錄時(shí)鐘周期個(gè)數(shù)的計(jì)數(shù)器
- reg [ 5:0] bit_cnt_n; //bit_cnt的下一個(gè)狀態(tài)
- reg [ 7:0] data_out; //用來保存穩(wěn)定的AD數(shù)據(jù)
- reg [ 7:0] data_out_n; //data_out的下一個(gè)狀態(tài)
- reg [ 7:0] ad_data_reg; //用于保存數(shù)據(jù)的移位寄存器
- reg [ 7:0] ad_data_reg_n; //ad_data_reg_n的下一個(gè)狀態(tài)
- parameter FSM_IDLE = 3'h0; //狀態(tài)機(jī)的初始狀態(tài);
- parameter FSM_READY = 3'h1; //滿足CS有效時(shí)的第一個(gè)1.4us的延時(shí)狀態(tài)
- parameter FSM_DATA = 3'h2; //讀取8個(gè)數(shù)據(jù)狀態(tài)
- parameter FSM_WAIT_CONV = 3'h3; //等待轉(zhuǎn)換狀態(tài),等待17us;
- parameter FSM_END = 3'h4; //結(jié)束的狀態(tài)
- //---------------------------------------------------------------------------
- //-- 邏輯功能實(shí)現(xiàn)
- //---------------------------------------------------------------------------
- //時(shí)序電路,用來給ad_fsm_cs寄存器賦值
- always @ (posedge CLK_50M or negedge RST_N)
- begin
- if(!RST_N) //判斷復(fù)位
- ad_fsm_cs <= 1'b0; //初始化ad_fsm_cs值
- else
- ad_fsm_cs <= ad_fsm_ns; //用來給ad_fsm_ns賦值
- end
- //組合電路,用來實(shí)現(xiàn)狀態(tài)機(jī)
- always @ (*)
- begin
- case(ad_fsm_cs) //判斷狀態(tài)機(jī)的當(dāng)前狀態(tài)
- FSM_IDLE:
- //3 x 0.909us = 2.727us用于初始化延時(shí)
- if((bit_cnt == 6'd2 ) && (time_cnt == `AD_CLK_TIME))
- ad_fsm_ns = FSM_READY; //如果空閑狀態(tài)完成就進(jìn)入延時(shí)狀態(tài)
- else
- ad_fsm_ns = ad_fsm_cs; //否則保持原狀態(tài)不變
- FSM_READY:
- //2 x 0.909us = 1.818us用于延遲1.4us
- if((bit_cnt == 6'd2 ) && (time_cnt == `AD_CLK_TIME))
- ad_fsm_ns = FSM_DATA; //如果延時(shí)狀態(tài)完成就進(jìn)入讀取數(shù)據(jù)狀態(tài)
- else
- ad_fsm_ns = ad_fsm_cs; //否則保持原狀態(tài)不變
- FSM_DATA:
- //讀取數(shù)據(jù)8位,1~8個(gè)時(shí)鐘脈沖
- if((bit_cnt == 6'd8 ) && (time_cnt == `AD_CLK_TIME))
- ad_fsm_ns = FSM_WAIT_CONV;//如果讀取數(shù)據(jù)狀態(tài)完成就進(jìn)入等待狀態(tài)
- else
- ad_fsm_ns = ad_fsm_cs; //否則保持原狀態(tài)不變
- FSM_WAIT_CONV:
- //19 x 0.909us = 17.271us用于延遲17us
- if((bit_cnt == 6'd10) && (time_cnt == `AD_CLK_TIME))
- ad_fsm_ns = FSM_END; //如果等待狀態(tài)完成就進(jìn)入讀取狀態(tài)
- else
- ad_fsm_ns = ad_fsm_cs; //否則保持原狀態(tài)不變
- FSM_END:
- ad_fsm_ns = FSM_READY; //完成一次數(shù)據(jù)轉(zhuǎn)換,進(jìn)入下一次轉(zhuǎn)換
- default:ad_fsm_ns = FSM_IDLE;
- endcase
- end
- //時(shí)序電路,用來給time_cnt寄存器賦值
- always @ (posedge CLK_50M or negedge RST_N)
- begin
- if(!RST_N) //判斷復(fù)位
- time_cnt <= 6'h0; //初始化time_cnt值
- else
- time_cnt <= time_cnt_n; //用來給time_cnt賦值
- end
- //組合電路,實(shí)現(xiàn)0.909us的定時(shí)計(jì)數(shù)器
- always @ (*)
- begin
- if(time_cnt == `AD_CLK_TIME) //判斷0.909us時(shí)間
- time_cnt_n = 6'h0; //如果到達(dá)0.909us,定時(shí)器清零
- else
- time_cnt_n = time_cnt + 6'h1; //如果未到0.909us,定時(shí)器繼續(xù)加1
- end
- //時(shí)序電路,用來給bit_cnt寄存器賦值
- always @ (posedge CLK_50M or negedge RST_N)
- begin
- if(!RST_N) //判斷復(fù)位
- bit_cnt <= 6'h0; //初始化bit_cnt值
- else
- bit_cnt <= bit_cnt_n; //用來給bit_cnt賦值
- end
- //組合電路,用來記錄時(shí)鐘周期個(gè)數(shù)的計(jì)數(shù)器
- always @ (*)
- begin
- if(ad_fsm_cs != ad_fsm_ns) //判斷狀態(tài)機(jī)的當(dāng)前狀態(tài)
- bit_cnt_n = 6'h0; //如果當(dāng)前的狀態(tài)不等于下一個(gè)狀態(tài),計(jì)時(shí)器就清零
- else if(time_cnt == `AD_CLK_TIME_HALF)//判斷0.4545us時(shí)間
- bit_cnt_n = bit_cnt + 6'h1; //如果到達(dá)0.4545us,計(jì)數(shù)器就加1
- else
- bit_cnt_n = bit_cnt; //否則計(jì)數(shù)器保持不變
- end
- //時(shí)序電路,用來給AD_CLK寄存器賦值
- always @ (posedge CLK_50M or negedge RST_N)
- begin
- if(!RST_N) //判斷復(fù)位
- AD_CLK <= 1'h0; //初始化AD_CLK值
- else
- AD_CLK <= AD_CLK_N; //用來給AD_CLK賦值
- end
- //組合電路,用來生成AD的時(shí)鐘波形
- always @ (*)
- begin
- if(ad_fsm_cs != FSM_DATA) //判斷狀態(tài)機(jī)的當(dāng)前狀態(tài)
- AD_CLK_N = 1'h0; //如果當(dāng)前的狀態(tài)不等于讀取數(shù)據(jù)狀態(tài),AD_CLK_N就置0
- else if(time_cnt == `AD_CLK_TIME_HALF)//判斷0.4545us時(shí)間
- AD_CLK_N = 1'h1; //如果到達(dá)0.4545us,ADC_CLK_N就置1
- else if(time_cnt == `AD_CLK_TIME)//判斷0.909us時(shí)間
- AD_CLK_N = 1'h0; //如果到達(dá)0.909us,AD_CLK_N就置0
- else
- AD_CLK_N = AD_CLK; //否則保持不變
- end
- //時(shí)序電路,用來給AD_CS寄存器賦值
- always @ (posedge CLK_50M or negedge RST_N)
- begin
- if(!RST_N) //判斷復(fù)位
- AD_CS <= 1'h0; //初始化AD_CS值
- else
- AD_CS <= AD_CS_N; //用來給AD_CS賦值
- end
- //組合電路,用來生成AD的片選波形
- always @ (*)
- begin
- if((ad_fsm_cs == FSM_DATA) || (ad_fsm_cs == FSM_READY))//判斷狀態(tài)機(jī)的當(dāng)前狀態(tài)
- AD_CS_N = 1'h0;//如果當(dāng)前的狀態(tài)等于讀取數(shù)據(jù)狀態(tài)或等于延時(shí)1.4us狀態(tài),AD_CS_N就置0
- else
- AD_CS_N = 1'h1;//如果當(dāng)前的狀態(tài)不等于讀取數(shù)據(jù)狀態(tài)或不等于延時(shí)1.4us狀態(tài),AD_CS_N就置1
- end
- //時(shí)序電路,用來給ad_data_reg寄存器賦值
- always @ (posedge CLK_50M or negedge RST_N)
- begin
- if(!RST_N) //判斷復(fù)位
- ad_data_reg <= 8'h0; //初始化ad_data_reg值
- else
- ad_data_reg <= ad_data_reg_n; //用來給ad_data_reg賦值
- end
- //組合電路,將AD線上的數(shù)據(jù)保存到移位寄存器中
- always @(*)
- begin
- if((ad_fsm_cs == FSM_DATA) && (!AD_CLK) && (AD_CLK_N))//判斷每一個(gè)時(shí)鐘的上升沿
- ad_data_reg_n = {ad_data_reg[6:0],AD_DATA};//將數(shù)據(jù)存入移位寄存器中,高位優(yōu)先
- else
- ad_data_reg_n = ad_data_reg; //否則保持不變
- end
- //時(shí)序電路,用來給data_out寄存器賦值
- always @ (posedge CLK_50M or negedge RST_N)
- begin
- if(!RST_N) //判斷復(fù)位
- data_out <= 8'h0; //初始化data_out值
- else
- data_out <= data_out_n; //用來給data_out賦值
- end
- //組合電路,將移位寄存器中的數(shù)據(jù)存入data_out中,可用于輸出
- always @ (*)
- begin
- if(ad_fsm_cs == FSM_END) //判斷復(fù)位
- data_out_n = ad_data_reg; //初始化data_out值
- else
- data_out_n = data_out; //用來給data_out賦值
- end
- endmodule
復(fù)制代碼
所有資料51hei提供下載:
Ad_Module.rar
(2.06 KB, 下載次數(shù): 80)
2019-4-26 11:04 上傳
點(diǎn)擊文件名下載附件
|
評(píng)分
-
查看全部評(píng)分
|