State cars are not too complicated. Use localparam (with a width, don't forget the width not shown here because it is just one bit) to define labels for your states. Then create two reg variables ( state_reg
, state_next
). The _reg
variable is your actual case. The _next
variable is a "wired river" (a wire that can be assigned inside a combinational always block). Two things to remember are to do X_next = X_reg;
always in a combinational block (and then the rest of the combinational logic) and X_reg <= X_next;
always in sequential block. You may get imagination for special occasions, but if you follow these simple rules, then everything should work. I try not to use the instance for very simple things like adders, since Verilog is great at adding support.
Since I work with FPGA, I assign initial values ββto my registers, and I do not use the reset signal. I'm not sure, but for ASIC design, I think it's the other way around.
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
I found this book to be very useful. There is also a version of the VHDL book, so you can use both side by side and Rosetta Stone to learn VHDL.
source share