Merge pull request #1275 from YosysHQ/clifford/ids
[yosys.git] / kernel / macc.h
index 271141112f265d65b25a3b4944f4e8d4291cd7f5..e07e7e01a8e9938b0c60fb76ba923a5c2c71d9f2 100644 (file)
@@ -2,11 +2,11 @@
  *  yosys -- Yosys Open SYnthesis Suite
  *
  *  Copyright (C) 2012  Clifford Wolf <clifford@clifford.at>
- *  
+ *
  *  Permission to use, copy, modify, and/or distribute this software for any
  *  purpose with or without fee is hereby granted, provided that the above
  *  copyright notice and this permission notice appear in all copies.
- *  
+ *
  *  THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
  *  WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
  *  MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
@@ -42,17 +42,20 @@ struct Macc
 
                for (auto &port : ports)
                {
-                       if (SIZE(port.in_a) == 0 && SIZE(port.in_b) == 0)
+                       if (GetSize(port.in_a) == 0 && GetSize(port.in_b) == 0)
                                continue;
 
-                       if (SIZE(port.in_a) == 1 && SIZE(port.in_b) == 0 && !port.is_signed && !port.do_subtract) {
+                       if (GetSize(port.in_a) < GetSize(port.in_b))
+                               std::swap(port.in_a, port.in_b);
+
+                       if (GetSize(port.in_a) == 1 && GetSize(port.in_b) == 0 && !port.is_signed && !port.do_subtract) {
                                bit_ports.append(port.in_a);
                                continue;
                        }
 
                        if (port.in_a.is_fully_const() && port.in_b.is_fully_const()) {
                                RTLIL::Const v = port.in_a.as_const();
-                               if (SIZE(port.in_b))
+                               if (GetSize(port.in_b))
                                        v = const_mul(v, port.in_b.as_const(), port.is_signed, port.is_signed, width);
                                if (port.do_subtract)
                                        off = const_sub(off, v, port.is_signed, port.is_signed, width);
@@ -62,24 +65,24 @@ struct Macc
                        }
 
                        if (port.is_signed) {
-                               while (SIZE(port.in_a) > 1 && port.in_a[SIZE(port.in_a)-1] == port.in_a[SIZE(port.in_a)-2])
-                                       port.in_a.remove(SIZE(port.in_a)-1);
-                               while (SIZE(port.in_b) > 1 && port.in_b[SIZE(port.in_b)-1] == port.in_b[SIZE(port.in_b)-2])
-                                       port.in_b.remove(SIZE(port.in_b)-1);
+                               while (GetSize(port.in_a) > 1 && port.in_a[GetSize(port.in_a)-1] == port.in_a[GetSize(port.in_a)-2])
+                                       port.in_a.remove(GetSize(port.in_a)-1);
+                               while (GetSize(port.in_b) > 1 && port.in_b[GetSize(port.in_b)-1] == port.in_b[GetSize(port.in_b)-2])
+                                       port.in_b.remove(GetSize(port.in_b)-1);
                        } else {
-                               while (SIZE(port.in_a) > 1 && port.in_a[SIZE(port.in_a)-1] == RTLIL::S0)
-                                       port.in_a.remove(SIZE(port.in_a)-1);
-                               while (SIZE(port.in_b) > 1 && port.in_b[SIZE(port.in_b)-1] == RTLIL::S0)
-                                       port.in_b.remove(SIZE(port.in_b)-1);
+                               while (GetSize(port.in_a) > 1 && port.in_a[GetSize(port.in_a)-1] == State::S0)
+                                       port.in_a.remove(GetSize(port.in_a)-1);
+                               while (GetSize(port.in_b) > 1 && port.in_b[GetSize(port.in_b)-1] == State::S0)
+                                       port.in_b.remove(GetSize(port.in_b)-1);
                        }
 
                        new_ports.push_back(port);
                }
 
                for (auto &bit : bit_ports)
-                       if (bit == RTLIL::S1)
+                       if (bit == State::S1)
                                off = const_add(off, RTLIL::Const(1, width), false, false, width);
-                       else if (bit != RTLIL::S0)
+                       else if (bit != State::S0)
                                new_bit_ports.append(bit);
 
                if (off.as_bool()) {
@@ -96,35 +99,37 @@ struct Macc
 
        void from_cell(RTLIL::Cell *cell)
        {
-               RTLIL::SigSpec port_a = cell->getPort("\\A");
+               RTLIL::SigSpec port_a = cell->getPort(ID(A));
 
                ports.clear();
-               bit_ports = cell->getPort("\\B");
+               bit_ports = cell->getPort(ID(B));
 
-               std::vector<RTLIL::State> config_bits = cell->getParam("\\CONFIG").bits;
-               int config_width = cell->getParam("\\CONFIG_WIDTH").as_int();
+               std::vector<RTLIL::State> config_bits = cell->getParam(ID(CONFIG)).bits;
                int config_cursor = 0;
 
-               log_assert(SIZE(config_bits) >= config_width);
+#ifndef NDEBUG
+               int config_width = cell->getParam(ID(CONFIG_WIDTH)).as_int();
+               log_assert(GetSize(config_bits) >= config_width);
+#endif
 
                int num_bits = 0;
-               if (config_bits[config_cursor++] == RTLIL::S1) num_bits |= 1;
-               if (config_bits[config_cursor++] == RTLIL::S1) num_bits |= 2;
-               if (config_bits[config_cursor++] == RTLIL::S1) num_bits |= 4;
-               if (config_bits[config_cursor++] == RTLIL::S1) num_bits |= 8;
+               if (config_bits[config_cursor++] == State::S1) num_bits |= 1;
+               if (config_bits[config_cursor++] == State::S1) num_bits |= 2;
+               if (config_bits[config_cursor++] == State::S1) num_bits |= 4;
+               if (config_bits[config_cursor++] == State::S1) num_bits |= 8;
 
                int port_a_cursor = 0;
-               while (port_a_cursor < SIZE(port_a))
+               while (port_a_cursor < GetSize(port_a))
                {
                        log_assert(config_cursor + 2 + 2*num_bits <= config_width);
 
                        port_t this_port;
-                       this_port.is_signed = config_bits[config_cursor++] == RTLIL::S1;
-                       this_port.do_subtract = config_bits[config_cursor++] == RTLIL::S1;
+                       this_port.is_signed = config_bits[config_cursor++] == State::S1;
+                       this_port.do_subtract = config_bits[config_cursor++] == State::S1;
 
                        int size_a = 0;
                        for (int i = 0; i < num_bits; i++)
-                               if (config_bits[config_cursor++] == RTLIL::S1)
+                               if (config_bits[config_cursor++] == State::S1)
                                        size_a |= 1 << i;
 
                        this_port.in_a = port_a.extract(port_a_cursor, size_a);
@@ -132,7 +137,7 @@ struct Macc
 
                        int size_b = 0;
                        for (int i = 0; i < num_bits; i++)
-                               if (config_bits[config_cursor++] == RTLIL::S1)
+                               if (config_bits[config_cursor++] == State::S1)
                                        size_b |= 1 << i;
 
                        this_port.in_b = port_a.extract(port_a_cursor, size_b);
@@ -143,7 +148,7 @@ struct Macc
                }
 
                log_assert(config_cursor == config_width);
-               log_assert(port_a_cursor == SIZE(port_a));
+               log_assert(port_a_cursor == GetSize(port_a));
        }
 
        void to_cell(RTLIL::Cell *cell) const
@@ -153,51 +158,51 @@ struct Macc
                int max_size = 0, num_bits = 0;
 
                for (auto &port : ports) {
-                       max_size = std::max(max_size, SIZE(port.in_a));
-                       max_size = std::max(max_size, SIZE(port.in_b));
+                       max_size = max(max_size, GetSize(port.in_a));
+                       max_size = max(max_size, GetSize(port.in_b));
                }
 
                while (max_size)
                        num_bits++, max_size /= 2;
 
                log_assert(num_bits < 16);
-               config_bits.push_back(num_bits & 1 ? RTLIL::S1 : RTLIL::S0);
-               config_bits.push_back(num_bits & 2 ? RTLIL::S1 : RTLIL::S0);
-               config_bits.push_back(num_bits & 4 ? RTLIL::S1 : RTLIL::S0);
-               config_bits.push_back(num_bits & 8 ? RTLIL::S1 : RTLIL::S0);
+               config_bits.push_back(num_bits & 1 ? State::S1 : State::S0);
+               config_bits.push_back(num_bits & 2 ? State::S1 : State::S0);
+               config_bits.push_back(num_bits & 4 ? State::S1 : State::S0);
+               config_bits.push_back(num_bits & 8 ? State::S1 : State::S0);
 
                for (auto &port : ports)
                {
-                       if (SIZE(port.in_a) == 0)
+                       if (GetSize(port.in_a) == 0)
                                continue;
 
-                       config_bits.push_back(port.is_signed ? RTLIL::S1 : RTLIL::S0);
-                       config_bits.push_back(port.do_subtract ? RTLIL::S1 : RTLIL::S0);
+                       config_bits.push_back(port.is_signed ? State::S1 : State::S0);
+                       config_bits.push_back(port.do_subtract ? State::S1 : State::S0);
 
-                       int size_a = SIZE(port.in_a);
+                       int size_a = GetSize(port.in_a);
                        for (int i = 0; i < num_bits; i++)
-                               config_bits.push_back(size_a & (1 << i) ? RTLIL::S1 : RTLIL::S0);
+                               config_bits.push_back(size_a & (1 << i) ? State::S1 : State::S0);
 
-                       int size_b = SIZE(port.in_b);
+                       int size_b = GetSize(port.in_b);
                        for (int i = 0; i < num_bits; i++)
-                               config_bits.push_back(size_b & (1 << i) ? RTLIL::S1 : RTLIL::S0);
+                               config_bits.push_back(size_b & (1 << i) ? State::S1 : State::S0);
 
                        port_a.append(port.in_a);
                        port_a.append(port.in_b);
                }
 
-               cell->setPort("\\A", port_a);
-               cell->setPort("\\B", bit_ports);
-               cell->setParam("\\CONFIG", config_bits);
-               cell->setParam("\\CONFIG_WIDTH", SIZE(config_bits));
-               cell->setParam("\\A_WIDTH", SIZE(port_a));
-               cell->setParam("\\B_WIDTH", SIZE(bit_ports));
+               cell->setPort(ID(A), port_a);
+               cell->setPort(ID(B), bit_ports);
+               cell->setParam(ID(CONFIG), config_bits);
+               cell->setParam(ID(CONFIG_WIDTH), GetSize(config_bits));
+               cell->setParam(ID(A_WIDTH), GetSize(port_a));
+               cell->setParam(ID(B_WIDTH), GetSize(bit_ports));
        }
 
        bool eval(RTLIL::Const &result) const
        {
                for (auto &bit : result.bits)
-                       bit = RTLIL::S0;
+                       bit = State::S0;
 
                for (auto &port : ports)
                {
@@ -205,25 +210,31 @@ struct Macc
                                return false;
 
                        RTLIL::Const summand;
-                       if (SIZE(port.in_b) == 0)
-                               summand = const_pos(port.in_a.as_const(), port.in_b.as_const(), port.is_signed, port.is_signed, SIZE(result));
+                       if (GetSize(port.in_b) == 0)
+                               summand = const_pos(port.in_a.as_const(), port.in_b.as_const(), port.is_signed, port.is_signed, GetSize(result));
                        else
-                               summand = const_mul(port.in_a.as_const(), port.in_b.as_const(), port.is_signed, port.is_signed, SIZE(result));
+                               summand = const_mul(port.in_a.as_const(), port.in_b.as_const(), port.is_signed, port.is_signed, GetSize(result));
 
                        if (port.do_subtract)
-                               result = const_sub(result, summand, port.is_signed, port.is_signed, SIZE(result));
+                               result = const_sub(result, summand, port.is_signed, port.is_signed, GetSize(result));
                        else
-                               result = const_add(result, summand, port.is_signed, port.is_signed, SIZE(result));
+                               result = const_add(result, summand, port.is_signed, port.is_signed, GetSize(result));
                }
 
                for (auto bit : bit_ports) {
                        if (bit.wire)
                                return false;
-                       result = const_add(result, bit.data, false, false, SIZE(result));
+                       result = const_add(result, bit.data, false, false, GetSize(result));
                }
 
                return true;
        }
+
+       Macc(RTLIL::Cell *cell = nullptr)
+       {
+               if (cell != nullptr)
+                       from_cell(cell);
+       }
 };
 
 YOSYS_NAMESPACE_END