FPGA 設計 Verilog 基礎(二)
阿新 • • 發佈:2018-12-16
1.1 狀態機設計
狀態機是許多數字系統的核心部件,是一類重要的時序邏輯電路。通常包括三個部分:一是下一個狀態的邏輯電路,二是儲存狀態機當前狀態的時序邏輯電路,三是輸出組合邏輯電路。通常,狀態機的狀態數量有限,成為有限狀態機(FSM)。由於狀態機的所有觸發器的時鐘由同一脈衝邊沿觸發,故也稱之位有限狀態機。
根據狀態機的輸出訊號是否與電路的輸入有關分為Mealy型狀態機和Moore型狀態機。電路的輸出訊號不僅與電路的當前狀態有關,還與電路的輸入有關,稱為Mealy型狀態機。相反,電路的輸出僅僅與各觸發器的狀態有關,不受電路輸入訊號的影響,稱為Moore型狀態機。其標準模型如下所示:
狀態機的狀態轉移圖,通常可以根據輸入和內部條件畫出。一般來說,狀態機的設計包括以下設計步驟:
- 根據需求和設計原則,確定是Mealy型還是Moore型狀態機。
- 分析狀態機的所有狀態,對每一狀態選擇合適的編碼方式,進行編碼。
- 根據狀態轉移關係和輸出繪出狀態轉移圖。
- 構建何使的狀態機結構,對狀態機進行硬體描述。
狀態機的描述通常由三種描述方法,稱為一段式狀態,二段式狀態機和三段式狀態機。狀態機的描述通常包括以下四個部分:
- 利用引數定義語句parameter 描述狀態機的各個狀態名稱,即狀態編碼。狀態編碼通常有很多種方法,包括自然二進位制編碼、One-hot編碼、格雷編碼等。
- 用時序的always 塊描述狀態觸發器實現狀態儲存。
- 使用敏感表和case語句(也可採用if-else)描述狀態轉換邏輯。
- 描述狀態機的輸出邏輯。
下面根據狀態機的三種方法,來比較各種方法的優劣。
1.2 一段式狀態機
`timescale 1ns / 1ps module detect_1( input clk_i, input rst_n_i, output out_o ); reg out_r; //狀態宣告和狀態編碼 reg [1:0] state; parameter [1:0] S0 = 2'b00; parameter [1:0] S1 = 2'b01; parameter [1:0] S2 = 2'b10; parameter [1:0] S3 = 2'b11; //一段式狀態機 always @(posedge clk_i) begin if(!rst_n_i) begin state <= S0; out_r <= 1'b0; end else case(state) S0: begin out_r <= 1'b0; state <= S1; end S1: begin out_r <= 1'b1; state <= S2; end S2: begin out_r <= 1'b0; state <= S3; end S3: begin out_r <=1'b1; state <= S0; end endcase end assign out_o = out_r; endmodule
1.3 兩段式狀態機
`timescale 1ns / 1ps
//兩段式狀態機
module detect_2(
input clk_i,
input rst_n_i,
output out_o
);
reg out_r;
//狀態宣告和狀態編碼
reg [1:0] Current_state;
reg [1:0] Next_state;
parameter [1:0] S0 = 2'b00;
parameter [1:0] S1 = 2'b01;
parameter [1:0] S2 = 2'b10;
parameter [1:0] S3 = 2'b11;
//時序邏輯:描述狀態轉換
always @(posedge clk_i)
begin
if(!rst_n_i)
Current_state <= 0;
else
Current_state <= Next_state;
end
always @(*)
begin
out_r =1'b0;
case(Current_state)
S0:
begin
out_r = 1'b0;
Next_state = S1;
end
S1:
begin
out_r = 1'b1;
Next_state = S2;
end
S2:
begin
out_r =1'b0;
Next_state = S3;
end
S3:
begin
out_r = 1'b0;
Next_state = Next_state;
end
default:
begin
out_r =1'b0;
Next_state = S0;
end
endcase
end
endmodule
1.4 三段式狀態機
`timescale 1ns / 1ps
module detect_3(
input clk_i,
input rst_n_i,
output out_o
);
reg out_r;
//狀態宣告和狀態編碼
reg [1:0] Current_state;
reg [1:0] Next_state;
parameter [1:0] S0 = 2'b00;
parameter [1:0] S1 = 2'b01;
parameter [1:0] S2 = 2'b10;
parameter [1:0] S3 = 2'b11;
//時序邏輯:描述狀態轉換
always @(posedge clk_i)
begin
if(!rst_n_i)
Current_state <= 0 ;
else
Current_state <= Next_state;
end
//組合邏輯:描述下一狀態
always @(*)
begin
case(Current_state)
S0:
begin
Next_state <= S1;
end
S1:
begin
Next_state <= S2;
end
S2:
begin
Next_state <= S3;
end
S3:
begin
Next_state <= Next_state;
end
default:
Next_state = S0;
endcase
end
//輸出邏輯
always @(posedge clk_i)
begin
if(!rst_n_i)
out_r <= 1'b0;
else
begin
case(Current_state)
S0,S2:
out_r <= 1'b0;
S1,S3:
out_r <= 1'b1;
default:
out_r <= out_r;
endcase
end
end
endmodule