Answers Database
Verilog one-hot state machine
Record #1299
Product Family: Software
Product Line: Synopsys
Problem Title:
Verilog one-hot state machine
Problem Description:
Here is an example state machine coded as a direct one-hot.
Solution 1:
The outputs are written as combinatorial. If you want to
register the outputs (so they change coincidently with the
state register), you can write then in terms of the
"next_state" vector (and then regsister them) instead of the
"state" vector as shown below:
/************************************************************\
* Verilog code for `dram_ras_ab' state machine *
\************************************************************/
module dram_ras_ab (clk,
rst,
dram_ras_go,
refresh_grt,
bank_a,
bank_b,
dram_ras_evn_ba,
dram_ras_odd_ba,
dram_ras_evn_bb,
dram_ras_odd_bb);
input clk,
rst,
dram_ras_go,
refresh_grt,
bank_a,
bank_b;
output dram_ras_evn_ba,
dram_ras_odd_ba,
dram_ras_evn_bb,
dram_ras_odd_bb;
reg [3:0] state, next_state;
parameter [1:0] RAS_IDLE_AB = 0,
RAS_BA = 1,
RAS_BB = 2,
RAS_ALL_AB = 3;
always @ (state or dram_ras_go or refresh_grt or
bank_a or bank_b)
begin
next_state = 4'b0; //set defaults
case (1'b1) //synopsys parallel_case full_case
state[RAS_IDLE_AB] :
if (dram_ras_go & !refresh_grt & bank_a)
next_state[RAS_BA] = 1'b1;
else if (dram_ras_go & !refresh_grt & bank_b)
next_state[RAS_BB] = 1'b1;
else if (dram_ras_go & refresh_grt)
next_state[RAS_ALL_AB] = 1'b1;
else
next_state[RAS_IDLE_AB] = 1'b1;
state[RAS_BA] :
if (dram_ras_go)
next_state[RAS_BA] = 1'b1;
else
next_state[RAS_IDLE_AB] = 1'b1;
state[RAS_BB] :
if (dram_ras_go)
next_state[RAS_BB] = 1'b1;
else
next_state[RAS_IDLE_AB] = 1'b1;
state[RAS_ALL_AB] :
if (dram_ras_go)
next_state[RAS_ALL_AB] = 1'b1;
else
next_state[RAS_IDLE_AB] = 1'b1;
endcase
end
// Decode outputs using the minimal number of state flops.
// For instance, if an output is active in states RAS_BA,
// RAS_BB and RAS_ALL_AB, write it as :
//
// assign out = ~RAS_IDLE_AB;
//
// instead of :
//
// assign out = (RAS_BA | RAS_BB | RAS_ALL_AB);
assign dram_ras_evn_ba = (state[RAS_BA] |
state[RAS_ALL_AB]);
assign dram_ras_odd_ba = (state[RAS_BA] |
state[RAS_ALL_AB]);
assign dram_ras_evn_bb = (state[RAS_BB] |
state[RAS_ALL_AB]);
assign dram_ras_odd_bb = (state[RAS_BB] |
state[RAS_ALL_AB]);
always @ (posedge clk or posedge rst)
begin
if (rst)
begin
state <= 4'b0000;
state[RAS_IDLE_AB] <= 1'b1;
end
else
state <= next_state;
end
endmodule
End of Record #1299
For the latest news, design tips, and patch information on the Xilinx design environment, check out the Xilinx Expert Journals! |