激情综合丁香-激情综合六月-激情综合婷婷亚洲图片-激情综合图区-激情综合网五月

基于PCIE接口的高速大容量數據采集——硬件篇

 2022-5-7     作者:Emtronix         

  高速大容量數據采集方案是一個可實現是連續采集數據率超過10MB/s的應用方案,方案包括基于FPGA的硬件設計部分,以及以Linux DMA Engine為基礎框架的應用軟件部分。方案的總體介紹請參考《基于PCIE接口的高速大容量數據采集——總體方案》一文。本文將重點介紹采用Xilinx的FPGA芯片XC7A50T-2CSG325實現數據采集以及利用PCIE端點進行DMA傳輸的硬件機制。


  XC7A50T的設計工具為Xilinx公司的Vivado 2021.1。本文認為用戶已了解Xilinx的FPGA芯片特性及設計工具的使用,這方面就不再贅述。


功能框圖


  創建的eta750_pcie_xdma_dtaker1_5.xpr采用block design,其功能框圖如下:


基于PCIE接口的高速大容量數據采集.png

圖1 ETA750 Block Design Diagram


  圖1中的實例xdma_0是Xilinx公司的PCIE/DMA IP模塊,作為PCIE端點設備(PCIE Endpoint Device)。PCIE的配置在后面介紹。IP模塊實現通過PCIE接口,把數據傳送到系統的某個內存區域,原始數據則通過AXI-Stream接口的C2H通道,由自定義的數據采集模塊DTaker送入。DTaker是整個硬件設計的重點,由Vivado工具的<Create and Package New IP>創建,然后采用verilog編寫全部數字邏輯。注意axi_aclk和axi_aresetn分別為全局工作時鐘和全局復位信號。


  圖1框圖中的主要對外管腳是PCIE×1的三對高速差分信號,以及用戶前端數字接口,這里是AD7606接口,如圖2所示。


基于PCIE接口的高速大容量數據采集.png

圖2 ETA750主要外部信號管腳


  用戶時鐘user_clk是供用戶前端邏輯的時鐘,由用戶根據需求配置,在ETA750中,選擇50MHz時鐘信號。外部硬件復位信號sys_rst_n,低電平有效,直接接入PCIE/DMA模塊。


基于PCIE接口的高速大容量數據采集.png

圖3 ETA750輔助外部信號管腳


  對Xilinx的PCIE/DMA IP模塊的細節感興趣的客戶,請參考手冊《DMA/Bridge Subsystem for PCI Express v4.1》。以下列出對PCIE的基本配置。


PCIE配置


基于PCIE接口的高速大容量數據采集.png

圖4 PCIE接口配置


  作為PCIE Endpoint Device,其數據道數與ESMARC主板一致,為PCIE×1;因主板均支持PCIE2.0或以上標準,所以選擇Maximum Link Speed為5.0Gbps。AXI總線是ARM公司的ABMA總線架構的一部分,是一種高性能同步總線,支持multi-initiator, multi-target通訊機制。Xilinx把AXI作為其FPGA的內部總線,后續自定義的IP核DTaker都是基于AXI的。網上有大量AXI的介紹。這里AXI的配置包括:64-bit數據寬度、62.5MHz的AXI_ACLK、DMA控制器數據接口采用AXI-Stream接口形式。


基于PCIE接口的高速大容量數據采集.png 

圖5 PCI ID配置


  直接使用Xilinx的VID和PID,Linux的PCIE Device驅動將根據此動態加載。


基于PCIE接口的高速大容量數據采集.png

圖6 PCI BAR配置


  PCIE BAR是一組配置PCIE設備占用系統存儲器資源的寄存器。對搭載32-bit Linux系統的ESM7100主板,使用2個32-bit BAR,其中BAR0用于數據采集DTaker,BAR1用于DMA控制器IP核。


基于PCIE接口的高速大容量數據采集.png 

