verilog編程,可能你一直在錯誤地使用計數器cnt

計數器是verilog編程中非常常用的一種技巧,但是我們如果是C等語言的編程思維則極有可能錯誤地使用計數器。下面舉個例子:

module delay (
	input clk_sys,  //系統時鐘
	input rst_n,
	output reg [31:0] time_cnt         
);
parameter DELAY_TIME = 32'd50; //計數總時鐘個數
reg [31:0] time_cnt_r;

//組合電路,實現計數器自增1
always @(*) begin
	if(time_cnt == DELAY_TIME) 
		time_cnt_r = 32'h1;
	else 
		time_cnt_r = time_cnt_r + 1;

end
//時序電路,實現同步輸出到端口
always @(posedge clk_sys or negedge rst_n) begin
	if(!rst_n) 
		time_cnt <= 32'h0;
	else 
		time_cnt <= time_cnt_r;
end

endmodule
該模塊實現對系統時鐘的計數,計數到50個時鐘個數則清零重新開始計數。代碼中
time_cnt_r = time_cnt_r + 1;

這條語句大家並不陌生,在C語言裏,典型的計數方式。

我們使用quartus編譯綜合得出的電路:


是不是感覺有點複雜。我們把代碼稍微變一下,把上面那條計數器自增1代碼改成:

time_cnt_r = time_cnt + 1;
再次編譯綜合,得到的RTL電路如下:


電路竟然變得如此簡潔,更重要的是節省了很多很多的buf資源:


仔細對比兩條計數器自增1代碼,發現區別在於:前面一個是計數器+1後賦值給自己,而後面一個是計數器+1後賦值給另外一個臨時計數器。

一個小小的改動,結果相差這麼大,值得深思。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章