конечные автоматы не слишком хитры. Используйте localparam (с шириной, не забудьте про ширину, не показанную здесь, потому что она всего один бит), чтобы определить метки для ваших состояний. Затем создайте две переменные reg (state_reg
, state_next
). Переменная _reg
является вашим фактическим регистром. Переменная _next
представляет собой «проводной регистр» (провод, который можно назначить внутри комбинационного всегда блока). Следует запомнить две вещи: X_next = X_reg;
в комбинационном блоке всегда (а затем и в остальной части комбинационной логики) и X_reg <= X_next;
в последовательном блоке всегда. В особых случаях вы можете полюбить себя, но если вы будете придерживаться этих простых правил, то все должно сработать. Я стараюсь не использовать создание экземпляров для очень простых вещей, таких как сумматоры, поскольку Verilog прекрасно поддерживает сумматоры.
Поскольку я работаю с ПЛИС, я назначаю начальные значения своим регистрам и не использую сигнал сброса. Я не уверен, но для дизайна 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
Я нашел эту книгу очень полезной. Существует также версия книги на VHDL, так что вы можете использовать их как Rosetta Stone для изучения VHDL.