圖7 PCIE中斷配置


  基于XC7A50T的PCIE/DMA IP可支持最多4路DMA通道,分別為2路發送(H2C通道)和2路接收(C2H通道),加上用戶前端邏輯,共有至少5個中斷源。采用PCIE的MSI中斷機制是解決多中斷源的最好方式,所以配置8個中斷矢量,實際使用5個。


基于PCIE接口的高速大容量數據采集.png 

圖8 PCIE中斷配置


  盡管本設計僅需要1路C2H DMA通道,即可實現。但考慮到DMA Engine驅動的完整性,DMA通道還是按最大化配置。


基于PCIE接口的高速大容量數據采集.png 

圖9 PCIE BAR0配置


  PCIE BAR0分成2個64KB段,一段用于控制DTaker模塊,一段可以讀取DMA的運行信息。


DTaker自定義IP


  自定義IP DTaker是由Vivado的<Create and Package New IP>工具創建的一個AXI外設,其基本配置占用8個32-bit寄存器和1路用戶中斷,如圖10所示:


基于PCIE接口的高速大容量數據采集.png 

圖10 DTaker展開圖


  Vivado會自動生成與AXI-Lite接口的寄存器讀寫的verilog代碼,只需在此基礎上增添相應的數據通道接口信號及實現代碼。數據通道的數據輸入端,就是用戶前端數據接口,對ETA750模塊,就是AD7606C的并行接口,通過該接口啟動AD芯片的轉換并讀取轉換的數據;數據通道的輸出端口就是符合AXI-Stream的C2H接口。DTaker需要做的工作,就是把多通道16-bit AD數據,打包成64-bit的AXI-Stream接口數據,并發送給PCIE/DMA。AXI總線的數據收發,采用的是一種簡單高效的同步握手機制<TVALID, TREADY>,其中數據發方輸出TVALID,告知數據有效,然后數據收方輸出TREADY應答,雙方在AXI_ACLK時鐘下,檢測到<TVALID, TREADY>同時有效時,鎖存數據,并同時撤銷各自的握手信號,從而完成一次數據的傳輸。典型的握手時序如圖11所示,T3上升沿為數據鎖存時刻:


基于PCIE接口的高速大容量數據采集.png

圖11 AXI同步握手時序


  Xilinx提供的PCIE/DMA IP(DMA/Bridge Subsystem for PCI Express v4.1),盡管支持多個描述符的多段buffer級聯傳輸,但本質上仍然是單次傳輸結構,即每次傳輸完成后,需要系統驅動干預,啟動下一次傳輸,兩次傳輸間就必然存在一個時間間隔。為了實現連續采集,同時避免兩次傳輸間的數據丟失,需要在用戶前端邏輯和PCIE/DMA的AXI-Stream C2H接口間插入一個FIFO緩沖buffer,這樣就可得到DTaker的功能框圖如圖12所示:


基于PCIE接口的高速大容量數據采集.png

圖12 DTaker功能框圖


  從圖12框圖可見DTaker大致由4個部分組成:(1)AXI-Lite控制狀態寄存器;(2)FIFO Reader,這是一個狀態機(FSM)控制器,實現AXIS的同步握手,把FIFO的數據提交給C2H接口;(3)FIFO Writer,也是一個FSM控制器,實現用戶邏輯接口(User_Logic_Interface),把數據寫入FIFO,處理overflow錯誤;(4)用戶前端邏輯單元,這部分與具體的數據采集應用相關。在具體的Verilog實現中,則分成2個層次,如圖13所示:


基于PCIE接口的高速大容量數據采集.png

圖13 DTaker Verilog代碼層次


  在dtaker1_5_v1_5_S00_AXI.v中,實現了DTaker框圖中的(1)~(3)以及FIFO,FIFO模塊直接采用Xilinx的XPM庫XPM_FIFO_ASYNC,同時調用用戶邏輯模塊。在ETA750中,用戶邏輯模塊由獨立的文件user_logic_ad7606_module.v實現,在實際應用中,用戶可以編寫面向自己應用的前端模塊文件,代替作為參考案例的user_logic_ad7606_module.v,就可很快完成整個硬件設計。用戶邏輯模塊通過user_logic_interface與上層模塊交互數據的,用戶邏輯模塊必須遵守其規范,以下詳細介紹user_logic_interface。


