2011-10-28 38 views
4

我正在嘗試在verilog中創建一個計數器,計算出有多少個時鐘週期,並且在一千萬個時鐘週期後它將重置並重新開始。24位計數器狀態機

我創建了一個二十四位加法器模塊以及另一個包含二十四個D觸發器的模塊,用於存儲加法器輸出的週期數。

然後我想要一個處於計數狀態的狀態機,直到一千萬個週期過去,然後它進入重置狀態。

這聽起來是正確的?問題是我不知道如何實現狀態機。

任何人都可以指向我的網站/書籍,可以幫助我嗎?

謝謝

回答

3

你不需要狀態機。你已經在櫃檯上了。所有你需要做的是在這一點上

在僞代碼檢測你想和負載0包裝的價值到您的計數器:

if count == 10000000 then 
    nextCount = 0; 
else 
    nextCount = count + 1; 

......或者......

nextCount = count + 1; 
if count == 10000000 then 
    resetCount = 1; 
4

正如Paul S已經提到的,如果您希望計數器在溢出後繼續計數,則不需要狀態機。你可以這樣做(未經測試,可能包含錯別字):

module overflow_counter (
    clk, 
    reset, 
    enable, 
    ctr_out 
); 

// Port definitions 
input clk, reset, enable; 
output [23:0] ctr_out; 

// Register definitions 
reg [23:0] reg_ctr; 

// Assignments 
assign ctr_out = reg_ctr; 

// Counter behaviour - Asynchronous active-high reset 
initial reg_ctr <= 0; 
always @ (posedge clk or posedge reset) 
begin 
    if (reset)     reg_ctr <= 0; 
    else if (enable) 
    begin 
    if (reg_ctr == 10000000) reg_ctr <= 0; 
    else      reg_ctr <= reg_ctr + 1; 
    end 
end 

endmodule 

當然,通常你會使用參數,這樣你就不會得到你想要的滿溢計數器每次做一個自定義模塊。我會把它留給你;)。

[編輯]這裏有一些文件來幫助你與FSM。我只是搜查谷歌「的Verilog狀態機」:

我沒有看過第一篇論文,所以我不能對此作出評論。第二個顯示了各種不同風格的編碼FSM,其中3個總是塊風格,我強烈建議,因爲它更容易調試(狀態轉換和FSM輸出整齊分離)。該鏈接似乎是關閉的,所以這裏是the cached Google result

2

狀態機不是太棘手。使用localparam(寬度不要忘記寬度,這裏沒有顯示,因爲它只是一個位)來爲你的狀態定義標籤。然後創建兩個reg變量(state_reg,state_next)。變量_reg是您的實際註冊表。變量_next是一個「導線註冊」(一個可以分配到組合總是塊內的導線)。需要記住的兩件事是在連續always塊中的組合邏輯總塊(然後是組合邏輯的其餘部分)和X_reg <= X_next;中執行X_next = X_reg;。你可以喜歡特殊情況,但如果你堅持這些簡單的規則,那麼事情應該是正常的。我嘗試不使用實例化來實現像加法器這樣的非常簡單的事情,因爲Verilog對加法器有很大的支持。

由於我使用FPGA,我將初始值分配給我的寄存器,並且我不使用復位信號。我不確定,但是對於ASIC設計,我認爲情況正好相反。

localparam STATE_RESET = 1'b0, STATE_COUNT = 1'b1; 

reg [23:0] cntr_reg = 24'd0, cntr_next; 
reg state_reg = STATE_COUNT, state_next; 

always @* begin 
    cntr_next = cntr_reg; // statement not required since we handle all cases 
    if (cntr_reg == 24'd10_000_000) 
     cntr_next = 24'd0; 
    else 
     cntr_next = cntr_reg + 24'd1; 
    state_next = state_reg; // statement required since we don't handle all cases 
    case (state_reg) 
     STATE_COUNT: if (cntr_reg == 24'd10_000_000) state_next = STATE_RESET; 
    endcase 
end 

always @(posedge clk) begin 
    cntr_reg <= cntr_next; 
    state_reg <= state_next; 
end 

我發現this book是非常有幫助的。這本書還有一個VHDL版本,所以你可以並排使用它作爲Rosetta Stone來學習VHDL。

+0

我看不出你的例子中狀態是怎樣完成的。沒有什麼依賴於它。如果該代碼放置在FPGA中,合成器將優化與狀態相關的代碼。 – Darhuuk

+0

我回答了原來的問題。 –