One ring sequencer advances on step and returns to S0 on abort. Three outputs report busy (not in S0), last (S7) and odd (S1, S3, S5 or S7).
Three coded versions run under one testbench with random stimulus. Outputs must match on every cycle, and the full code sits under Testbench below.
The counts below come from the recipe further down (synth -top <module> -nofsm; stat, generic gate mapping, FSM recoding disabled). Flip-flops are the $_DFFE_* cells; logic gates are every other cell.
Encoding | Flip-flops | Logic gates | Total cells |
|---|---|---|---|
Binary | 3 | 11 | 14 |
Gray | 3 | 12 | 15 |
One-hot | 8 | 13 | 21 |
These are generic cell counts, not silicon area or delay. In this table one-hot uses the most flops and, for this tiny ring, slightly more logic cells too: its simple output decode does not pay back the per-bit next-state logic. Cell sizes, fan-in, fanout and wiring can reverse the physical ranking. No speed winner follows from these counts.
Use only the three design modules from the listing below as enc.sv (exclude tb_enc). Run each top from a fresh Yosys invocation. Record the source revision/hash, yosys -V, complete command and log. The built-in generic gate mapping has no target Liberty library or device; synth already invokes ABC, so do not count a second mapping pass as the same experiment.
yosys -V
yosys -p 'read_verilog -sv enc.sv; synth -top seq_bin -nofsm; stat' > seq_bin.log
yosys -p 'read_verilog -sv enc.sv; synth -top seq_gray -nofsm; stat' > seq_gray.log
yosys -p 'read_verilog -sv enc.sv; synth -top seq_onehot -nofsm; stat' > seq_onehot.logFor a speed decision, repeat with the actual FPGA part/flow or ASIC Liberty/corner and physical flow. Hold clock period, I/O delays, output loads, reset constraints and optimization settings constant; record encoding reports, flop/LUT or area totals, worst path endpoints, delay/slack and routing stage. Compare state-to-state and state-to-output paths, not just gate totals. Your counts can differ with another Yosys version. See the primary Yosys synth command reference.
Each state bit's next-state logic depends only on its own predecessors and guards, and a single-state output is one bit. On a larger FSM with sparse transitions, that can keep the logic in front of each flop shallow, while a binary code needs a full decode of every state bit. Whether it actually wins must be measured on the target flow.
Sparse incoming transitions can give shallow per-bit next-state logic. Many predecessors or complex guards add AND/OR depth and routing load; depth is not constant for arbitrary FSMs.
Single-state output decode can be just a bit: last is s[7]. Combined outputs such as odd still require an OR network, and even a wire has fanout and routing cost.
Platform resources matter: try one-hot where the target has available registers and binary decode is the reported bottleneck. Compare mapped resource use and timing before choosing; FPGA/ASIC labels alone do not select a winner.
The listing audits hold, advance, wrap, abort and reset transitions from every state, then checks identical outputs over 20000 random cycles. Only ring advances guarantee one Gray bit changes; aborts explicitly demonstrate multiple-bit changes.
module seq_bin (
input logic clk, rst_n, step, abort,
output logic busy, last, odd
);
typedef enum logic [2:0] {S0, S1, S2, S3, S4, S5, S6, S7} state_t;
state_t state, next;
always_comb begin
next = state;
if (abort) next = S0;
else if (step) unique case (state)
S0: next = S1; S1: next = S2; S2: next = S3; S3: next = S4;
S4: next = S5; S5: next = S6; S6: next = S7; S7: next = S0;
endcase
end
always_ff @(posedge clk or negedge rst_n)
if (!rst_n) state <= S0; else state <= next;
assign busy = (state != S0);
assign last = (state == S7);
assign odd = (state == S1) || (state == S3) || (state == S5) || (state == S7);
endmodule
module seq_onehot (
input logic clk, rst_n, step, abort,
output logic busy, last, odd
);
logic [7:0] s; // s[i] = 1 means "in state Si"
always_ff @(posedge clk or negedge rst_n)
if (!rst_n) s <= 8'b0000_0001;
else if (abort) s <= 8'b0000_0001;
else if (step) s <= {s[6:0], s[7]}; // rotate: S0 -> S1 -> ... -> S7 -> S0
assign busy = !s[0];
assign last = s[7];
assign odd = s[1] | s[3] | s[5] | s[7];
endmodule
module seq_gray (
input logic clk, rst_n, step, abort,
output logic busy, last, odd
);
// 3-bit Gray sequence: consecutive states differ in exactly one bit
localparam logic [2:0] G0 = 3'b000, G1 = 3'b001, G2 = 3'b011, G3 = 3'b010,
G4 = 3'b110, G5 = 3'b111, G6 = 3'b101, G7 = 3'b100;
logic [2:0] s;
always_ff @(posedge clk or negedge rst_n)
if (!rst_n) s <= G0;
else if (abort) s <= G0;
else if (step) begin
case (s)
G0: s <= G1; G1: s <= G2; G2: s <= G3; G3: s <= G4;
G4: s <= G5; G5: s <= G6; G6: s <= G7; default: s <= G0;
endcase
end
assign busy = (s != G0);
assign last = (s == G7);
assign odd = (s == G1) || (s == G3) || (s == G5) || (s == G7);
endmodule
Cell counts (binary 3 flip-flops and 11 logic gates, Gray 3 and 12, one-hot 8 and 13) come from Yosys 0.69, run 2026-10-16 with synth -top <module> -nofsm; stat, generic gate mapping and FSM recoding disabled. They contain no target timing evidence.