FPGA中邏輯復制


 

  在FPGA設計中經常使用到邏輯復制,邏輯復制也用在很多場合。

1.    信號驅動級數非常大,扇出很大,需要增加驅動力

  邏輯復制最常使用的場合時調整信號的扇出。如果某個信號需要驅動后級很多單元,此時該信號的扇出非常大,那么為了增加這個信號的驅動能力,一種辦法就是插入多級Buffer,但是這樣雖然能增加驅動能力,但是也增加了這個信號的路徑延時。

  為了避免這種情況這時可以復制生成這個信號的邏輯,用多路同頻同相的信號驅動后續電路,使平均到每路的扇出變低,這樣不需要插入Buffer就能滿足驅動能力增加的要求,從而節約該信號的路徑延時。如從圖1.1到圖1.2轉變所示。                                                                                                    圖1.1  邏輯復制前

 

                              

                             圖1.2  邏輯復制后

  由於現在綜合器都已經非常智能,此種場合的邏輯復制工作大多由綜合器完成,不需要人手動調整。各大FPGA廠商的綜合器以及第三方綜合器都有這種功能。

2.    FPGA中需要做很多重復工作

  在某些FPGA設計中,需要很多重復設計的時候,這時候邏輯復制也就有用了。

  例如:在某個特殊應用場合需要設計方向可以任意改變的240位寬的三態IO管腳。我們先看看常用的一個位寬的三態管腳怎么設計。

module inout_interface(
dat_in,
io_out,
io_dir,
dat_out
);
input dat_in;
input io_dir;
output dat_out;
inout io_out;

assign io_out = io_dir ? dat_in : 1'bz;
assign dat_out = io_out;

endmodule

 

  如上述程序所示為單個雙向IO口的典型設計代碼,中間由IO輸入方向控制數據和高阻之間的切換,難題出現了,怎么設計240位寬的雙向IO口呢?難道如下列程序所示:

module inout_interface(
dat_in,
io_out,
io_dir,
dat_out
);
input [239 : 0] dat_in;
input [239 : 0] io_dir;
output [239 : 0] dat_out;
inout [239 : 0] io_out;

assign io_out = io_dir ? dat_in : 240'bz;
assign dat_out = io_out;

endmodule

  顯然這樣是不行的,因為當io_dir為240位的時候只有當全為0的時候此式才為假,其余時候都為真,顯然達不到想要的每個IO都是雙向口的設計。

修改代碼如下:

module inout_interface(

dat_in,

io_out,

io_dir,

dat_out

);

input [239 : 0] dat_in;

input [239 : 0] io_dir;

output [239 : 0] dat_out;

inout [239 : 0] io_out;



assign io_out[0] = io_dir[0] ? dat_in[0] : 1'bz;

assign dat_out[0] = io_out[0];



assign io_out[1] = io_dir[1] ? dat_in[1] : 1'bz;

assign dat_out[1] = io_out[1];



assign io_out[2] = io_dir[2] ? dat_in[2] : 1'bz;

assign dat_out[2] = io_out[2];



.

. // 此處略去1萬行

.



assign io_out[239] = io_dir[239] ? dat_in[239] : 1'bz;

assign dat_out[239] = io_out[239];



endmodule

  顯然這種辦法能實現240位寬的獨立方向控制IO,但是估計寫代碼要累死人,有沒得更好的辦法呢?

  當然有,在verilog2001中有個邏輯復制語法——generate,可以對verilog模塊進行無限復制。有了這個模塊我們即可輕松通過邏輯復制來達到我們的要求了。

// 單個雙向IO實現模塊

module pin_inout(

indat,

indir,

outdat,

outdatin

);



input indat;

input indir;

inout outdat;

output outdatin;



assign outdat = indir ? indat : 1'bz;

assign outdatin = outdat;



endmodule



module inout_interface(

dat_in,

io_out,

io_dir,

dat_out

);

input [239 : 0] dat_in;

input [239 : 0] io_dir;

output [239 : 0] dat_out;

inout [239 : 0] io_out;



// 邏輯復制240次

genvar i;

generate

for(i = 0; i < 240; i = i + 1)

begin : pin_loop

pin_inout pin_inout_inst(

.indat ( dat_in[i] ),

.indir ( io_dir[i] ),

.outdat ( io_out[i] ),

.outdatin ( dat_out[i] )

);

end

endgenerate



endmodule

  由上面代碼可看出,巧妙利用verilog語法能減少自身工作量。

3.    總結

  在FPGA設計中有些情況的邏輯復制不需要我們做,但是有些情況的邏輯復制不得不手工完成,因此,熟練掌握verilog語法是設計出好的模型、減少工作量的前提。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM