FPGA之IO訊號型別深入理解

2021-10-01 22:05:49 字數 4450 閱讀 9121

在fpga設計開發中,很多場合會遇到同一根訊號既可以是輸入訊號,又可以是輸出訊號,即io型別(verilog定義成inout)。

對於inout型的訊號,我們既可以使用fpga原語來實現,也可以使用verilog**來實現。下面將介紹在xilinx 7系列fpga上兩種實現方式的差別和注意點。

不管哪種方式實現io功能,從編譯結果看都會呼叫iobuf原語,為此,我們先來看一下iobuf的結構,如下圖所示。

1.fpga原語實現

首先,我們編寫的**如下:

1

`define primitive 23

module

io_buf(

4input

t ,

5input

i ,

6output

o ,

7inoutio8

);910`ifdef primitive

11iobuf #(

12 .drive (12 ), //

specify the output drive strength

13 .ibuf_low_pwr ("

true

" ), //

low power - "true", high performance = "false"

14 .iostandard ("

default

" ), //

specify the i/o standard

15 .slew ("

slow

" ) //

specify the output slew rate

16) iobuf_inst (

17 .o (o ), //

buffer output

18 .io (io ), //

buffer inout port (connect directly to top-level port)

19 .i (i ), //

buffer input

20 .t (t ) //

3-state enable input, high=input, low=output

21);

22 `else

23assign io = t? i:1

'bz;

24assign o =io;

25`endif

2627

endmodule

該**通過原語iobuf實現io功能,使用vivado編譯後的原理圖如下圖所示。可以看到iobuf內部由obuft和ibuf原語構成。

2.使用verilog實現

把`define primitive注釋掉,則為通過verilog的實現方式,如下圖:

//

`define primitive

module

io_iobuf(

input

t ,

input

i ,

output

o ,

inout

io);

`ifdef primitive

iobuf #(

.drive (

12 ), //

specify the output drive strength

.ibuf_low_pwr ("

true

" ), //

low power - "true", high performance = "false"

.iostandard ("

default

" ), //

specify the i/o standard

.slew ("

slow

" ) //

specify the output slew rate

) iobuf_inst (

.o (o ),

//buffer output

.io (io ), //

buffer inout port (connect directly to top-level port)

.i (i ), //

buffer input

.t (t ) //

3-state enable input, high=input, low=output);`

else

assign io = t? i:1

'bz;

assign o =io;

`endif

endmodule

該**使用vivado編譯後的原理圖如下圖所示。該實現方式也會呼叫iobuf原語,但多消耗了乙個lut資源。

通過verilog實現時,我們在把io訊號當成輸入時給賦值高阻態(1『bz)。假如我們把此時的io訊號賦值1『b0或者1『b1,會出現什麼情況呢?我們把1『bz寫成1『b1,如下所示:

1

//`define primitive 23

module

io_iobuf(

4input

t ,

5input

i ,

6output

o ,

7inoutio8

);910`ifdef primitive

11iobuf #(

12 .drive (12 ), //

specify the output drive strength

13 .ibuf_low_pwr ("

true

" ), //

low power - "true", high performance = "false"

14 .iostandard ("

default

" ), //

specify the i/o standard

15 .slew ("

slow

" ) //

specify the output slew rate

16) iobuf_inst (

17 .o (o ), //

buffer output

18 .io (io ), //

buffer inout port (connect directly to top-level port)

19 .i (i ), //

buffer input

20 .t (t ) //

3-state enable input, high=input, low=output

21);

22 `else

23assign io = t? i:1

'b1;

24assign o =io;

25`endif

2627

endmodule

編譯後的原理圖如下,可以看到並不會呼叫iobuf原語,io的不能實現輸入功能,這就是解釋了為什麼在使用verilog實現一根訊號的io功能時需要賦值1『bz。

JAVA 深入理解 IO

定義 如果乙個類是用來完成程式和裝置之間的資料傳輸,則這個類有乙個特殊的稱謂叫 流 流和類的關係 流一定是類,但是類不一定是流。分類 輸入流 輸出流 位元組流 字元流 原始流 包裹流 常用流 的介紹 四大基本抽象流 inputstream outputsream reader writer 位元組流...

深入理解Qt訊號槽

訊號槽機制是觀察者模式的一種應用,達到訂閱 發布的效果。與之類似的有c 中的委託機制,只是寫法有所不同。訊號槽實現的主體是connect函式,常有兩種寫法 利用signal slot巨集和使用 類名 函式的結構 需要注意connect除了可以連線訊號和槽,還可以連線訊號與訊號 單個訊號與多個槽 多個...

C 深入理解型別

值型別 值型別通常儲存在棧中,值型別管理由作業系統管理 引用型別 引用型別儲存在堆中由gc管理 引用型別巢狀定義值型別 值型別巢狀引用型別 值型別繼承自valuetype,valuetype有繼承自system.object 引用型別直接繼承自system.object 值型別的記憶體不受gc控制,...