fpga設計技巧:
1:一款好用的編輯軟體:
其實我們完全可以使用vivadao或者quartus自帶的編輯**軟體。這兩個我都用過,但是說實在的我是都用過了,著實一搬般。然後推薦一下我一直在用的編輯軟體:notepaid++。體積小,外掛程式多,字型可調,語法高亮。
2:verilog基本語法:
現在我們來複習一下verilog的基本語法吧:
module…endmodule(每個模組,必不可少的)
input output inout (埠宣告語句)
wire reg (宣告資料型別,預設是wire型)
parameter (常量定義)
if…else if…else…(條件判斷語句)
!= , == , >= (等邏輯判斷條件)
case…default…endcase(狀態機)
always (塊)
task…endtask(任務語句)
3:if…else 和 case 的區別:
其實二者之間並沒有區別。形式上來看,if…esle 有明顯優先順序,case 則是並行執行的。但是現階段,綜合邏輯的功能足夠強大,那麼兩者之間就沒有明顯的區別了,所消耗的資源和執行的速度是一樣的。注意一下case 是可以用拼接的形式做組合的。少用優先順序的語句,因為他們更加的占用資源。
4:inout:
inout 其使用的比較少,需要注意的是,我們不能同時把inout 即作為輸入,又同時作為輸出。
5:4輸入lut結構
這個涉及到查詢表的相關知識,就是我們應該如何最大限度的發揮fpga的能力,充分的利用fpga的資源。四個輸入當然是最大程度的利用了資源,但是我們在實際的使用過程中很難真的滿足這個需求。
6:狀態機的設計
什麼是狀態機,其實簡單來說,我認為就是描述狀態變化的邏輯電路。很典型的就是sdram控制器的設計,我們需要控制sdram的不同狀態滿足sdram(idel,wr,rd)的不同設計功能。
狀態機又分為:一段式狀態機,二段式狀態機,三段式狀態機。單純從形式上來區分的:那就是看有幾個always塊了,但是請搞清楚他們之間最顯著的區別在於內在的邏輯:
一段式狀態機(邏輯簡單,大包大攬,不利維護,最好不用):
always@(posedge clk or negedge rst)if(
!rst)begin
cstate <= idel;
cmd <=
3'b111;
endelse
case
(cstate)
idel:
if(wr_req)begin
cstate <= wr_s1;
cmd <=
3'b011;
endelse
if(rd_req)begin
cstate <= rd_s1;
cmd <=
3'b011;
endelse begin
cstate <= idel;
cmd <=
3'b111;
endwr_s1:
begin
cstate <= wr_s2;
cmd <=
3'b101;
endwr_s2:
begin:
cstate <= idel;
cmd <=
3'b111;
endrd_s1:
if(wr_req)begin
cstate <= wr_s2;
cmd <=
3'b101;
endelse begin
cstate <= rd_s2;
cmd <=
3'b110;
endrd_s2:
if(wr_req)begin
cstate <= wr_s1;
cmd <=
3'b011;
endelse begin
cstate <= idel;
cmd <=
3'b111;
end
default
: cstate <= idel;
endcase
二段式狀態機(最常使用的,好維護):
always@(posedge clk or negedge rst) begin
case
(cstate)
idel:
if(wr_req)begin
nstate <= wr_s1;
cmd <=
3'b011;
endelse
if(rd_req)begin
nstate <= rd_s1;
cmd <=
3'b011;
endelse begin
nstate <= idel;
cmd <=
3'b111;
endwr_s1:
begin
nstate <= wr_s2;
cmd <=
3'b101;
endwr_s2:
begin:
nstate <= idel;
cmd <=
3'b111;
endrd_s1:
if(wr_req)begin
nstate <= wr_s2;
cmd <=
3'b101;
endelse begin
nstate <= rd_s2;
cmd <=
3'b110;
endrd_s2:
if(wr_req)begin
nstate <= wr_s1;
cmd <=
3'b011;
endelse begin
nstate <= idel;
cmd <=
3'b111;
end
default
: nstate <= idel;
endcase
end
三段式狀態機(比較常用,好維護):
reg [3:
0] cstate;
reg [3:
0] nstate;
always@(posedge clk or negedge rst)if(
!rst)
cstate <= idel;
else
cstate <= nstate;
always@(posedge clk or negedge rst)begin
case
(cstate)
idel:
if(wr_req)
nstate <= wr_s1;
else
if(rd_req)
nstate <= rd_s1;
else
nstate <= idel;
wr_s1:
nstate <= wr_s2;
wr_s2:
nstate <= idel;
rd_s1:
if(wr_req)
nstate <= wr_s2;
else
nstate <= rd_s2;
rd_s2:
if(wr_req)
nstate <= wr_s1;
else
nstate <= rd_s1;
default
: nstate <= idel;
endcase
endalways@(posedge clk or negedge rst) begin
case
(nstate)
idel:
if(wr_req)begin
cmd <=
3'b011;
endelse
if(rd_req)begin
cmd <=
3'b011;
endelse begin
cmd <=
3'b111;
endwr_s1:
begin
cmd <=
3'b101;
endwr_s2:
begin:
cmd <=
3'b111;
endrd_s1:
if(wr_req)begin
cmd <=
3'b101;
endelse begin
cmd <=
3'b110;
endrd_s2:
if(wr_req)begin
cmd <=
3'b011;
endelse begin
cmd <=
3'b111;
end
default
: nstate <= idel;
endcase
end
總結:
我以乙個比較通俗易懂的方式來講解一下這幾種狀態機的區別:假設我們他們分為三個部分:當前狀態,下乙個狀態,執行操作。
一段式狀態機:當前狀態是什麼執行什麼什麼操作,這兩個部分直接寫在了一起,這樣導致的結果就是**的維護性非常的差。
二段式狀態機:就是用下乙個狀態的暫存器鎖存當前的狀態,然後將這個暫存器和執行操作寫在一起。這樣增強了**的可讀性。
三段式狀態機: 則是將三個部分都分來來寫。
FPGA學習筆記第三彈
fpga學習筆記第三彈 1 同步復位和非同步復位 說實話這個問題在我沒有看書時候,我一直以為是一樣的沒有什麼區別。那他們到底有何不同之處呢 同步復位的邏輯 always posedge clk if rst b 0 else a b 非同步復位邏輯 always posedge clk or neg...
FPGA學習筆記第五彈
fpga學習筆記第五彈 基於fpga的跨時鐘域訊號處理 在實際設計中我們一般會遇到很多關於時鐘域處理的問題,越是複雜的fpga設計,越是存在很多關於跨時鐘處理的問題。如何解決跨時鐘域帶來的問題 1 同步處理 先寄存乙個時鐘週期在使用 2 利用儲存器 fifo 握手訊號 什麼是握手訊號 所謂的握手訊號...
Python學習第二彈
編碼 unicode utf 8 gbk 關係 關鍵字 1.continue 終止當前迴圈,進行下一次迴圈 2.break 終止迴圈 題6 使用者登入 三次機會充實 count 0 while count 3 user input 請輸入使用者名稱 pwd input 請輸入密碼 if user l...