@@ -82,7 +82,7 @@ struct Macc
8282 new_ports.swap (ports);
8383 }
8484
85- void from_cell (RTLIL::Cell *cell)
85+ void from_cell_v1 (RTLIL::Cell *cell)
8686 {
8787 RTLIL::SigSpec port_a = cell->getPort (ID::A);
8888
@@ -136,52 +136,82 @@ struct Macc
136136 log_assert (port_a_cursor == GetSize (port_a));
137137 }
138138
139- void to_cell (RTLIL::Cell *cell) const
139+ void from_cell (RTLIL::Cell *cell)
140140 {
141- RTLIL::SigSpec port_a;
142- std::vector<RTLIL::State> config_bits;
143- int max_size = 0 , num_bits = 0 ;
144-
145- for (auto &port : ports) {
146- max_size = max (max_size, GetSize (port.in_a ));
147- max_size = max (max_size, GetSize (port.in_b ));
141+ if (cell->type == ID ($macc)) {
142+ from_cell_v1 (cell);
143+ return ;
148144 }
145+ log_assert (cell->type == ID ($macc_v2));
149146
150- while (max_size)
151- num_bits++, max_size /= 2 ;
147+ RTLIL::SigSpec port_a = cell-> getPort (ID::A);
148+ RTLIL::SigSpec port_b = cell-> getPort (ID::B) ;
152149
153- log_assert (num_bits < 16 );
154- config_bits.push_back (num_bits & 1 ? State::S1 : State::S0);
155- config_bits.push_back (num_bits & 2 ? State::S1 : State::S0);
156- config_bits.push_back (num_bits & 4 ? State::S1 : State::S0);
157- config_bits.push_back (num_bits & 8 ? State::S1 : State::S0);
150+ ports.clear ();
158151
159- for (auto &port : ports)
160- {
161- if (GetSize (port.in_a ) == 0 )
162- continue ;
152+ int nterms = cell->getParam (ID::NTERMS).as_int ();
153+ const Const &neg = cell->getParam (ID::TERM_NEGATED);
154+ const Const &a_widths = cell->getParam (ID::A_WIDTHS);
155+ const Const &b_widths = cell->getParam (ID::B_WIDTHS);
156+ const Const &a_signed = cell->getParam (ID::A_SIGNED);
157+ const Const &b_signed = cell->getParam (ID::B_SIGNED);
158+
159+ int ai = 0 , bi = 0 ;
160+ for (int i = 0 ; i < nterms; i++) {
161+ port_t term;
162+
163+ log_assert (a_signed[i] == b_signed[i]);
164+ term.is_signed = (a_signed[i] == State::S1);
165+ int a_width = a_widths.extract (16 * i, 16 ).as_int (false );
166+ int b_width = b_widths.extract (16 * i, 16 ).as_int (false );
167+
168+ term.in_a = port_a.extract (ai, a_width);
169+ ai += a_width;
170+ term.in_b = port_b.extract (bi, b_width);
171+ bi += b_width;
172+ term.do_subtract = (neg[i] == State::S1);
173+
174+ ports.push_back (term);
175+ }
176+ log_assert (port_a.size () == ai);
177+ log_assert (port_b.size () == bi);
178+ }
163179
164- config_bits.push_back (port.is_signed ? State::S1 : State::S0);
165- config_bits.push_back (port.do_subtract ? State::S1 : State::S0);
180+ void to_cell (RTLIL::Cell *cell)
181+ {
182+ cell->type = ID ($macc_v2);
166183
167- int size_a = GetSize (port.in_a );
168- for (int i = 0 ; i < num_bits; i++)
169- config_bits.push_back (size_a & (1 << i) ? State::S1 : State::S0);
184+ int nterms = ports.size ();
185+ const auto Sx = State::Sx;
186+ Const a_signed (Sx, nterms), b_signed (Sx, nterms), negated (Sx, nterms);
187+ Const a_widths, b_widths;
188+ SigSpec a, b;
170189
171- int size_b = GetSize (port.in_b );
172- for (int i = 0 ; i < num_bits; i++)
173- config_bits.push_back (size_b & (1 << i) ? State::S1 : State::S0);
190+ for (int i = 0 ; i < nterms; i++) {
191+ SigSpec term_a = ports[i].in_a , term_b = ports[i].in_b ;
174192
175- port_a.append (port.in_a );
176- port_a.append (port.in_b );
177- }
193+ a_widths.append (Const (term_a.size (), 16 ));
194+ b_widths.append (Const (term_b.size (), 16 ));
178195
179- cell->setPort (ID::A, port_a);
180- cell->setPort (ID::B, {});
181- cell->setParam (ID::CONFIG, config_bits);
182- cell->setParam (ID::CONFIG_WIDTH, GetSize (config_bits));
183- cell->setParam (ID::A_WIDTH, GetSize (port_a));
184- cell->setParam (ID::B_WIDTH, 0 );
196+ a_signed.bits ()[i] = b_signed.bits ()[i] =
197+ (ports[i].is_signed ? RTLIL::S1 : RTLIL::S0);
198+ negated.bits ()[i] = (ports[i].do_subtract ? RTLIL::S1 : RTLIL::S0);
199+
200+ a.append (term_a);
201+ b.append (term_b);
202+ }
203+ negated.is_fully_def ();
204+ a_signed.is_fully_def ();
205+ b_signed.is_fully_def ();
206+
207+ cell->setParam (ID::NTERMS, nterms);
208+ cell->setParam (ID::TERM_NEGATED, negated);
209+ cell->setParam (ID::A_SIGNED, a_signed);
210+ cell->setParam (ID::B_SIGNED, b_signed);
211+ cell->setParam (ID::A_WIDTHS, a_widths);
212+ cell->setParam (ID::B_WIDTHS, b_widths);
213+ cell->setPort (ID::A, a);
214+ cell->setPort (ID::B, b);
185215 }
186216
187217 bool eval (RTLIL::Const &result) const
0 commit comments