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/rtlil.h"
24 #include "kernel/log.h"
28 int num_inputs
, num_outputs
, state_bits
, reset_state
;
29 struct transition_t
{ int state_in
, state_out
; RTLIL::Const ctrl_in
, ctrl_out
; };
30 std::vector
<transition_t
> transition_table
;
31 std::vector
<RTLIL::Const
> state_table
;
33 void copy_to_cell(RTLIL::Cell
*cell
)
35 cell
->parameters
["\\CTRL_IN_WIDTH"] = RTLIL::Const(num_inputs
);
36 cell
->parameters
["\\CTRL_OUT_WIDTH"] = RTLIL::Const(num_outputs
);
38 int state_num_log2
= 0;
39 for (int i
= state_table
.size(); i
> 0; i
= i
>> 1)
41 state_num_log2
= std::max(state_num_log2
, 1);
43 cell
->parameters
["\\STATE_BITS"] = RTLIL::Const(state_bits
);
44 cell
->parameters
["\\STATE_NUM"] = RTLIL::Const(state_table
.size());
45 cell
->parameters
["\\STATE_NUM_LOG2"] = RTLIL::Const(state_num_log2
);
46 cell
->parameters
["\\STATE_RST"] = RTLIL::Const(reset_state
);
47 cell
->parameters
["\\STATE_TABLE"] = RTLIL::Const();
49 for (int i
= 0; i
< int(state_table
.size()); i
++) {
50 std::vector
<RTLIL::State
> &bits_table
= cell
->parameters
["\\STATE_TABLE"].bits
;
51 std::vector
<RTLIL::State
> &bits_state
= state_table
[i
].bits
;
52 bits_table
.insert(bits_table
.end(), bits_state
.begin(), bits_state
.end());
55 cell
->parameters
["\\TRANS_NUM"] = RTLIL::Const(transition_table
.size());
56 cell
->parameters
["\\TRANS_TABLE"] = RTLIL::Const();
57 for (int i
= 0; i
< int(transition_table
.size()); i
++)
59 std::vector
<RTLIL::State
> &bits_table
= cell
->parameters
["\\TRANS_TABLE"].bits
;
60 transition_t
&tr
= transition_table
[i
];
62 RTLIL::Const const_state_in
= RTLIL::Const(tr
.state_in
, state_num_log2
);
63 RTLIL::Const const_state_out
= RTLIL::Const(tr
.state_out
, state_num_log2
);
64 std::vector
<RTLIL::State
> &bits_state_in
= const_state_in
.bits
;
65 std::vector
<RTLIL::State
> &bits_state_out
= const_state_out
.bits
;
67 std::vector
<RTLIL::State
> &bits_ctrl_in
= tr
.ctrl_in
.bits
;
68 std::vector
<RTLIL::State
> &bits_ctrl_out
= tr
.ctrl_out
.bits
;
71 bits_table
.insert(bits_table
.end(), bits_ctrl_out
.begin(), bits_ctrl_out
.end());
72 bits_table
.insert(bits_table
.end(), bits_state_out
.begin(), bits_state_out
.end());
73 bits_table
.insert(bits_table
.end(), bits_ctrl_in
.begin(), bits_ctrl_in
.end());
74 bits_table
.insert(bits_table
.end(), bits_state_in
.begin(), bits_state_in
.end());
78 void copy_from_cell(RTLIL::Cell
*cell
)
80 num_inputs
= cell
->parameters
["\\CTRL_IN_WIDTH"].as_int();
81 num_outputs
= cell
->parameters
["\\CTRL_OUT_WIDTH"].as_int();
83 state_bits
= cell
->parameters
["\\STATE_BITS"].as_int();
84 reset_state
= cell
->parameters
["\\STATE_RST"].as_int();
86 int state_num
= cell
->parameters
["\\STATE_NUM"].as_int();
87 int state_num_log2
= cell
->parameters
["\\STATE_NUM_LOG2"].as_int();
88 int trans_num
= cell
->parameters
["\\TRANS_NUM"].as_int();
90 if (reset_state
< 0 || reset_state
>= state_num
)
93 RTLIL::Const state_table
= cell
->parameters
["\\STATE_TABLE"];
94 RTLIL::Const trans_table
= cell
->parameters
["\\TRANS_TABLE"];
96 for (int i
= 0; i
< state_num
; i
++) {
97 RTLIL::Const state_code
;
98 int off_begin
= i
*state_bits
, off_end
= off_begin
+ state_bits
;
99 state_code
.bits
.insert(state_code
.bits
.begin(), state_table
.bits
.begin()+off_begin
, state_table
.bits
.begin()+off_end
);
100 this->state_table
.push_back(state_code
);
103 for (int i
= 0; i
< trans_num
; i
++)
105 auto off_ctrl_out
= trans_table
.bits
.begin() + i
*(num_inputs
+num_outputs
+2*state_num_log2
);
106 auto off_state_out
= off_ctrl_out
+ num_outputs
;
107 auto off_ctrl_in
= off_state_out
+ state_num_log2
;
108 auto off_state_in
= off_ctrl_in
+ num_inputs
;
109 auto off_end
= off_state_in
+ state_num_log2
;
111 RTLIL::Const state_in
, state_out
, ctrl_in
, ctrl_out
;
112 ctrl_out
.bits
.insert(state_in
.bits
.begin(), off_ctrl_out
, off_state_out
);
113 state_out
.bits
.insert(state_out
.bits
.begin(), off_state_out
, off_ctrl_in
);
114 ctrl_in
.bits
.insert(ctrl_in
.bits
.begin(), off_ctrl_in
, off_state_in
);
115 state_in
.bits
.insert(state_in
.bits
.begin(), off_state_in
, off_end
);
118 tr
.state_in
= state_in
.as_int();
119 tr
.state_out
= state_out
.as_int();
120 tr
.ctrl_in
= ctrl_in
;
121 tr
.ctrl_out
= ctrl_out
;
123 if (tr
.state_in
< 0 || tr
.state_in
>= state_num
)
125 if (tr
.state_out
< 0 || tr
.state_out
>= state_num
)
128 transition_table
.push_back(tr
);
132 void log_info(RTLIL::Cell
*cell
)
134 log("-------------------------------------\n");
136 log(" Information on FSM %s (%s):\n", cell
->name
.c_str(), cell
->parameters
["\\NAME"].decode_string().c_str());
138 log(" Number of input signals: %3d\n", num_inputs
);
139 log(" Number of output signals: %3d\n", num_outputs
);
140 log(" Number of state bits: %3d\n", state_bits
);
143 log(" Input signals:\n");
144 RTLIL::SigSpec sig_in
= cell
->connections_
["\\CTRL_IN"];
145 for (int i
= 0; i
< SIZE(sig_in
); i
++)
146 log(" %3d: %s\n", i
, log_signal(sig_in
[i
]));
149 log(" Output signals:\n");
150 RTLIL::SigSpec sig_out
= cell
->connections_
["\\CTRL_OUT"];
151 for (int i
= 0; i
< SIZE(sig_out
); i
++)
152 log(" %3d: %s\n", i
, log_signal(sig_out
[i
]));
155 log(" State encoding:\n");
156 for (int i
= 0; i
< SIZE(state_table
); i
++)
157 log(" %3d: %10s%s\n", i
, log_signal(state_table
[i
], false),
158 int(i
) == reset_state
? " <RESET STATE>" : "");
161 log(" Transition Table (state_in, ctrl_in, state_out, ctrl_out):\n");
162 for (int i
= 0; i
< SIZE(transition_table
); i
++) {
163 transition_t
&tr
= transition_table
[i
];
164 log(" %5d: %5d %s -> %5d %s\n", i
, tr
.state_in
, log_signal(tr
.ctrl_in
), tr
.state_out
, log_signal(tr
.ctrl_out
));
168 log("-------------------------------------\n");
171 // implemented in fsm_opt.cc
172 static void optimize_fsm(RTLIL::Cell
*cell
, RTLIL::Module
*module
);