2 * yosys -- Yosys Open SYnthesis Suite
4 * Copyright (C) 2012 Clifford Wolf <clifford@clifford.at>
6 * Permission to use, copy, modify, and/or distribute this software for any
7 * purpose with or without fee is hereby granted, provided that the above
8 * copyright notice and this permission notice appear in all copies.
10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
23 #include "kernel/yosys.h"
29 int num_inputs
, num_outputs
, state_bits
, reset_state
;
30 struct transition_t
{ int state_in
, state_out
; RTLIL::Const ctrl_in
, ctrl_out
; };
31 std::vector
<transition_t
> transition_table
;
32 std::vector
<RTLIL::Const
> state_table
;
34 void copy_to_cell(RTLIL::Cell
*cell
)
36 cell
->parameters
["\\CTRL_IN_WIDTH"] = RTLIL::Const(num_inputs
);
37 cell
->parameters
["\\CTRL_OUT_WIDTH"] = RTLIL::Const(num_outputs
);
39 int state_num_log2
= 0;
40 for (int i
= state_table
.size(); i
> 0; i
= i
>> 1)
42 state_num_log2
= std::max(state_num_log2
, 1);
44 cell
->parameters
["\\STATE_BITS"] = RTLIL::Const(state_bits
);
45 cell
->parameters
["\\STATE_NUM"] = RTLIL::Const(state_table
.size());
46 cell
->parameters
["\\STATE_NUM_LOG2"] = RTLIL::Const(state_num_log2
);
47 cell
->parameters
["\\STATE_RST"] = RTLIL::Const(reset_state
);
48 cell
->parameters
["\\STATE_TABLE"] = RTLIL::Const();
50 for (int i
= 0; i
< int(state_table
.size()); i
++) {
51 std::vector
<RTLIL::State
> &bits_table
= cell
->parameters
["\\STATE_TABLE"].bits
;
52 std::vector
<RTLIL::State
> &bits_state
= state_table
[i
].bits
;
53 bits_table
.insert(bits_table
.end(), bits_state
.begin(), bits_state
.end());
56 cell
->parameters
["\\TRANS_NUM"] = RTLIL::Const(transition_table
.size());
57 cell
->parameters
["\\TRANS_TABLE"] = RTLIL::Const();
58 for (int i
= 0; i
< int(transition_table
.size()); i
++)
60 std::vector
<RTLIL::State
> &bits_table
= cell
->parameters
["\\TRANS_TABLE"].bits
;
61 transition_t
&tr
= transition_table
[i
];
63 RTLIL::Const const_state_in
= RTLIL::Const(tr
.state_in
, state_num_log2
);
64 RTLIL::Const const_state_out
= RTLIL::Const(tr
.state_out
, state_num_log2
);
65 std::vector
<RTLIL::State
> &bits_state_in
= const_state_in
.bits
;
66 std::vector
<RTLIL::State
> &bits_state_out
= const_state_out
.bits
;
68 std::vector
<RTLIL::State
> &bits_ctrl_in
= tr
.ctrl_in
.bits
;
69 std::vector
<RTLIL::State
> &bits_ctrl_out
= tr
.ctrl_out
.bits
;
72 bits_table
.insert(bits_table
.end(), bits_ctrl_out
.begin(), bits_ctrl_out
.end());
73 bits_table
.insert(bits_table
.end(), bits_state_out
.begin(), bits_state_out
.end());
74 bits_table
.insert(bits_table
.end(), bits_ctrl_in
.begin(), bits_ctrl_in
.end());
75 bits_table
.insert(bits_table
.end(), bits_state_in
.begin(), bits_state_in
.end());
79 void copy_from_cell(RTLIL::Cell
*cell
)
81 num_inputs
= cell
->parameters
["\\CTRL_IN_WIDTH"].as_int();
82 num_outputs
= cell
->parameters
["\\CTRL_OUT_WIDTH"].as_int();
84 state_bits
= cell
->parameters
["\\STATE_BITS"].as_int();
85 reset_state
= cell
->parameters
["\\STATE_RST"].as_int();
87 int state_num
= cell
->parameters
["\\STATE_NUM"].as_int();
88 int state_num_log2
= cell
->parameters
["\\STATE_NUM_LOG2"].as_int();
89 int trans_num
= cell
->parameters
["\\TRANS_NUM"].as_int();
91 if (reset_state
< 0 || reset_state
>= state_num
)
94 RTLIL::Const state_table
= cell
->parameters
["\\STATE_TABLE"];
95 RTLIL::Const trans_table
= cell
->parameters
["\\TRANS_TABLE"];
97 for (int i
= 0; i
< state_num
; i
++) {
98 RTLIL::Const state_code
;
99 int off_begin
= i
*state_bits
, off_end
= off_begin
+ state_bits
;
100 state_code
.bits
.insert(state_code
.bits
.begin(), state_table
.bits
.begin()+off_begin
, state_table
.bits
.begin()+off_end
);
101 this->state_table
.push_back(state_code
);
104 for (int i
= 0; i
< trans_num
; i
++)
106 auto off_ctrl_out
= trans_table
.bits
.begin() + i
*(num_inputs
+num_outputs
+2*state_num_log2
);
107 auto off_state_out
= off_ctrl_out
+ num_outputs
;
108 auto off_ctrl_in
= off_state_out
+ state_num_log2
;
109 auto off_state_in
= off_ctrl_in
+ num_inputs
;
110 auto off_end
= off_state_in
+ state_num_log2
;
112 RTLIL::Const state_in
, state_out
, ctrl_in
, ctrl_out
;
113 ctrl_out
.bits
.insert(state_in
.bits
.begin(), off_ctrl_out
, off_state_out
);
114 state_out
.bits
.insert(state_out
.bits
.begin(), off_state_out
, off_ctrl_in
);
115 ctrl_in
.bits
.insert(ctrl_in
.bits
.begin(), off_ctrl_in
, off_state_in
);
116 state_in
.bits
.insert(state_in
.bits
.begin(), off_state_in
, off_end
);
119 tr
.state_in
= state_in
.as_int();
120 tr
.state_out
= state_out
.as_int();
121 tr
.ctrl_in
= ctrl_in
;
122 tr
.ctrl_out
= ctrl_out
;
124 if (tr
.state_in
< 0 || tr
.state_in
>= state_num
)
126 if (tr
.state_out
< 0 || tr
.state_out
>= state_num
)
129 transition_table
.push_back(tr
);
133 void log_info(RTLIL::Cell
*cell
)
135 log("-------------------------------------\n");
137 log(" Information on FSM %s (%s):\n", cell
->name
.c_str(), cell
->parameters
["\\NAME"].decode_string().c_str());
139 log(" Number of input signals: %3d\n", num_inputs
);
140 log(" Number of output signals: %3d\n", num_outputs
);
141 log(" Number of state bits: %3d\n", state_bits
);
144 log(" Input signals:\n");
145 RTLIL::SigSpec sig_in
= cell
->getPort("\\CTRL_IN");
146 for (int i
= 0; i
< GetSize(sig_in
); i
++)
147 log(" %3d: %s\n", i
, log_signal(sig_in
[i
]));
150 log(" Output signals:\n");
151 RTLIL::SigSpec sig_out
= cell
->getPort("\\CTRL_OUT");
152 for (int i
= 0; i
< GetSize(sig_out
); i
++)
153 log(" %3d: %s\n", i
, log_signal(sig_out
[i
]));
156 log(" State encoding:\n");
157 for (int i
= 0; i
< GetSize(state_table
); i
++)
158 log(" %3d: %10s%s\n", i
, log_signal(state_table
[i
], false),
159 int(i
) == reset_state
? " <RESET STATE>" : "");
162 log(" Transition Table (state_in, ctrl_in, state_out, ctrl_out):\n");
163 for (int i
= 0; i
< GetSize(transition_table
); i
++) {
164 transition_t
&tr
= transition_table
[i
];
165 log(" %5d: %5d %s -> %5d %s\n", i
, tr
.state_in
, log_signal(tr
.ctrl_in
), tr
.state_out
, log_signal(tr
.ctrl_out
));
169 log("-------------------------------------\n");
172 // implemented in fsm_opt.cc
173 static void optimize_fsm(RTLIL::Cell
*cell
, RTLIL::Module
*module
);