Im just starting to learn how to code in Verilog. Can anyone help me figure out how to implement the following code in verilog using one-hot encoding
module Controller(b, x, clk, rst);
input b, clk, rst;
output x;
reg x;
parameter Off = 2'b00,
On1 = 2'b01,
On2 = 2'b10,
On3 = 2'b11;
reg [1:0] currentstate;
reg [1:0] nextstate;
//state register
always @ (posedge rst or posedge clk)
begin
if(rst==1)
currentstate <= Off;
else
currentstate <= nextstate;
end
//combinational
always @ (*)
begin
case (currentstate)
Off: begin
x <= 0;
if(b==0)
nextstate <= Off;
else
nextstate <= On1;
end
On1 : begin
x <= 1;
nextstate <= On2;
end
On2 : begin
x <= 1;
nextstate <= On3;
end
On3 : begin
x <= 1;
nextstate <= Off;
end
endcase
end
I tried changing the parameters to:
parameter Off = 4'b0001,
On1 = 4'b0010,
On2 = 4'b0100,
On3 = 4'b1000;
However, ive read that this is not a good implementations.
Some of the advantages of onehot encoding in FSMs are as follows:
- Low switching activity. Since only single bit is switched at a time, the power consumption is less and it is less prone to glitches.
- Simplified encoding. One can determine the state just by looking at the bit position of '1' in the current state variable.
The disadvantage of this technique is that it requires more number of flops. So, if one has a FSM with 10 different states, one needs 10 flops, while one needs only 4 flops when using decimal encoding.
Coming to your question, it is simple to change to onehot encoded FSM. One needs to implement a case
statement based on the position of 1
in the currentstate
variable. The code snippet can be implemented as follows:
parameter Off = 2'b00,
On1 = 2'b01,
On2 = 2'b10,
On3 = 2'b11;
//...
always @ (*)
begin
nextstate = 4'b0000;
case (1'b1)
currentstate[Off] : begin
x = 0;
if(b==0)
nextstate[Off] = 1'b1;
else
nextstate[On1] = 1'b1;
end
currentstate[On1] : begin
x = 1;
nextstate[On2] = 1'b1;
end
//...
A simple example is available at this link and explanation is over here. Cummings paper is also a good source for more info.
EDIT: As @Greg pointed out, it was a copy-paste error. A combinational block must use blocking assignments.