昨天介紹完 有限狀態機(Finite State Machine) 之後,今天來用一個電路實作給大家看,題目就是費伯納西數列(Fibonacci number),input output規格如下:
所以我們在寫電路之前先把架構想好,因為不是非常的複雜,所以就把FSM想好就好,那一個state該做什麼事情,那今天就用我的想法來實作.
沿用昨天畫的圖,就拿這個當我的FSM,再來是程式碼部分:
module Fibonacci (
input clk,
input reset,
input [7:0]in_level,
input in_valid,
output reg out_valid,
output reg [7:0]result
);
parameter[1:0] IDLE = 0, CALCULATE = 1, COMPLETE = 2;
reg[1:0]Q, Q_NEXT;
reg[31:0]f1;
reg[31:0]f2;
reg [7:0]in_level_r;
wire done;
//FSM begin
always@(posedge clk)begin
if(reset)
Q <= IDLE;
else
Q <= Q_NEXT;
end
always@(*)begin
case(Q)
IDLE:
if(in_valid) Q_NEXT = CALCULATE;
else Q_NEXT = IDLE;
CALCULATE:
if(done) Q_NEXT = COMPLETE;
else Q_NEXT = CALCULATE;
COMPLETE:
Q_NEXT = IDLE;
default:
Q_NEXT = IDLE;
endcase
end
//FSM end
assign done = (in_level_r-1 == 0);
//signal controller
always@(posedge clk)begin
case(Q)
IDLE:
in_level_r <= (in_valid) ? in_level : in_level_r;
CALCULATE:
in_level_r <= in_level_r-1;
COMPLETE:
in_level_r <= 0;
endcase
end
always@(posedge clk)begin
case(Q)
IDLE:begin
result <= 0;
out_valid <= 0;
end
CALCULATE:
result <= f2;
COMPLETE:
out_valid <= 1;
endcase
end
always@(posedge clk)begin
case(Q)
IDLE:begin
f1 <= 1;
f2 <= 1;
end
CALCULATE:begin
f1 <= f1 + f2;
f2 <= f1;
end
endcase
end
endmodule
為了增加可讀性,所以會幫每一個state取名字,所以會用parameter這個關鍵字宣告,上面程式可以看到說,每個變數都會依造不同的state去做不同的事情,所以我們只要控制好state,基本上電路就不會有太大的問題,那我來簡單介紹一下我寫的電路,一開始我會讓state停在IDLE等待input訊號,當要算的訊號進來之後我就跳到COMPUTE 這個state,接下來依照公式做累加,(大家都學過組合邏輯跟循序邏輯了,所以<=這符號應該知道怎麼用了,還不知道的可以往前面幾天複習),所以我會設一個done的flag,就是當我的level等於0時就代表算完了,那就可以跳到COMPLETE state去做輸出,因為輸出只要一個clock cycle,所以輸出完直接跳IDLE等待下一個input,那寫一個簡單的testbench給大家看:
for(i=0;i<10;i=i+1)begin
in_valid = 1;
in_level = ($random(seed) % 'd10) +1;
$display("data level = %d\n",in_level);
@(posedge clk);
in_valid = 0;
in_level = 0;
while(out_valid != 1)begin
@(posedge clk);
end
$display("result = %d\n\n",result);
end
repeat(10)@(posedge clk);
$finish;
隨機產生10個random的input值,來看一段波形圖跟結果:
大家可以看到當in_valid = 1時會給要算哪層level的值,接下來我有把Q這個FSM抓出來看,所已拿完input值後會開始運算,於是就跳到COMPUTE,算完到DONE且把out_valid設為1並輸出結果值,大家可以參考一下波形圖唷.
今天先到這邊,明天開始幾天會來分享一下verilog的coding style,有興趣的朋友們可以來看看喔.