今天開始幾天會來分享一些coding style,並舉大量的例子,在一些例子當中或許有些是我自己的習慣,不過也分享給大家,如果有不同的觀點也歡迎大家分享.
那這邊就從基本的開始說吧.
-變數名稱:
每種程式語言這點其實都差不多,為了增加程式的可讀性,變數名稱命名就非常重要,曾經看過有人變數全部都取xyz,導致交接給下面的人時完全不知道電路的訊號會怎麼跑,所以為了自己方便debug也方便別人,名字命名要留意一下,尤其是FSM的state名稱更為重要.
-給值的方法:
之前有提過blocking & nonblocking,在同一個always block裡面只能選一種,不能混用,然後同一個變數只能在同一個always block出現,各舉一個錯誤的例子給大家看
混用的錯誤例子:
always@(posedge clk)begin
if(reset)
counter <= 0;
else
counter = counter + 1;
end
出現在不同的always block的錯誤例子:
always@(posedge clk)begin
if(reset)
counter <= 0;
end
always@(posedge clk)begin
counter <= counter + 1;
end
-給初始值
一般來說,在寫軟體的程式語言時,習慣在宣告變數時給初始值(ex:0),但在電路當中,我們會在適合的時機給初始值,何謂適合的時機,像是電路重置(reset)的時候,或者是在特定的FSM的某一個state中(ex:IDLE),比較少看到在宣告時給,或許現在的合成器變得比較聰明,或特殊處理,不過還是建議大家記得要給初始值.
-不要寫在同一個always block
這點非常的重要(個人認為),因為看過很多人包括我自己,在剛學verilog時很喜歡把全部的變數寫在同一個always block中,造成可讀性降低,只要遇到bug就會非常難找,如果還是寫組合邏輯,可能會產生許多latch(明天或後天介紹)導致一些不可預期的錯誤.
錯誤的例子:
always@(posedge clk)begin
if(rst)begin
a <= 0;
b <= 0;
c <= 0;
end
else if(condition1)
a <= b;
else if(condition2)
c <= a;
else if(condition3)
b <= a + c;
end
應該更正為:
always@(posedge clk)begin
if(rst)
a <= 0;
else if(condition1)
a <= b;
end
always@(posedge clk)begin
if(rst)
b <= 0;
else if(condition3)
b <= a + c;
end
always@(posedge clk)begin
if(rst)
c <= 0;
else if(condition2)
c <= a;
end
也不一定不同變數一定要拆開來寫,我個人習慣是當變數在相同情況的判斷是都要改變值時,就會把它寫在同一個always block裡面,像是
always@(posedge clk)begin
if(state == IDLE)begin
out_valid <= 0;
output_data <= 0;
end
else if(state == FINISH)begin
out_valid <= 1;
output_data <= data;
end
else begin
out_valid <= 0;
output_data <= 0;
end
end
類似這樣,也沒有說一定要照這樣寫,就依個人習慣,畢竟就算全部擠在一起電路一樣能work,就只是當要看起來比較沒那麼整齊.
明天再繼續分享其他部分給大家囉~