用戶邏輯接口


  用戶邏輯接口遵從AXI架構的同步握手原則,從應用角度來看的user_logic_interface的各個信號如下:


信號名稱信號方向信號描述
AXI_ACLKinput全局時鐘,62.5Mhz
AXI_ARESETNinput全局復位信號,低電平有效
UL_CLKinput用戶專用時鐘,50Mhz
UL_DAQ_CFG[31:0]input數據采集配置信息,用戶自定義
UL_EVENT_CFG[31:0]input事件配置信息,用戶自定義,通常用于觸發配置
UL_DATA[63:0]output用戶數據總線
UL_DATA_VALIDoutput數據有效標志,與UL_DATA_READY實現同步握手
UL_DATA_READYinput數據讀取標志,與UL_DATA_VALID實現同步握手
UL_EVENT_VALIDoutput事件有效標志,與UL_EVENT_READY實現同步握手
UL_EVENT_READYinput事件讀取標志,與UL_EVENT_VALID實現同步握手
UL_EVENT_CODE[2:0]output事件編碼,與UL_EVENT_VALID同步讀取


  用戶邏輯接口中,數據同步握手時序是必須實現的,事件同步握手是可選實現的。在范例模塊user_logic_ad7606_module.v中,已有兩套同步握手的實現代碼。其中<UL_DATA_VALID, UL_DATA_READY>這對握手線,除了在正常的數據傳輸中遵守圖11所示的同步握手方式外,還有其特殊性,這是因為數據采集是按一定時間周期進行的,比如1Msps采樣率,代表1us的采樣周期,UL_DATA_VALID不可能一直有效,超過其采樣周期,那就會造成數據丟失,因此要求上層邏輯(在ETA750中,由dtaker1_5_v1_5_S00_AXI.v實現)在UL_DATA_VALID由高變低后的ACLK上升沿,必須至UL_DATA_READY為高,從而結束本次傳輸周期,同時設置overflow錯誤標志。其時序如圖14所示:


基于PCIE接口的高速大容量數據采集.png

圖14 用戶邏輯接口overflow時序


  在上層dtaker1_5_v1_5_S00_AXI.v模塊中,調用低層用戶邏輯模塊的代碼如下:


// user logic implemented in user_logic_ad7606_module.v
user_logic_ad7606 ad7606_m0(
// global signals
.AXI_ACLK(S_AXI_ACLK),
.AXI_ARESETN(S_AXI_ARESETN),    //!fifo_reset),      
    
// user logic interface for PCIE/DMA
.UL_DAQ_CFG(slv_reg3),
.UL_EVENT_CFG(slv_reg4),
.UL_DATA(daq_data),
.UL_DATA_VALID(daq_data_valid),
.UL_DATA_READY(daq_data_ready),
.UL_EVENT_VALID(daq_event_valid),
.UL_EVEN_READY(daq_event_ready),
.UL_EVENT_CODE(daq_event_code),
.UL_CLK(U_CLK),
 
// externel ad7606 interface, oriented to application
.AD7606_DATA(M_AD7606_DATA),
.AD7606_BUSY(M_AD7606_BUSY),
.AD7606_FIRSTDATA(M_AD7606_FIRSTDATA),
.AD7606_OS(M_AD7606_OS),
.AD7606_CSN(M_AD7606_CSN),
.AD7606_RDN(M_AD7606_RDN),
.AD7606_RESET(M_AD7606_RESET),
.AD7606_CONVST(M_AD7606_CONVST)
);

 

  實現用戶邏輯接口(user_logic_interface)握手的時序控制包含在FIFO Writer中:


