1. 程式人生 > >QDR SRAM介面FPGA 詳細Verilog程式碼

QDR SRAM介面FPGA 詳細Verilog程式碼

QDR SRAM介紹

QDR 具有獨立的讀、寫資料通路,均使用DDR,在每個時鐘週期內會傳輸四個匯流排寬度的資料 (兩個讀和兩個寫),這就是QDR四倍資料速率的由來。
這裡用到的是典型2字突發的QDR,對於4字突發的QDR操作類似,稍作改動就行。針對每個讀或寫請求,2 字突發器件傳輸兩個字。DDR 地址匯流排用於在前半個時鐘週期允許讀請求,在後半個時鐘週期允許寫請求。
首先看介面的時序圖
這裡寫圖片描述
時序圖,表明了 2 字突發 QDR II 儲存器介面上的併發讀 / 寫操作。時鐘有三組差分時鐘,其中C時鐘是傳送暫存器的傳送時鐘,K時鐘是目的暫存器用的取樣時鐘,CQ時鐘是經過QDR器件延時,跟輸出Q同步的時鐘。
在K時鐘的前半個週期,DDR 地址匯流排允許讀地址傳輸給儲存器;在時鐘的後半個週期,DDR 地址匯流排允許寫地址出現其中。因此,低有效的讀控制 (/R) 和寫控制 (/W) 控制可在同一時鐘週期內有效。
設計目標就是要把QDR介面封裝簡化,把DDR介面都轉化為FPGA內部可用的SDR,這樣對使用者側而言,讀寫控制分離,讀寫地址分離,操作起來更簡便。介面的原理圖如下

這裡寫圖片描述

時鐘關係

可用看出兩組傳送給QDR的時鐘,同頻,滿足C時鐘相位為0和K時鐘相位為270的關係。
這裡寫圖片描述

寫資料通路

這裡寫圖片描述
從QDR SRAM的時序圖中可以看出,寫資料和地址的時序要求一樣,因此處理起來也一樣。多根資料匯流排用generate for生成,程式碼如下。地址通道做相同的處理

generate
    genvar var1;
    for(var1=0;var1<18;var1=var1+1)
      begin:  
        gen_QDR_D
        ODDR #(
            .DDR_CLK_EDGE("SAME_EDGE"
), // "OPPOSITE_EDGE" or "SAME_EDGE" .INIT (1'b0 ), // Initial value of Q: 1'b0 or 1'b1 .SRTYPE ("SYNC" ) // Set/Reset type: "SYNC" or "ASYNC" ) O_QDR_D_inst ( .Q (O_QDR_D[var1] ), // 1-bit DDR output .C (I_user_clk0 ), // 1
-bit clock input .CE(1'b1 ), // 1-bit clock enable input .D1(I_user_wr_data1[var1]), // 1-bit data input (positive edge) .D2(I_user_wr_data2[var1]), // 1-bit data input (negative edge) .R (1'b0 ), // 1-bit reset .S (1'b0 ) // 1-bit set ); end endgenerate

時鐘通路

由於資料要經過DDR輸出,為了保證時鐘和資料具有相同的延時,構造相同的時鐘通路,對CLK0和CLK270都進行如下處理
這裡寫圖片描述
參考程式碼如下,這裡只是一個差分時鐘CLK270的處理,對另一個差分時鐘CLK0做相同處理。

