从底层结构开始学习FPGA(5)----移位寄存器
文章目錄
系列目錄與傳送門
一、移位寄存器SRL
1.1、概述
1.2、概念
1.3、應用
1.4、結構
1.5、級聯
三、移位操作
3.1、靜態操作(移位長度固定)
3.2、動態操作(移位長度可變)
3.3、Timing
四、實例化
4.1、源語
4.2、推斷方式
五、應用
5.1、同步移位寄存器
5.2、固定長度的移位寄存器
六、總結
系列目錄與傳送門
????????《從底層結構開始學習FPGA》目錄與傳送門
一、移位寄存器SRL
1.1、概述
????????移位寄存器內的數據可以在移位脈沖(時鐘信號)的作用下依次左移或右移。移位寄存器不僅可以存儲數據,還可以用來實現數據的串并轉換、分頻,構成序列碼發生器、序列碼檢測器,進行數值運算以及數據處理等,它也是數字系統中應用非常廣泛的時序邏輯部件之一。
????????在FPGA的底層結構----可配置邏輯塊CLB中,一個CLB由4個Slice組成,這4個Slice又可以分SliceM和SliceL(其比例大致為1:3),其中M是Memory的首字母,L是Logic的首字母,比較SliceM和SliceL,其區別就是SliceM的查找表具有RAM和ROM的功能,而SliceL的則不具備,所以SliceM比SliceL多的功能就是做存儲器和移位。
1.2、概念
????????SLICEM可以在不使用觸發器的條件下配置為32位移位寄存器(注意:只能左移)。這樣,每個LUT可以將串行數據延遲1到32個時鐘周期。移位輸入D(LUT DI1腳)和移位輸出Q31(LUT MC31腳)可以進行級聯,以形成更大的移位寄存器。一個SLICEM的4個LUT6級聯可以實現128個時鐘周期的延時。多個SLICEM也可以進行組合。但SLICEM之間沒有直接連接以形成更長的移位寄存器,在LUT B/C/D處的MC31輸出也沒有。由此產生的可編程延遲可用于平衡數據pipeline的時間。
1.3、應用
- 延遲或延遲補償
- 同步FIFO和內容尋址存儲器(CAM)
1.4、結構
上圖是由一個LUT構成的最高支持32位移位的移位寄存器SRLC32E結構。?
- CLK:時鐘
- CE:時鐘使能,高電平有效
- SHIFTIN(D):數據輸入
- A[4:0]:移位長度配置(支持1~32位),需要+1。如9位移位則A[4:0]需配置成1+8(01000)
- SHIFTOUT:32個長度移位后的數據輸出,可用來與其他SRLC32E級聯,形成更大長度的移位寄存器
- OUTPUT(Q)?:當移位長度被確定后,數據就會出現在Q端
1.5、級聯
通過兩個32位的移位寄存器SRL32與一個MUX2,即可級聯成最高支持64位的移位寄存器。
通過三個32位的移位寄存器SRL32與三個MUX2,即可級聯成最高支持96位的移位寄存器。?
通過四個32位的移位寄存器SRL32與三個MUX2,即可級聯成最高支持128位的移位寄存器。
而4個移位寄存器由4個LUT組成,剛好一個SLICEM中有4個LUT,這說明一個SLICEM可以實現最多支持128位的移位寄存器。由于4個LUT同在一個SLICE里面,所以布線方便且延遲短,有利于時序收斂。
三、移位操作
3.1、靜態操作(移位長度固定)
- 輸入(D)被加載到移位寄存器的第一個位
- 前一個位被移到下一個位置并出現在Q輸出上,最高位移到MC31輸出。
- 移位寄存器固定長度為(N + 1),其中N為輸入地址(0-31),由地址總線A[4:0]決定
- 在級聯操作中,前一個移位寄存器的SHIFTOUT鏈接至下一個移位寄存器的SHIFTIN
3.2、動態操作(移位長度可變)
- 數據的移位輸出是異步信號
- 其他與靜態操作一致
3.3、Timing
四、實例化
在實際的編寫RTL過程中,我們可通過以下方式來生成一個移位寄存器。
- 源語方式
- 綜合工具推斷方式
4.1、源語
(1)源語類型
- SRL16E:最高可實現16個時鐘周期的移位功能
- SRLC32E:最高可實現32個時鐘周期的移位功能
以上均可以實現移位寄存器功能,后文以SRLC32E為例進行講解。
(2)源語例化
// SRLC32E: 32-bit variable length cascadable shift register LUT (Mapped to a SliceM LUT6) // with clock enableSRLC32E #( .INIT(32'h00000000) // Initial Value of Shift Register ) SRLC32E_inst (.Q(Q), // SRL data output.Q31(Q31), // SRL cascade output pin.A(A), // 5-bit shift depth select input.CE(CE), // Clock enable input.CLK(CLK), // Clock input.D(D) // SRL data input );// End of SRLC32E_inst instantiation關于參數與信號在上面已講解,不贅述。
(3)示例代碼
module test(input clk,input ce, input shift_in, //移位輸入output Q, //移位輸出output shift_out //移位輸出,可級聯);SRLC32E #(.INIT(32'h00000000) // Initial Value of Shift Register) SRLC32E_inst (.Q(Q), // SRL data output.Q31(shift_out), // SRL cascade output pin.A(5'b01001), // 5-bit shift depth select input,移位長度固定為10----01001+1.CE(ce), // Clock enable input.CLK(clk), // Clock input.D(shift_in) // SRL data input);endmodule上面的模塊是直接使用SRL32源語例化的一個移位寄存器,移位長度固定為10。 下面是綜合出來的結構,可以看到只使用了一個LUT。
(4)Testbench
`timescale 1ns / 1ns module tb_test();reg clk; reg ce; reg shift_in; wire Q; wire shift_out;test test_inst(.clk(clk),.ce(ce),.shift_in(shift_in),.Q(Q),.shift_out(shift_out));initial beginclk=0;ce=1;shift_in = 1;#330 $finish; endalways#5 clk=~clk;always#10 shift_in<=~shift_in;endmodule(5)仿真結果
在第一個周期輸入信號從0跳轉到1;移位長度設置為10,在第10個周期Q輸出為1,此后輸出與shift_in一致;在第32個周期,shift_out開始輸出1,然后輸出與shift_in一致。仿真結果符合Timing。
4.2、推斷方式
除了直接例化SRL源語外,也可以通過編寫常規的RTL代碼來實現移位寄存器的功能。但是需要注意的是,要注意編寫RTL的風格,有些風格可能導致vivado無法綜合出SRL,而是使用多個REG來實現,會造成大量的資源浪費。
(1)錯誤的推斷方式
module test(input clk,input ce,input shift_in,input rst,output Q,output shift_out);reg [31:0] dff;always@(posedge clk) beginif(rst)dff<=0;else if(ce) begindff[31:0]<={dff[30:0],shift_in}; //拼接運算實現向左移位end endassign shift_out=dff[31]; assign Q=dff[9];endmodule上面代碼的綜合結果如下,顯然不是用的SRL32,而是數個LUT+數個FF。其原因在于RTL中使用了復位信號,而SRL32這個元件是沒有復位端口的,因為流水線的結構根本就不需要復位!復位的使用完全是畫蛇添足,導致不必要的資源浪費。
?
?(2)正確的推斷方式
module test(input clk,input ce,input shift_in,output Q,output shift_out);reg [31:0] dff;always@(posedge clk) beginif(ce) begindff[31:0]<={dff[30:0],shift_in}; //拼接運算實現向左移位end endassign shift_out=dff[31]; assign Q=dff[9];endmodule上面的代碼是刪除復位后的代碼,綜合結果如下。
?使用的資源:3個FF+2個SRL。因為我們要做的是10位移位,所以結果在第10位被引出。vivado自動幫輸入以及輸出做了寄存,所以資源消耗得多一些。??
仿真結果:?
在第一個周期輸入信號從0跳轉到1;移位長度設置為10,在第10個周期Q輸出為1,此后輸出與shift_in一致;在第32個周期,shift_out開始輸出1,然后輸出與shift_in一致。仿真結果符合Timing。
五、應用
5.1、同步移位寄存器
????????移位寄存器原語不會使用同一SLICE中可用的寄存器。要實現完全同步的讀和寫移位寄存器,輸出引腳Q必須連接到觸發器FF。移位寄存器和觸發器共享同一時鐘,如圖所示。
5.2、固定長度的移位寄存器
????????32位移位寄存器可級聯實現任何靜態長度模式的移位寄存器,而不需要使用專用的多路復用器(F7AMUX, F7BMUX和F8MUX)。下圖說明了如何構建72位移位寄存器。只有最后一個SRLC32E原語需要將其地址輸入綁定到ob00111。另外,可以將移位寄存器的長度限制為71位(綁定到obo0110的地址),并且可以使用一個觸發器作為最后一個寄存器。(在SRLC32E原語中,移位寄存器長度為地址輸入+ 1)。
?六、總結
- 一個移位操作需要一個時鐘沿
- 對LUT的Q輸出的動態移位長度讀操作是異步的
- 對LUT的Q輸出的靜態移位長度讀取操作是同步的
- 數據輸入具有 setup-to-clock的時序規范
- 在可級聯配置中,Q31輸出總是包含最后一位值
- Q31輸出在每次移位操作后同步變化
- SRL結構不需要使用復位,如果希望使用SRL32減少資源,實現移位,則建議使用源語方式例化
總結
以上是生活随笔為你收集整理的从底层结构开始学习FPGA(5)----移位寄存器的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 使用声音传感器的Arduino控制的音乐
- 下一篇: 软件体系结构的第二次实验(解释器风格与管