Added "int ceil_log2(int)" function
authorClifford Wolf <clifford@clifford.at>
Sat, 13 Feb 2016 15:52:16 +0000 (16:52 +0100)
committerClifford Wolf <clifford@clifford.at>
Sat, 13 Feb 2016 15:52:16 +0000 (16:52 +0100)
backends/btor/btor.cc
kernel/yosys.cc
kernel/yosys.h
libs/ezsat/ezsat.cc
passes/fsm/fsm_recode.cc

index 26585f43be7759327c0c833619c5dec7140307ad..465723f1a24e4e09f2388b151fe407666be5d43b 100644 (file)
@@ -260,7 +260,7 @@ struct BtorDumper
                if(it==std::end(line_ref))
                {
                        ++line_num;
-                       int address_bits = ceil(log(memory->size)/log(2));
+                       int address_bits = ceil_log2(memory->size);
                        str = stringf("%d array %d %d", line_num, memory->width, address_bits);
                        line_ref[memory->name]=line_num;
                        f << stringf("%s\n", str.c_str());
@@ -272,7 +272,7 @@ struct BtorDumper
         int dump_memory_next(const RTLIL::Memory* memory)
         {
          auto mem_it = line_ref.find(memory->name);
-         int address_bits = ceil(log(memory->size)/log(2));
+         int address_bits = ceil_log2(memory->size);
          if(mem_it==std::end(line_ref))
            {
              log("can not write next of a memory that is not dumped yet\n");
@@ -593,18 +593,18 @@ struct BtorDumper
                                bool l1_signed = cell->parameters.at(RTLIL::IdString("\\A_SIGNED")).as_bool();
                                //bool l2_signed = cell->parameters.at(RTLIL::IdString("\\B_SIGNED")).as_bool();
                                int l1_width = cell->parameters.at(RTLIL::IdString("\\A_WIDTH")).as_int();
-                               l1_width = pow(2, ceil(log(l1_width)/log(2)));
+                               l1_width = 1 << ceil_log2(l1_width);
                                int l2_width = cell->parameters.at(RTLIL::IdString("\\B_WIDTH")).as_int();
-                               //log_assert(l2_width <= ceil(log(l1_width)/log(2)) );
+                               //log_assert(l2_width <= ceil_log2(l1_width)) );
                                int l1 = dump_sigspec(&cell->getPort(RTLIL::IdString("\\A")), l1_width);
-                               int l2 = dump_sigspec(&cell->getPort(RTLIL::IdString("\\B")), ceil(log(l1_width)/log(2)));
+                               int l2 = dump_sigspec(&cell->getPort(RTLIL::IdString("\\B")), ceil_log2(l1_width));
                                int cell_output = ++line_num;
                                str = stringf ("%d %s %d %d %d", line_num, cell_type_translation.at(cell->type.str()).c_str(), l1_width, l1, l2);
                                f << stringf("%s\n", str.c_str());
 
-                               if(l2_width > ceil(log(l1_width)/log(2)))
+                               if(l2_width > ceil_log2(l1_width))
                                {
-                                       int extra_width = l2_width - ceil(log(l1_width)/log(2));
+                                       int extra_width = l2_width - ceil_log2(l1_width);
                                        l2 = dump_sigspec(&cell->getPort(RTLIL::IdString("\\B")), l2_width);
                                        ++line_num;
                                        str = stringf ("%d slice %d %d %d %d;6", line_num, extra_width, l2, l2_width-1, l2_width-extra_width);
@@ -821,7 +821,7 @@ struct BtorDumper
                                         ++line_num;
                                         str = cell->parameters.at(RTLIL::IdString("\\MEMID")).decode_string();
                                         RTLIL::Memory *memory = module->memories.at(RTLIL::IdString(str.c_str()));
-                                        int address_bits = ceil(log(memory->size)/log(2));
+                                        int address_bits = ceil_log2(memory->size);
                                         str = stringf("%d array %d %d", line_num, memory->width, address_bits);
                                         f << stringf("%s\n", str.c_str());
                                         ++line_num;
index 109918816649242eb3d390764dff4458c6798db6..4bfbe36140b914330e674c071d02781af949e397 100644 (file)
@@ -124,6 +124,31 @@ void yosys_banner()
        log("\n");
 }
 
+int ceil_log2(int x)
+{
+       if (x <= 0)
+               return 0;
+
+       int y = (x & (x - 1));
+       y = (y | -y) >> 31;
+
+       x |= (x >> 1);
+       x |= (x >> 2);
+       x |= (x >> 4);
+       x |= (x >> 8);
+       x |= (x >> 16);
+
+       x >>= 1;
+       x -= ((x >> 1) & 0x55555555);
+       x = (((x >> 2) & 0x33333333) + (x & 0x33333333));
+       x = (((x >> 4) + x) & 0x0f0f0f0f);
+       x += (x >> 8);
+       x += (x >> 16);
+       x = x & 0x0000003f;
+
+       return x - y;
+}
+
 std::string stringf(const char *fmt, ...)
 {
        std::string string;
index 92fa6ac1928dafdee58cbb690d8a71eaf86a19a2..c8bc46b65ad69e7ef71b66edc98fdb2c60f71287 100644 (file)
@@ -222,6 +222,7 @@ extern bool memhasher_active;
 inline void memhasher() { if (memhasher_active) memhasher_do(); }
 
 void yosys_banner();
+int ceil_log2(int x);
 std::string stringf(const char *fmt, ...) YS_ATTRIBUTE(format(printf, 1, 2));
 std::string vstringf(const char *fmt, va_list ap);
 int readsome(std::istream &f, char *s, int n);
index da36fb74eadd467f7f774235eed6f699b1430f68..177bcd8a3014b3031caeb9338822c1d8fa06a037 100644 (file)
@@ -1337,6 +1337,28 @@ void ezSAT::printInternalState(FILE *f) const
        fprintf(f, "--8<-- snap --8<--\n");
 }
 
+static int clog2(int x)
+{
+       int y = (x & (x - 1));
+       y = (y | -y) >> 31;
+
+       x |= (x >> 1);
+       x |= (x >> 2);
+       x |= (x >> 4);
+       x |= (x >> 8);
+       x |= (x >> 16);
+
+       x >>= 1;
+       x -= ((x >> 1) & 0x55555555);
+       x = (((x >> 2) & 0x33333333) + (x & 0x33333333));
+       x = (((x >> 4) + x) & 0x0f0f0f0f);
+       x += (x >> 8);
+       x += (x >> 16);
+       x = x & 0x0000003f;
+
+       return x - y;
+}
+
 int ezSAT::onehot(const std::vector<int> &vec, bool max_only)
 {
        // Mixed one-hot/binary encoding as described by Claessen in Sec. 4.2 of
@@ -1350,7 +1372,7 @@ int ezSAT::onehot(const std::vector<int> &vec, bool max_only)
                formula.push_back(expression(OpOr, vec));
 
        // create binary vector
-       int num_bits = ceil(log2(vec.size()));
+       int num_bits = clog2(vec.size());
        std::vector<int> bits;
        for (int k = 0; k < num_bits; k++)
                bits.push_back(literal());
index aa1e99bef400a98c63ff2ed57d68e722c8f93a58..a4b45295e11ebdb8fafb9a8891011252f5bfa0f7 100644 (file)
@@ -85,7 +85,7 @@ static void fsm_recode(RTLIL::Cell *cell, RTLIL::Module *module, FILE *fm_set_fs
                fsm_data.state_bits = fsm_data.state_table.size();
        } else
        if (encoding == "binary") {
-               int new_num_state_bits = ceil(log2(fsm_data.state_table.size()));
+               int new_num_state_bits = ceil_log2(fsm_data.state_table.size());
                if (fsm_data.state_bits == new_num_state_bits) {
                        log("  existing encoding is already a packed binary encoding.\n");
                        return;