我是一名FPGA設(shè)計領(lǐng)域的新手,有太多的不足和缺陷,需要花時間去一個一個地攻破他們。唯有這樣,也許在未來的某一天,我就成功了。
這幾天,我在搞設(shè)計時發(fā)現(xiàn)了幾種可以減少設(shè)計資源的技巧,現(xiàn)在把它們拿出來與大家分享,希望對大家在設(shè)計時有一定的幫助。*^_^*下面綜合的器件以Xilinx公司的Spartan6系列的xc6slx45-2fgg484為例。
一、加法計數(shù)器
這里以20000進制的加法計數(shù)器為例進行講解。
<1>通過判斷計數(shù)器cnt是否小于19999,若小于19999則每個時鐘加1,否則賦值為0,實現(xiàn)電路如程序清單1所示:
程序清單1
/********************************Copyright************************************ ** CrazyBird ** ** **-----------------------------File Infomation-------------------------------- ** FileName : add_counter_1.v ** Author : CrazyBird ** Data : 2015-10-31 ** Version : v1.0 ** Description : 20000 decimal additive counter ** *****************************************************************************/ // synopsys translate_off `timescale 1 ns / 1 ps // synopsys translate_on module add_counter_1 #( parameter T_COUNT = 20000 ) ( input rst_n, input clk, output reg [14:0] cnt ); //----------------------------------------------- // 20000 decimal additive counter always @(posedge clk or negedge rst_n) begin if(rst_n==1'b0) cnt <= 15'd0; else if(cnt < T_COUNT-1'b1) cnt <= cnt + 1'b1; else cnt <= 15'd0; end endmodule //********************************End File***********************************
綜合后資源消耗情況如圖1所示:
圖1 加法計數(shù)器在臨界條件cnt<19999下的資源消耗情況
<2>通過判斷計數(shù)器cnt是否等于19999,若等于19999則賦值為0,否則每個時鐘加1,實現(xiàn)電路如程序清單2所示:
程序清單2
/********************************Copyright********************************** ** CrazyBird ** ** **----------------------------File Infomation------------------------------- ** FileName : add_counter_2.v ** Author : CrazyBird ** Data : 2015-10-31 ** Version : v1.0 ** Description : 20000 decimal additive counter ** ***************************************************************************/ // synopsys translate_off `timescale 1 ns / 1 ps // synopsys translate_on module add_counter_2 #( parameter T_COUNT = 20000 ) ( input rst_n, input clk, output reg [14:0] cnt ); //----------------------------------------------- // 20000 decimal additive counter always @(posedge clk or negedge rst_n) begin if(rst_n==1'b0) cnt <= 15'd0; else if(cnt == T_COUNT) cnt <=15'd0; else cnt <= cnt + 1'b1; end endmodule //*******************************End File**********************************
綜合后資源消耗情況如圖2所示:
圖2 加法計數(shù)器在臨界條件cnt==19999下的資源消耗情況
<3>總結(jié):一般情況下,加法計數(shù)器在臨界條件cnt小于T_COUNT下綜合消耗的資源要比在臨界條件cnt等于T_COUNT下要少。
二、將大的計數(shù)器適當分解為小的計數(shù)器
這里以時鐘為100MHz,每延時20ms產(chǎn)生一個時鐘周期的使能信號即計數(shù)2000000次為例。
<1>用一個計數(shù)器實現(xiàn),實現(xiàn)電路如程序清單3所示:
程序清單3
/*******************************Copyright********************************** ** CrazyBird ** ** **---------------------------File Infomation------------------------------- ** FileName : large_counter.v ** Author : CrazyBird ** Data : 2015-10-31 ** Version : v1.0 ** Description : Large counter to achieve 2000000 count ** **************************************************************************/ // synopsys translate_off `timescale 1 ns / 1 ps // synopsys translate_on module large_counter #( parameter T_COUNT = 2000000 ) ( input rst_n, input clk, output cnt_done ); //----------------------------------------- // count 2000000 reg [20:0] cnt; always @(posedge clk or negedge rst_n) begin if(rst_n == 1'b0) cnt <= 21'd0; else if(cnt < T_COUNT-1'b1) cnt <= cnt + 1'b1; else cnt <= 21'd0; end assign cnt_done = (cnt == T_COUNT-1'b1); endmodule //******************************End File***********************************
綜合后資源消耗情況如圖3所示:
圖3 采用單個大的計數(shù)器消耗的資源情況
<2>用兩個小的計數(shù)器實現(xiàn),其中一個計數(shù)器cnt1計數(shù)2000,另一個計數(shù)器cnt2計數(shù)1000。每當cnt1完成一個周期的計數(shù),cnt2加1(嘿嘿,注意了,這里還可以運用第一種設(shè)計技巧來幫助減少資源消耗),實現(xiàn)電路如程序清單4所示:
程序清單4
/*******************************Copyright********************************** ** CrazyBird ** ** **---------------------------File Infomation------------------------------- ** FileName : small_counter.v ** Author : CrazyBird ** Data : 2015-10-31 ** Version : v1.0 ** Description : Small counter to achieve 2000000 count ** **************************************************************************/ // synopsys translate_off `timescale 1 ns / 1 ps // synopsys translate_on module small_counter #( parameter T_COUNT_1 = 2000, parameter T_COUNT_2 = 1000 ) ( input rst_n, input clk, output cnt_done ); //----------------------------------------- // count 2000 reg [10:0] cnt1; always @(posedge clk or negedge rst_n) begin if(rst_n == 1'b0) cnt1 <= 11'd0; else if(cnt1 < T_COUNT_1-1'b1) cnt1 <= cnt1 + 1'b1; else cnt1 <= 11'd0; end wire cnt1_done = (cnt1 == T_COUNT_1-1'b1); // count 1000 reg [9:0] cnt2; always @(posedge clk or negedge rst_n) begin if(rst_n == 1'b0) cnt2 <= 10'd0; else if(cnt2 < T_COUNT_2-1'b1) cnt2 <= cnt2 + 1'b1; else cnt2 <= 10'd0; end assign cnt_done = (cnt2 == T_COUNT_2-1'b1); endmodule //******************************End File************************************
綜合后資源消耗情況如圖4所示:
圖4 適當分解為小的計數(shù)器消耗的資源情況
<3>總結(jié):一般情況下,將一個大的計數(shù)器適當分解為小的計數(shù)器可以減少資源的消耗。