Revert "Merge pull request #1917 from YosysHQ/eddie/abc9_delay_check"
[yosys.git] / passes / fsm / fsmdata.h
1 /*
2 * yosys -- Yosys Open SYnthesis Suite
3 *
4 * Copyright (C) 2012 Clifford Wolf <clifford@clifford.at>
5 *
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.
9 *
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.
17 *
18 */
19
20 #ifndef FSMDATA_H
21 #define FSMDATA_H
22
23 #include "kernel/yosys.h"
24
25 YOSYS_NAMESPACE_BEGIN
26
27 struct FsmData
28 {
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;
33
34 void copy_to_cell(RTLIL::Cell *cell)
35 {
36 cell->parameters[ID::CTRL_IN_WIDTH] = RTLIL::Const(num_inputs);
37 cell->parameters[ID::CTRL_OUT_WIDTH] = RTLIL::Const(num_outputs);
38
39 int state_num_log2 = 0;
40 for (int i = state_table.size(); i > 0; i = i >> 1)
41 state_num_log2++;
42 state_num_log2 = max(state_num_log2, 1);
43
44 cell->parameters[ID::STATE_BITS] = RTLIL::Const(state_bits);
45 cell->parameters[ID::STATE_NUM] = RTLIL::Const(state_table.size());
46 cell->parameters[ID::STATE_NUM_LOG2] = RTLIL::Const(state_num_log2);
47 cell->parameters[ID::STATE_RST] = RTLIL::Const(reset_state);
48 cell->parameters[ID::STATE_TABLE] = RTLIL::Const();
49
50 for (int i = 0; i < int(state_table.size()); i++) {
51 std::vector<RTLIL::State> &bits_table = cell->parameters[ID::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());
54 }
55
56 cell->parameters[ID::TRANS_NUM] = RTLIL::Const(transition_table.size());
57 cell->parameters[ID::TRANS_TABLE] = RTLIL::Const();
58 for (int i = 0; i < int(transition_table.size()); i++)
59 {
60 std::vector<RTLIL::State> &bits_table = cell->parameters[ID::TRANS_TABLE].bits;
61 transition_t &tr = transition_table[i];
62
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;
67
68 std::vector<RTLIL::State> &bits_ctrl_in = tr.ctrl_in.bits;
69 std::vector<RTLIL::State> &bits_ctrl_out = tr.ctrl_out.bits;
70
71 // append lsb first
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());
76 }
77 }
78
79 void copy_from_cell(RTLIL::Cell *cell)
80 {
81 num_inputs = cell->parameters[ID::CTRL_IN_WIDTH].as_int();
82 num_outputs = cell->parameters[ID::CTRL_OUT_WIDTH].as_int();
83
84 state_bits = cell->parameters[ID::STATE_BITS].as_int();
85 reset_state = cell->parameters[ID::STATE_RST].as_int();
86
87 int state_num = cell->parameters[ID::STATE_NUM].as_int();
88 int state_num_log2 = cell->parameters[ID::STATE_NUM_LOG2].as_int();
89 int trans_num = cell->parameters[ID::TRANS_NUM].as_int();
90
91 if (reset_state < 0 || reset_state >= state_num)
92 reset_state = -1;
93
94 RTLIL::Const state_table = cell->parameters[ID::STATE_TABLE];
95 RTLIL::Const trans_table = cell->parameters[ID::TRANS_TABLE];
96
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);
102 }
103
104 for (int i = 0; i < trans_num; i++)
105 {
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;
111
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);
117
118 transition_t tr;
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;
123
124 if (tr.state_in < 0 || tr.state_in >= state_num)
125 tr.state_in = -1;
126 if (tr.state_out < 0 || tr.state_out >= state_num)
127 tr.state_out = -1;
128
129 transition_table.push_back(tr);
130 }
131 }
132
133 void log_info(RTLIL::Cell *cell)
134 {
135 log("-------------------------------------\n");
136 log("\n");
137 log(" Information on FSM %s (%s):\n", cell->name.c_str(), cell->parameters[ID::NAME].decode_string().c_str());
138 log("\n");
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);
142
143 log("\n");
144 log(" Input signals:\n");
145 RTLIL::SigSpec sig_in = cell->getPort(ID::CTRL_IN);
146 for (int i = 0; i < GetSize(sig_in); i++)
147 log(" %3d: %s\n", i, log_signal(sig_in[i]));
148
149 log("\n");
150 log(" Output signals:\n");
151 RTLIL::SigSpec sig_out = cell->getPort(ID::CTRL_OUT);
152 for (int i = 0; i < GetSize(sig_out); i++)
153 log(" %3d: %s\n", i, log_signal(sig_out[i]));
154
155 log("\n");
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>" : "");
160
161 log("\n");
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));
166 }
167
168 log("\n");
169 log("-------------------------------------\n");
170 }
171
172 // implemented in fsm_opt.cc
173 static void optimize_fsm(RTLIL::Cell *cell, RTLIL::Module *module);
174 };
175
176 YOSYS_NAMESPACE_END
177
178 #endif