YosysのPassを見てみたい。Yosysのリポジトリにおいて、以下のようなディレクトリにPassが配置してある。
. ├── cmds ├── equiv ├── fsm ├── hierarchy ├── memory ├── opt ├── pmgen ├── proc ├── sat ├── techmap └── tests 11 directories, 0 files
例えば、fsm_detect
を見てみることにした。
fsm/fsm_detect.cc
struct FsmDetectPass : public Pass { FsmDetectPass() : Pass("fsm_detect", "finding FSMs in design") { } void help() override { // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| log("\n"); log(" fsm_detect [selection]\n"); log("\n"); log("This pass detects finite state machines by identifying the state signal.\n"); log("The state signal is then marked by setting the attribute 'fsm_encoding'\n"); log("on the state signal to \"auto\".\n"); log("\n"); log("Existing 'fsm_encoding' attributes are not changed by this pass.\n"); log("\n"); log("Signals can be protected from being detected by this pass by setting the\n"); log("'fsm_encoding' attribute to \"none\".\n"); log("\n"); }
例えば、以下のようなfsm.sv
を作って動作を検証してみる。
module fsm ( input logic i_clk, input logic i_reset, input logic in, output logic out ); typedef enum logic [ 1: 0] { INIT = 0, ST0 = 1, ST2 = 2, ST3 = 3 } state_t; state_t r_state; always_ff @ (posedge i_clk, posedge i_reset) begin if (i_reset) begin r_state <= INIT; end else begin case (r_state) INIT : if ( in) begin r_state <= ST0; end ST0 : if (!in) begin r_state <= ST2; end ST2 : if ( in) begin r_state <= ST3; end ST3 : if (!in) begin r_state <= INIT; end default : r_state <= INIT; endcase // case (r_statet) end // else: !if(i_reset) end // always_ff @ (posedge i_clk, posedge i_reset) assign out = (r_state == ST3); endmodule // fsm
Yosysの実行コマンドfsm_detect
を追加して合成を実行する。
5. Executing FSM_DETECT pass (finding FSMs in design). Found FSM state register fsm.r_state.
ソースコードを読んでみると、どうやらツリーのつながり方からFSMを認識しているようだが、どうなっているのか詳細はまだ見ていない。ちょっと調べてみよう。