ODDR #(
    .DDR_CLK_EDGE("OPPOSITE_EDGE"), // "OPPOSITE_EDGE" or "SAME_EDGE"
    .INIT        (1'b0           ), // Initial value of Q: 1'b0 or 1'b1
    .SRTYPE      ("SYNC"         )  // Set/Reset type: "SYNC" or "ASYNC"
) O_QDR_K_p_inst (
    .Q (O_QDR_K_p), // 1-bit DDR output
    .C (I_user_clk270), // 1-bit clock input
    .CE(1'b1), // 1-bit clock enable input
    .D1(1'b0), // 1-bit data input (positive edge)
    .D2(1'b1), // 1-bit data input (negative edge)
    .R (1'b0), // 1-bit reset
    .S (1'b0)  // 1-bit set
);
ODDR #(
    .DDR_CLK_EDGE("OPPOSITE_EDGE"), // "OPPOSITE_EDGE" or "SAME_EDGE"
    .INIT        (1'b0           ), // Initial value of Q: 1'b0 or 1'b1
    .SRTYPE      ("SYNC"         )  // Set/Reset type: "SYNC" or "ASYNC"
) O_QDR_K_n_inst (
    .Q (O_QDR_K_n), // 1-bit DDR output
    .C (I_user_clk270), // 1-bit clock input
    .CE(1'b1), // 1-bit clock enable input
    .D1(1'b1), // 1-bit data input (positive edge)
    .D2(1'b0), // 1-bit data input (negative edge)
    .R (1'b0), // 1-bit reset
    .S (1'b0)  // 1-bit set
);

讀資料通路

這裡寫圖片描述

//******************************************************************************
//                               input data path
//******************************************************************************

//-------------------------------------QDR_Q-------------------------------------
generate
    genvar var3;
    for(var3=0;var3<18;var3=var3+1)
      begin:  
        gen_QDR_Q
        IDDR #(
            .DDR_CLK_EDGE("SAME_EDGE_PIPELINED"), // "OPPOSITE_EDGE", "SAME_EDGE"//    or "SAME_EDGE_PIPELINED"
            .INIT_Q1     (1'b0       ), // Initial value of Q1: 1'b0 or 1'b1
            .INIT_Q2     (1'b0       ), // Initial value of Q2: 1'b0 or 1'b1
            .SRTYPE      ("SYNC"     )  // Set/Reset type: "SYNC" or "ASYNC"
        ) I_QDR_Q_inst (
            .Q1(W_rd_data1[var3]), // 1-bit output for positive edge of clock
            .Q2(W_rd_data2[var3]), // 1-bit output for negative edge of clock
            .C (W_dly_clk0), // 1-bit clock input
            .CE(1'b1), // 1-bit clock enable input
            .D (I_QDR_Q[var3]), // 1-bit DDR data input
            .R (1'b0), // 1-bit reset
            .S (1'b0)  // 1-bit set
        );
      end
endgenerate

IDELATY延時調整演算法

其中IDELAY的延時調整演算法如圖所示,分別找到CQ的上升沿(DDR輸出:01->10)和下降沿(DDR輸出:10->01),然後delay_cnt取中間值,使CLK0對準CQ的中間。由於相同的延遲,CLK0也對準資料取樣視窗的中間。當然,最簡單的是直接上板子,輸入一個正弦波,延時用vio輸入,用lia檢視波形。可以手動調整延時到能看到穩定的波形就行了,然後在程式碼裡面把delay_cnt寫死。也可以調兩個最壞的情況,取中間的延時,跟自動調整演算法一樣。
這裡寫圖片描述

   (* IODELAY_GROUP = "delay1" *) 
   IDELAYCTRL IDELAYCTRL_inst1 (
      .RDY(W_delay_rdy),       // 1-bit output: Ready output
      .REFCLK(I_ref_clk_200m), // 1-bit input: Reference clock input
      .RST(~I_reset_n)         // 1-bit input: Active high reset input
   );

   (* IODELAY_GROUP = "delay1" *) 
   IDELAYE2 #(
      .CINVCTRL_SEL("FALSE"),         // Enable dynamic clock inversion (FALSE, TRUE)
      .DELAY_SRC("IDATAIN"),          // Delay input (IDATAIN, DATAIN)
      .HIGH_PERFORMANCE_MODE("TRUE"), // Reduced jitter ("TRUE"), Reduced power ("FALSE")
      .IDELAY_TYPE("VAR_LOAD"),       // FIXED, VARIABLE, VAR_LOAD, VAR_LOAD_PIPE
      .IDELAY_VALUE(0),               // Input delay tap setting (0-31)
      .PIPE_SEL("FALSE"),             // Select pipelined mode, FALSE, TRUE
      .REFCLK_FREQUENCY(200.0),       // IDELAYCTRL clock input frequency in MHz (190.0-210.0, 290.0-310.0).
      .SIGNAL_PATTERN("CLOCK")        // DATA, CLOCK input signal
   )
   IDELAYE2_inst1 (
      .CNTVALUEOUT(), // 5-bit output: Counter value output
      .DATAOUT(W_dly_clk0),       // 1-bit output: Delayed data output
      .C(W_fc_clk),              // 1-bit input: Clock input
      .CE(1'b0),                 // 1-bit input: Active high enable increment/decrement input
      .CINVCTRL(1'b0),           // 1-bit input: Dynamic clock inversion input
      .CNTVALUEIN(W_delay_cnt),  // 5-bit input: Counter value input
      .DATAIN(1'b0),             // 1-bit input: Internal delay data input
      .IDATAIN(I_uae_clk0),       // 1-bit input: Data input from the I/O
      .INC(1'b0),                // 1-bit input: Increment / Decrement tap delay input
      .LD(1'b1),                 // 1-bit input: Load IDELAY_VALUE input
      .LDPIPEEN(1'b0),           // 1-bit input: Enable PIPELINE register to load data input
      .REGRST(1'b0)              // 1-bit input: Active-high reset tap-delay input
   );

程式碼很簡單,把I_user_clk0延遲一下,對齊CQ的中間,這樣也就對齊了資料QDR_Q的中間了。

相關推薦

QDR SRAM介面FPGA 詳細Verilog程式碼

QDR SRAM介紹 QDR 具有獨立的讀、寫資料通路,均使用DDR,在每個時鐘週期內會傳輸四個匯流排寬度的資料 (兩個讀和兩個寫),這就是QDR四倍資料速率的由來。 這裡用到的是典型2字突發的QDR,對於4字突發的QDR操作類似,稍作改動就行。針對每個讀或

學習筆記:FPGA設計Verilog基礎(一)——Verilog程式碼規範

本筆記內容轉自米聯客。一、Verilog 設計規範及背景介紹1、專案架構設計專案的構架用於團隊的溝通,以及專案設計的全域性把控2、介面時序設計規範模組和模組之間的通過模組的介面實現關聯,因此規範的時序設計,對於程式設計的過程,以及程式的維護,團隊之間的溝通都是非常必要的。3、

SRAM、FLASH中除錯程式碼的配置方法(附詳細步驟)

因為STM32的FLASH擦寫次數有限(大概為1萬次),所以為了延長FLASH的使用時間,我們平時除錯時可以選擇在SRAM中進行硬體除錯。除此之外,SRAM 儲存器的寫入速度比在內部 FLASH 中要快得多,所以下載程式到SRAM中的速度較快。 所以我們很有必要建立兩個版本的工程配置,在SRAM中除錯程式完畢

Verilog程式碼FPGA硬體的對映關係(五)

  既然我們可以指定暫存器放在IOB內,那我們同樣也可以指定PLL的位置。首先要確保我們有多個PLL才行。如圖1所示,我們所使用的EP4CE10F17C8晶片剛好有兩個。   圖 1   為了演示這個例子,我們使用pll工程,RTL程式碼如下所示: 1 //-------------------

eclipse呼叫webservice介面,自動獲取程式碼

使用eclipse呼叫webservice介面自動生成程式碼 第一步:導包 第二步:點選專案-右鍵-new-other-搜尋web service client 第三步:點選web service client-輸入地址 第三步:點選ne

獲取作業系統的詳細資訊--程式碼實現

1、GetVersionExA的使用 OSVERSIONINFO 結構體獲取 標頭檔案:#include <windows.h> OSVERSIONINFO osvi; ZeroMemory(osvi, sizeof(OSVERSIONINFO)); osvi.dwOSV

不同的verilog程式碼風格看RTL檢視之一

轉自:http://www.eepw.com.cn/article/268450.htm 作者:時間:2015-01-21來源:網路收藏       剛開始玩CPLD/FPGA開發板的時候使用的一塊基於EPM240T100的板子,alter的這塊晶片雖說功耗小體積

FPGA-12-Verilog的書寫規範格式

程式碼規範有利於在專案和工程中的維護,養成習慣對後期的工作學習會有很大的幫助! 下面就看下各個情況的規範書寫格式是什麼 1.時序邏輯的規範寫法: always @(posedge clk or negedge rst_n)begin if(rst_n==

POI-Excel匯入匯出 詳細實現程式碼

1.介面效果:                   1)點選批量匯入,彈出檔案選擇框,選擇檔案,點選開啟,檔案開始上傳。           &nb

MFC操作串列埠,詳細 複製程式碼(ActiveX控制元件和Windows API函式)

/******************************************************************* *******函式功能:開啟串列埠裝置連結 *******函式名稱:OpenComm *******輸入引數:無 *******輸出引數:無 ***

不用在介面中再定義View 也不用再寫 findViewById 省掉一些介面並不需要的程式碼

之前一直在用ButterKnife也覺得挺好用的,只是最近在做專案模組化的時候發現在子模組之中的id並非為常量導致子模組所有註解報錯,雖然找到一些解決的辦法不過都比較麻煩,而且我覺得也有些曲線救國的感覺。於是我開始用起了最傳統的方法findViewById 結果就出現了 介面

verilogHDL,system Verilog程式碼的多驅動問題

0.起因 最近在專案設計時,遇到了訊號多驅動問題。 記錄下來,提醒自己,方便他人。 1.現象起源 最近在設計YOLO—V3的模組邏輯。 在準備上FPGA時,綜合報錯:訊號多驅動錯誤。 2.原因分析 檢

07jdbc 使用PreparedStatement介面修改之前的程式碼

之前的增刪改差操作的sql語句使用的是Statement介面,現在知道了這個介面是有問題的 下面將之前博文中的增刪改差操作用PreparedStatement介面替換掉Statement介面 先提供工具類DBUtil類 package util; import java.sql.Con

FPGA 設計 Verilog 基礎(二)

1.1 狀態機設計 狀態機是許多數字系統的核心部件,是一類重要的時序邏輯電路。通常包括三個部分:一是下一個狀態的邏輯電路,二是儲存狀態機當前狀態的時序邏輯電路,三是輸出組合邏輯電路。通常,狀態機的狀態數量有限,成為有限狀態機(FSM)。由於狀態機的所有觸發器的時鐘由同一脈衝

資料探勘領域十大經典演算法之—樸素貝葉斯演算法(超詳細程式碼

簡介 NaïveBayes演算法,又叫樸素貝葉斯演算法,樸素:特徵條件獨立;貝葉斯:基於貝葉斯定理。屬於監督學習的生成模型,實現簡單,沒有迭代,並有堅實的數學理論(即貝葉斯定理)作為支撐。在大量樣本下會有較好的表現,不適用於輸入向量的特徵條件有關聯的場景。 基本思想 (1)

資料探勘領域十大經典演算法之—SVM演算法(超詳細程式碼

簡介 SVM(Support Vector Machine)中文名為支援向量機,是常見的一種判別方法。在機器學習領域,是一個有監督的學習模型,通常用來進行模式識別、分類以及迴歸分析。 相關概念 分類器:分類器就是給定一個樣本的資料,判定這個樣本屬於哪個類別的演算法。例如在股

開發前期必須準備的利器:開發原型圖、UI圖工具pxCook、找圖示、寫介面文件、程式碼託管等...

開發前期必準備的效率工具: 開發原型圖:Auxure https://www.axure.com.cn/axure/course/ ui圖量尺寸、標註尺寸 Pxcook’ http://www.fancynode.com.cn/pxcook 找圖示 inconfont

應用層提供相應的操作介面和應用層程式碼

(1)三根通訊線:SCL、SDA、GND (2)同步、序列、電平、低速、近距離 (3)匯流排式結構,支援多個裝置掛接在同一條總線上 (4)主從式結構,通訊雙方必須一個為主(master)一個為從(slave),主裝置掌握每次通訊的主動權,從裝置按照主裝置的節奏被動響應。每個從

load傳遞引數的三種方式(步驟詳細程式碼,要是你們看不懂我就放棄程式設計)

方式一:直接獲取上個頁面的資料; 這種方式主要依賴load這個方法的原理,這個其實就是一個本地ajax請求,所以前後兩個頁面是互通的,其資料是可以直接拿到的。例項如下: a頁面的程式碼: <script> var adata = "12"; $("#d

Java ResultSet介面 詳細說明

Java ResultSet介面 詳細說明 記錄集介面(ResultSet)介面   在JDBC API 2.0中,ResultSet介面有了很大的變化,增加了很多行操作、行定位的新方法,功能也強 大了許多,最主要的變化有以下幾個方面:   1、新定義了若干個常數   這些常數用於指定ResultS