我正在嘗試在verilog中創建一個計數器,計算出有多少個時鐘週期,並且在一千萬個時鐘週期後它將重置並重新開始。24位計數器狀態機
我創建了一個二十四位加法器模塊以及另一個包含二十四個D觸發器的模塊,用於存儲加法器輸出的週期數。
然後我想要一個處於計數狀態的狀態機,直到一千萬個週期過去,然後它進入重置狀態。
這聽起來是正確的?問題是我不知道如何實現狀態機。
任何人都可以指向我的網站/書籍,可以幫助我嗎?
謝謝
我正在嘗試在verilog中創建一個計數器,計算出有多少個時鐘週期,並且在一千萬個時鐘週期後它將重置並重新開始。24位計數器狀態機
我創建了一個二十四位加法器模塊以及另一個包含二十四個D觸發器的模塊,用於存儲加法器輸出的週期數。
然後我想要一個處於計數狀態的狀態機,直到一千萬個週期過去,然後它進入重置狀態。
這聽起來是正確的?問題是我不知道如何實現狀態機。
任何人都可以指向我的網站/書籍,可以幫助我嗎?
謝謝
你不需要狀態機。你已經在櫃檯上了。所有你需要做的是在這一點上
在僞代碼檢測你想和負載0包裝的價值到您的計數器:
if count == 10000000 then
nextCount = 0;
else
nextCount = count + 1;
......或者......
nextCount = count + 1;
if count == 10000000 then
resetCount = 1;
正如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。
狀態機不是太棘手。使用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。
我看不出你的例子中狀態是怎樣完成的。沒有什麼依賴於它。如果該代碼放置在FPGA中,合成器將優化與狀態相關的代碼。 – Darhuuk
我回答了原來的問題。 –