此驱动程序已经完成很久了,花了2个星期的时间,主要是提升程序运行的效率。最近整理文件的时候又看到了,记录一下。
- module adc7254_Ctrl(
- input sys_clk, //system clkc 50M
- input reset_n, //reset flag
- input iData_a_in, //ADC to fpga
- input iData_b_in,
-
- output sclk_out, //to ADC
- output cs_out, //to ADC
- output sdin, //to ADC
- output [11:0] oData_a, //get data
- output [11:0] oData_b //get data
- );
- wire clk_200M; //PLL驱动
- AD_PLL AD_PLL_inst(
- .inclk0(sys_clk),
- .c0(Clk_200M),
- .c1(sclk_out)
- );
- wire En_conv,En_send; //定义ADC发送和接收程序的状态切换时间
- adc_test adc_test_inst(
- .iRst_n(reset_n),
- .iDclk(sclk_out),
- .iSend_down(Send_down),
-
- .oAdc_rst_n(adc_rst_n),
- .oEn_conv(En_conv),
- .oEn_send(En_send)
- );
- wire Send_down; //ADC指令发送部分
- adc_in_send adc_in_send_inst
- (
- .iClk_200M(Clk_200M),
- .iRst_n(adc_rst_n),
- .iDcLK(sclk_out),
- .iEn_send(En_send),
- .oSDATA(sdin),
- .oSend_down(Send_down)
- );
- wire Conv_down;
- adc_out_conv adc_out_conv_inst //ADC数据采样部分
- (
- .iClk_200M ( Clk_200M ),
- .iRst_n ( adc_rst_n ),
- .iEn_conv ( En_conv ),
- .iDcLK ( sclk_out ),
- .iData_a_in ( iData_a_in ),
- .iData_b_in ( iData_b_in ),
-
- .oData_a ( oData_a ),
- .oData_b ( oData_b ),
- .oConv_down ( Conv_down )
- );
- assign cs_out = Conv_down & Send_down; //状态完成
- endmodule
其主要是以空状态,写状态,读状态三个状态顺序执行的。
- module adc_test(
- input iRst_n,
- input iDclk,
- input iSend_down,
-
- output oAdc_rst_n,
- output reg oEn_send,
- output reg oEn_conv
- );
-
- reg [1:0] state;
- reg [5:0] sclk_cnt;
- localparam state_IDLE = 2'd0;
- localparam state_Write = 2'd1;
- localparam state_Read = 2'd3;
- assign oAdc_rst_n = (iRst_n & state);
- always @(posedge iDclk or negedge iRst_n) begin
- if(!iRst_n)begin
- sclk_cnt <= 6'd0;
- state <= state_IDLE;
- oEn_conv = 1'd0;
- oEn_send = 1'd0;
- end else begin
- case(state)
- state_IDLE:
- begin
- if (sclk_cnt > 6'd30 ) begin
- sclk_cnt <= 6'd0;
- state <= state_Write;
- oEn_conv = 1'd0;
- oEn_send = 1'd1;
- end else begin
- sclk_cnt <= sclk_cnt + 1'd1;
- state <= state_IDLE;
- oEn_conv = 1'd0;
- oEn_send = 1'd0;
- end
- end
- state_Write:
- begin
- if (iSend_down == 1'd1 && sclk_cnt > 6'd30 ) begin
- sclk_cnt <= 0;
- state <= state_Read;
- oEn_conv = 1'd1;
- oEn_send = 1'd0;
- end else begin
- sclk_cnt <= sclk_cnt + 1'd1;
- state <= state_Write;
- oEn_conv = 1'd0;
- oEn_send = 1'd1;
- end
- end
- state_Read:
- begin
- state <= state_Read;
- sclk_cnt <= 1'd0;
- oEn_conv = 1'd1;
- oEn_send = 1'd0;
- end
- endcase
- end
- end
- endmodule
- module adc_in_send(
- input iClk_200M, //200M
- input iRst_n,
-
- input iDcLK, //最小T>60ns
- input iEn_send,
- output oSDATA,
- output oSend_down
- );
-
- //==================使能接收标志位en==================//
- //一旦启动不会突然停止除非复位信号到来
- reg en;
- reg [5:0] sclk_cnt;
- always @(posedge iDcLK or negedge iRst_n ) begin
- if (!iRst_n) begin
- en <= 1'd0;
- sclk_cnt <= 6'd0;
- end else if ( iEn_send == 1'd1 && sclk_cnt == 6'd0 ) begin
- en <= 1'd1;
- sclk_cnt <= 6'd32;
- end else if ( sclk_cnt > 6'd1 ) begin
- en <= en;
- sclk_cnt <= sclk_cnt - 1'd1;
- end else if (oSend_down == 1'd1 && sclk_cnt == 6'd1 ) begin
- en <= 1'd0;
- sclk_cnt <= sclk_cnt - 1'd1;
- end else begin
- en <= en;
- sclk_cnt <= sclk_cnt;
- end
- end
- //==================使能接收标志位en==================//
- //==================SDATA输出操作=========================//
- reg [15:0]CFR_16bit_data = 16'h8840; //需要写入寄存器中的数据
- assign oSDATA = (en > 1'd0) ? ((sclk_cnt > 6'd17) ? CFR_16bit_data[sclk_cnt-6'd17] : 0 ): 0;
- //==================SDATA操作=========================//
- //==================oSend_down操作======================//
- assign oSend_down = (sclk_cnt > 6'd1) ? 0 : 1;
- //==================oSend_down操作======================//
- endmodule
- module adc_out_conv(
- input iClk_200M, //200M
- input iRst_n,
- input iData_a_in,
- input iData_b_in,
- input iDcLK, //最小T=60ns
- input iEn_conv,
-
- output reg [11:0] oData_a,
- output reg [11:0] oData_b,
- output oConv_down //T>70ns
- );
- //下降沿接收
- //==================使能接收标志位en==================//
- //一旦启动不会突然停止除非复位信号到来
- reg en;//接收使能标志位
- reg [5:0] sclk_cnt;
- always @(posedge iDcLK or negedge iRst_n ) begin
- if (!iRst_n) begin
- en <= 1'd0;
- sclk_cnt <= 5'd0;
- end else if (iEn_conv == 1'd1 && sclk_cnt == 4'd0) begin
- en <= 1'd1;
- sclk_cnt <= 6'd17;
- end else if (sclk_cnt > 4'd1) begin
- en <= en;
- sclk_cnt <= sclk_cnt - 1'd1;
- end else if (oConv_down == 1'd1 && sclk_cnt == 4'd1)begin
- en <= 1'd0;
- sclk_cnt <= sclk_cnt - 1'd1;
- end else begin
- en <= en;
- sclk_cnt <= sclk_cnt;
- end
- end
- //==================使能接收标志位en==================//
- //==================dclk时钟采样==================//
- reg [6:0] dclk;
- always@(posedge iClk_200M or negedge iRst_n) begin
- if(!iRst_n) begin
- dclk <= 7'd0;
- end else if(!en) begin
- dclk <= 7'd0;
- end else begin
- dclk <= {dclk[5:0],iDcLK};
- end
-
- end
- //==================dclk时钟采样==================//
- //==================状态切换==================//
- reg [1:0] state;
- parameter state_IDLE = 2'd0;
- parameter state_Read = 2'd1;
- parameter state_Write = 2'd2;
- always@(posedge iClk_200M or negedge iRst_n) begin
- if(!iRst_n ) begin
- state <= state_IDLE;
- end else if(!en) begin
- state <= state_IDLE;
- end else if(dclk[1] == 1 & dclk[2] == 0) begin
- state <= state_Read;
- end else if (dclk[1] == 0 & dclk[2] == 1) begin
- state <= state_Write;
- end else begin
- state <=state;
- end
- end
- //==================状态切换==================//
- //==================data串行转并行==================//
- reg [2:0] Data_a_in_temp,Data_b_in_temp;//保证7次采样有4次为1
- reg [11:0] Data_a_temp,Data_b_temp;
- always@(posedge iClk_200M or negedge iRst_n)
- begin
- if(!iRst_n ) begin
- Data_a_temp <= 12'd0;
- Data_b_temp <= 12'd0;
- Data_a_in_temp <= 3'd0;
- Data_b_in_temp <= 3'd0;
- end else if(sclk_cnt > 6'd16)begin
- Data_a_in_temp <= 3'd0;
- Data_b_in_temp <= 3'd0;
- Data_a_temp <= 12'd0;
- Data_b_temp <= 12'd0;
- end else if(sclk_cnt > 6'd3 ) begin
- if(state == state_Read && dclk[6] == 0 ) begin
- Data_a_in_temp <= Data_a_in_temp + iData_a_in;
- Data_b_in_temp <= Data_b_in_temp + iData_b_in;
- Data_a_temp <= Data_a_temp;
- Data_b_temp <= Data_b_temp;
- end else if(state == state_Write && dclk[0]!=dclk[1])begin
- Data_a_in_temp <= 3'd0;
- Data_b_in_temp <= 3'd0;
- Data_a_temp <= {Data_a_temp[10:0],Data_a_in_temp[2]};
- Data_b_temp <= {Data_b_temp[10:0],Data_b_in_temp[2]};
- end else begin
- Data_a_in_temp <= Data_a_in_temp;
- Data_b_in_temp <= Data_b_in_temp;
- Data_a_temp <= Data_a_temp;
- Data_b_temp <= Data_b_temp;
- end
- end else begin
- Data_a_in_temp <= Data_a_in_temp;
- Data_b_in_temp <= Data_b_in_temp;
- Data_a_temp <= Data_a_temp;
- Data_b_temp <= Data_b_temp;
- end
- end
- //==================data串行转并行==================//
- //==================oConv_down操作======================//
- assign oConv_down = (sclk_cnt > 6'd1) ? 0 : 1;
- //==================oConv_down操作======================//
- //==================数据按帧输出==================//
- always@(posedge iClk_200M or negedge iRst_n)
- begin
- if(!iRst_n )
- begin
- oData_a <= 12'd0;
- oData_b <= 12'd0;
- end
- else if( oConv_down == 1'd1)
- begin
- oData_a <= Data_a_temp;
- oData_b <= Data_b_temp;
- end
- else
- begin
- oData_a <= oData_a;
- oData_b <= oData_b;
- end
- end
- //==================数据按帧输出==================//
- endmodule