在fpga設計開發中,很多場合會遇到同一根訊號既可以是輸入訊號,又可以是輸出訊號,即io型別(verilog定義成inout)。
對於inout型的訊號,我們既可以使用fpga原語來實現,也可以使用verilog**來實現。下面將介紹在xilinx 7系列fpga上兩種實現方式的差別和注意點。
不管哪種方式實現io功能,從編譯結果看都會呼叫iobuf原語,為此,我們先來看一下iobuf的結構,如下圖所示。
1.fpga原語實現
首先,我們編寫的**如下:
1該**通過原語iobuf實現io功能,使用vivado編譯後的原理圖如下圖所示。可以看到iobuf內部由obuft和ibuf原語構成。`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
2.使用verilog實現
把`define primitive注釋掉,則為通過verilog的實現方式,如下圖:
//該**使用vivado編譯後的原理圖如下圖所示。該實現方式也會呼叫iobuf原語,但多消耗了乙個lut資源。`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
通過verilog實現時,我們在把io訊號當成輸入時給賦值高阻態(1『bz)。假如我們把此時的io訊號賦值1『b0或者1『b1,會出現什麼情況呢?我們把1『bz寫成1『b1,如下所示:
1編譯後的原理圖如下,可以看到並不會呼叫iobuf原語,io的不能實現輸入功能,這就是解釋了為什麼在使用verilog實現一根訊號的io功能時需要賦值1『bz。//`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
JAVA 深入理解 IO
定義 如果乙個類是用來完成程式和裝置之間的資料傳輸,則這個類有乙個特殊的稱謂叫 流 流和類的關係 流一定是類,但是類不一定是流。分類 輸入流 輸出流 位元組流 字元流 原始流 包裹流 常用流 的介紹 四大基本抽象流 inputstream outputsream reader writer 位元組流...
深入理解Qt訊號槽
訊號槽機制是觀察者模式的一種應用,達到訂閱 發布的效果。與之類似的有c 中的委託機制,只是寫法有所不同。訊號槽實現的主體是connect函式,常有兩種寫法 利用signal slot巨集和使用 類名 函式的結構 需要注意connect除了可以連線訊號和槽,還可以連線訊號與訊號 單個訊號與多個槽 多個...
C 深入理解型別
值型別 值型別通常儲存在棧中,值型別管理由作業系統管理 引用型別 引用型別儲存在堆中由gc管理 引用型別巢狀定義值型別 值型別巢狀引用型別 值型別繼承自valuetype,valuetype有繼承自system.object 引用型別直接繼承自system.object 值型別的記憶體不受gc控制,...