// fifo_writer: a 2-bit FSM, fill raw data into fifo
assign overflow_irq_en = slv_reg0[5];
assign event_irq_en = slv_reg0[6];
assign daqen = slv_reg0[8];
assign cpu_data_valid = slv_reg_wren & (axi_awaddr[ADDR_LSB+OPT_MEM_ADDR_BITS:ADDR_LSB] == 3'h7);
assign cpu_data = {slv_reg7, slv_reg6};
assign raw_data_valid = (!daqen & cpu_data_valid) | (daqen & daq_data_valid);
assign raw_data = daqen ? daq_data : cpu_data;
 
// fifo_writer: 3-bit FSM as data filler of FIFO with overflow engine
always @( posedge S_AXI_ACLK )
begin
  if ( (S_AXI_ARESETN == 1'b0) | fifo_wr_rst_busy)
    begin
      fifo_Q <= 0;
    end 
  else
    begin
      case(fifo_Q)
        S0: begin
              if(raw_data_valid & !fifo_full)
                fifo_Q <= S1;
              else if(raw_data_valid & fifo_full)
                fifo_Q <= S3;  
              else
                fifo_Q <= S0;   
            end
        S1: begin       // fifo_wr_en = 1
              fifo_Q <= S2;  
            end
        S2: begin       // ack: raw_data_ready = 1       
              fifo_Q <= S0;   
            end
        S3: begin       // wait fifo_full becomes false
              if(raw_data_valid & !fifo_full)
                fifo_Q <= S1;
              else if(!raw_data_valid)
                fifo_Q <= S4;
              else
                fifo_Q <= S3;   
            end
        S4: begin       // overflow processing       
              fifo_Q <= S2;   
            end
        default:
            begin
              fifo_Q <= S0;   
            end
      endcase
    end
end    
 
// overflow processing 
always @( posedge S_AXI_ACLK )
begin
  if ( S_AXI_ARESETN == 1'b0 )
    begin
      overflow_err <= 1'b0;
      overflow_isr <= 1'b0;
    end
  else if(slv_reg_wren & (axi_awaddr[ADDR_LSB+OPT_MEM_ADDR_BITS:ADDR_LSB] == 3'h1))
    begin
      overflow_err <= (overflow_err & (overflow_err ^ S_AXI_WDATA[3]));
      overflow_isr <= (overflow_isr & (overflow_isr ^ S_AXI_WDATA[5]));
    end
  else if(fifo_Q == S4)
    begin
      overflow_err <= 1'b1;
      overflow_isr <= overflow_irq_en;
    end
  else
    begin
      overflow_err <= overflow_err;
      overflow_isr <= overflow_isr; 
    end
end    
// end of overflow processing
 
// decode of fifo_writer FSM
assign fifo_wr_en = (fifo_Q == S1);
assign raw_data_ready = (fifo_Q == S2);
assign daq_data_ready = daqen & raw_data_ready;


  在用戶模塊user_logic_ad7606_module.v中實現的用戶邏輯接口(user_logic_interface)的握手時序如下:


// control variables
assign running = UL_DAQ_CFG[0];
 
// user data provider: 3-bit FSM handshaker 
always @( posedge AXI_ACLK )
begin
  if ( (AXI_ARESETN == 1'b0) | !running )
    begin
      UQ <= 0;
    end 
  else
    begin
        case(UQ)
          S0: begin
                if(data_update_strobe)
                  UQ <= S1;
                else
                  UQ <= S0;   
              end
          S1: begin       // UL_DATA_VALID = 1, raw_data0
                if(UL_DATA_READY)
                  UQ <= S2;
                else if(!data_update_window)
                  UQ <= S7;
                else
                  UQ <= S1;   
              end
          S2: begin
                UQ <= S3;
              end
          S3: begin
                UQ <= S4;
              end
          S4: begin       // UL_DATA_VALID = 1,raw_data1
                if(UL_DATA_READY)
                  UQ <= S5;
                else if(!data_update_window)
                  UQ <= S7;
                else
                  UQ <= S4;   
              end
          S5: begin
                UQ <= S6;
              end
          S6: begin       // wait until data_update_strobe = 0       
                if(data_update_strobe)
                  UQ <= S6;
                else
                  UQ <= S0;   
              end
          S7: begin       // update window closed, wait ACK
                if(UL_DATA_READY)
                  UQ <= S6;
                else
                  UQ <= S7;   
              end
        endcase
      end
end    
 
  // decode of UQ
  assign user_data1_enable = (UQ == S3) | (UQ == S4) | (UQ == S5);
  assign user_data0 = {ch3_data, ch2_data, ch1_data, ch0_data};
  assign user_data1 = {ch7_data, ch6_data, ch5_data, ch4_data};
  assign UL_DATA_VALID = running & ((UQ == S1) | (UQ == S4));
  assign UL_DATA = user_data1_enable ? user_data1 : user_data0;
  // end of user provider


  在ETA750模塊中,每個采樣周期產生2個64-bit數據,因此會有兩次傳輸握手過程。控制信號running來自數據采集配置寄存器的D0 bit。用戶邏輯需要根據自身的情況產生信號data_update_strobe表示當前采集數據準備就緒,以及信號data_update_window,為數據可傳輸標志。用戶邏輯接口user_logic_interface的有限狀態機(3-bit FSM)的狀態轉換表如下所示:


譯碼動作當前狀態下一狀態轉移條件

S0S1data_update_strobe = 1
S0Otherwise
UL_DATA_VALID = 1S1S2UL_DATA_READY = 1
S7data_update_window = 0
S1Otherwise

S2S3unconditional
raw_data1_enable = 1S3S4unconditional

UL_DATA_VALID = 1

raw_data1_enable = 1

S4S5UL_DATA_READY = 1
S7data_update_window = 0
S4Otherwise
raw_data1_enable = 1S5S6unconditional

S6S6data_update_strobe = 1
S0Otherwise

S7S6UL_DATA_READY = 1
S7Otherwise


小結


  按照本文FPGA的時序設計,理論最快數據傳輸速率為125MB/s,實際數據的傳輸能力還與所處的Linux平臺處理能力有關。應用程序如何使用ETA750模塊,實現實時連續的數據采集和處理,將在《基于PCIE接口的高速大容量數據采集——軟件篇》一文中介紹。


  對大多數中低速數據采集的應用,可利用英創主板的精簡ISA總線接口,就可相對容易地實現。只有真正對高速大容量采集有需求,才需考慮PCIE/FPGA這樣的方案。因為本方案需要客戶具備FPGA的設計能力,同時能準確描述應用程序的需求,才能夠在本方案的基礎上快速實現自己的應用方案。對本方案感興趣的客戶可郵件或電話咨詢進一步的技術細節及合作事宜。


  英創公司技術支持:support@emtronix.com,028-86180660

主站蜘蛛池模板: 色综合91久久精品中文字幕| 2021久久精品国产99国产| 国内精品视频一区二区三区 | 欧美高清免费精品国产自| 日本一本久道| 欧美毛片视频| 精品国产精品| 欧美在线成人午夜网站| 久久在线国产| 后式大肥臀国产在线| 国产精品麻豆一区二区| 精品小视频| 亚洲一区高清| 日韩在线看片| 欧美a级完整在线观看| 黄色一及毛片| 精品国模一区二区三区| 一级二级毛片| 日韩一区二区三区四区五区| 欧美一级特黄做| 特黄a级毛片| 国产网站在线看| 亚洲福利在线看| 久久久精品午夜免费不卡| 全免费一级午夜毛片| 国产综合影院| 99re6久精品国产首页| 欧美精品在线观看| 自偷自偷自亚洲永久| 日韩在线视频线视频免费网站| 欧美 日韩 中字 国产| 特级aaa毛片| 国产精品免费大片| 日日干夜夜干| 91社区在线视频| 日本黄色高清视频| 成人午夜性a一级毛片美女| 国产伦精品一区二区三区| 91久久国产青草亚洲| 久久 在线播放| 色中文|