原创 FPGA之数据采集

2014-7-2 15:25 764 2 2 分类: FPGA/CPLD

//希望高手可以指导下 特别是下面的数据和地址采集的方式对不对 同时希望给一些建议

 

module Selector_Driver_verilog(      
        CLK,         //外部的时钟 频率为63KHz
        AD_BUS,      //外部的地址数据总线 CLK上升沿发送地址 CLK下降沿发送数据(分时复用) 上升沿50ns 下降沿50ns
        CS_AD,       //拨码开关的地址 用来与CLK的上升沿发来的地址作比较
        CTL_A,       //CLK下降沿数据接收
        );

wire clk_in;//调用出来的内部时钟 用来对外部的地址数据进行多次采集频率可调 我现在用为28MHz 觉得足以

input wire CLK;
input wire [7:0]AD_BUS;        
input wire [7:0]CS_AD;       
output reg [8:1]CTL_A;

//状态参数
/***********************************************************/
parameter  state1 = 5'd1;//地址状态量 
parameter  state2 = 5'd2;
parameter  state3 = 5'd3;
parameter  state4 = 5'd4;
parameter  state5 = 5'd5;
parameter  state6 = 5'd6;
parameter  state7 = 5'd7;
parameter  state8 = 5'd8;

parameter  state10 = 5'd10;//数据状态量
parameter  state11 = 5'd11;
parameter  state12 = 5'd12;
parameter  state13 = 5'd13;
parameter  state14 = 5'd14; 
parameter  state15 = 5'd15;
parameter  state16 = 5'd16;
parameter  state17 = 5'd17;
parameter  state18 = 5'd18;
parameter  state19 = 5'd19;

 

/***********************************************************/
wire [7:1]CS_AD0_BUFFER;//地址
assign CS_AD0_BUFFER = CS_AD;

 

//采集外部时钟边沿
/***********************************************************/
wire CLK_NEG;//上升沿  
wire CLK_POS;//下降沿

reg CLK_0;
reg CLK_1;
reg CLK_2;
reg CLK_3;
reg CLK_4;

always @(posedge clk_in)
begin
      CLK_0 <= CLK;
      CLK_1 <= CLK_0;
   CLK_2 <= CLK_1;
      CLK_3 <= CLK_2;
   CLK_4 <= CLK_3;
end

assign CLK_POS = CLK_0 &(~CLK_4);
assign CLK_NEG = CLK_4 &(~CLK_0);


//采集地址进程
/***********************************************************/
reg [7:0]A0;//地址采集寄存器
reg [7:0]A1;
reg [7:0]A2;
reg [7:0]A3;
reg [7:0]A4;
reg [7:0]A5;
reg [7:0]A6;

reg [4:0]A_STATE;//地址状态量
reg [7:0]Addr_BUFFER; //保存采样正确的地址值

always @(posedge clk_in)
begin
   if(CLK_POS) //CLK上升沿
   begin  
     case(A_STATE)
                  state1: begin
              A0 <= AD_BUS;
                    A_STATE <= state2;
           end
                           state2: begin
                              A1 <= AD_BUS;//这样采集地址和下面采集数据的方法对吗?????
                     A_STATE <= state3;
                           end             
                              state3: begin
                              A2 <= AD_BUS;
                     A_STATE <= state4;
                                 end
                        state4: begin        
                              A3 <= AD_BUS;
            A_STATE <= state5;
                                 end
                        state5: begin
                              A4 <= AD_BUS;
            A_STATE <= state6;           
                                 end
                        state6: begin
                              A5 <= AD_BUS;
            A_STATE <= state7;           
                                 end
                        state7: begin                              
            A6 <= AD_BUS;
            A_STATE <= state8;
                                 end
                        state8: if((A0 == AD_BUS) && (A1 == AD_BUS) && (A3 == AD_BUS) && (A4 == AD_BUS) && (A5 == AD_BUS) && (A6 == AD_BUS))//判断是否相等
                     Addr_BUFFER <= AD_BUS ;//得到正确的地址值
                          else A_STATE <= state1; 
         default: A_STATE <= state1;
           endcase 
      end
end

 

 


//采集数据进程
/***********************************************************/
reg [7:0]D0;//数据采集寄存器
reg [7:0]D1;
reg [7:0]D2;
reg [7:0]D3;
reg [7:0]D4;
reg [7:0]D5;
reg [7:0]D6;

reg [7:0]Data_BUFFER;//采集到的正确数据寄存器
reg [4:0]D_STATE;//数据状态量

always @(posedge clk_in)
begin
   if(CLK_NEG)   //CLK下降沿 
   begin
     case(D_STATE)
                  state10: begin
                              D0 <= AD_BUS;
                     D_STATE <= state11;
            end
                           state11: begin
                              D1 <= AD_BUS;
                     D_STATE <= state12;
                           end             
                              state12: begin
                              D2 <= AD_BUS;
                     D_STATE <= state13;
                                 end
                        state13: begin 
               D3 <= AD_BUS;
            D_STATE <= state14;        
                                 end
                        state14: begin
                              D4 <= AD_BUS;
            D_STATE <= state15;           
                                 end
                        state15: begin
                              D_STATE <= (D2 == D3) ? state16 : state14;
            D5 <= AD_BUS;
                                 end
                        state16: begin
                              D6 <= AD_BUS;
            D_STATE <= state17;           
                                 end
                        state11: if((D0 == AD_BUS)) && (D1 == AD_BUS) && (D2 == AD_BUS) && (D3 == AD_BUS) && (D4 == AD_BUS) && (D5 == AD_BUS) && (D6 == AD_BUS))
                     Data_BUFFER <= AD_BUS ;//得到正确的数据
                           else D_STATE <= state10; 
                              default: D_STATE <= state10;
               endcase     
      end
end

//最终采集到的正确地址和拨码开关的地址作比较 符合要求并在下降沿将正确的数据输出
/***********************************************************/
always @(posedge clk_in)
begin
   if((CLK_NEG) && (Addr_BUFFER == CS_AD0_BUFFER))
    CTL_A <= Data_BUFFER;
end
  

 

  
//调用内部晶振 时钟clk_in经PLL输出 //已调用出 已验证 无需理会
/***********************************************************/
wire osc;
myOscillator myOscillator (
 .clkout(osc)
 );

myPll Pll (
 .clkin(osc),    // Reference clock input.
 .clkcpu(),
 .clkout0(clk_in),   // Main clock output.
 .clkout1(),   // clock output 1.
 .clkout2()    // clock output 2.
 );
endmodule

 

 

 

PARTNER CONTENT

文章评论0条评论)

登录后参与讨论
EE直播间
更多
我要评论
0
2
关闭 站长推荐上一条 /3 下一条