Fixed FSM mapping for multiple reset-like signals
authorClifford Wolf <clifford@clifford.at>
Sun, 10 Aug 2014 10:04:02 +0000 (12:04 +0200)
committerClifford Wolf <clifford@clifford.at>
Sun, 10 Aug 2014 10:04:02 +0000 (12:04 +0200)
passes/fsm/fsm_map.cc
tests/fsm/generate.py

index b3750de08855491b5f7961dd232e4dbc117f2e65..048cf7e5fa9b13ada0427e105a9c37770ee0dae0 100644 (file)
 #include "fsmdata.h"
 #include <string.h>
 
+static bool pattern_is_subset(const RTLIL::Const &super_pattern, const RTLIL::Const &sub_pattern)
+{
+       log_assert(SIZE(super_pattern.bits) == SIZE(sub_pattern.bits));
+       for (int i = 0; i < SIZE(super_pattern.bits); i++)
+               if (sub_pattern.bits[i] == RTLIL::State::S0 || sub_pattern.bits[i] == RTLIL::State::S1) {
+                       if (super_pattern.bits[i] == RTLIL::State::S0 || super_pattern.bits[i] == RTLIL::State::S1) {
+                                       if (super_pattern.bits[i] != sub_pattern.bits[i])
+                                               return false;
+                       } else
+                               return false;
+               }
+       return true;
+}
+
 static void implement_pattern_cache(RTLIL::Module *module, std::map<RTLIL::Const, std::set<int>> &pattern_cache, std::set<int> &fullstate_cache, int num_states, RTLIL::Wire *state_onehot, RTLIL::SigSpec &ctrl_in, RTLIL::SigSpec output)
 {
        RTLIL::SigSpec cases_vector;
@@ -68,7 +82,13 @@ static void implement_pattern_cache(RTLIL::Module *module, std::map<RTLIL::Const
                        eq_cell->parameters["\\Y_WIDTH"] = RTLIL::Const(1);
                }
 
-               if (or_sig.size() < num_states-int(fullstate_cache.size()))
+               std::set<int> complete_in_state_cache = it.second;
+
+               for (auto &it2 : pattern_cache)
+                       if (pattern_is_subset(pattern, it2.first))
+                               complete_in_state_cache.insert(it2.second.begin(), it2.second.end());
+
+               if (SIZE(complete_in_state_cache) < num_states)
                {
                        if (or_sig.size() == 1)
                        {
index 722bd62afe2280ff5ef7a52677d34a57ac500850..ca0718b27ac3855fda942083aa3ecc18466c0b1a 100644 (file)
@@ -32,8 +32,15 @@ def random_expr(variables):
 
 for idx in range(50):
     with file('temp/uut_%05d.v' % idx, 'w') as f, redirect_stdout(f):
-        print('module uut_%05d(clk, rst, a, b, c, x, y, z);' % (idx))
-        print('  input clk, rst;')
+        rst2 = random.choice([False, True])
+        if rst2:
+            print('module uut_%05d(clk, rst1, rst2, rst, a, b, c, x, y, z);' % (idx))
+            print('  input clk, rst1, rst2;')
+            print('  output rst;')
+            print('  assign rst = rst1 || rst2;')
+        else:
+            print('module uut_%05d(clk, rst, a, b, c, x, y, z);' % (idx))
+            print('  input clk, rst;')
         variables=['a', 'b', 'c', 'x', 'y', 'z']
         print('  input%s [%d:0] a;' % (random.choice(['', ' signed']), random.randint(0, 31)))
         print('  input%s [%d:0] b;' % (random.choice(['', ' signed']), random.randint(0, 31)))
@@ -41,14 +48,15 @@ for idx in range(50):
         print('  output reg%s [%d:0] x;' % (random.choice(['', ' signed']), random.randint(0, 31)))
         print('  output reg%s [%d:0] y;' % (random.choice(['', ' signed']), random.randint(0, 31)))
         print('  output reg%s [%d:0] z;' % (random.choice(['', ' signed']), random.randint(0, 31)))
-        print('  reg [15:0] state;')
+        state_bits = random.randint(5, 16);
+        print('  reg [%d:0] state;' % (state_bits-1))
         states=[]
         for i in range(random.randint(2, 10)):
-            n = random.randint(0, 2**16-1)
+            n = random.randint(0, 2**state_bits-1)
             if n not in states:
                 states.append(n)
         print('  always @(posedge clk) begin')
-        print('    if (rst) begin')
+        print('    if (%s) begin' % ('rst1' if rst2 else 'rst'))
         print('      x <= %d;' % random.randint(0, 2**31-1))
         print('      y <= %d;' % random.randint(0, 2**31-1))
         print('      z <= %d;' % random.randint(0, 2**31-1))
@@ -67,6 +75,13 @@ for idx in range(50):
                         random.choice(['<', '<=', '>=', '>']), random_expr(variables), next_state))
             print('          end')
         print('      endcase')
+        if rst2:
+            print('      if (rst2) begin')
+            print('        x <= a;')
+            print('        y <= b;')
+            print('        z <= c;')
+            print('        state <= %d;' % random.choice(states))
+            print('      end')
         print('    end')
         print('  end')
         print('endmodule')
@@ -76,8 +91,8 @@ for idx in range(50):
         print('copy uut_%05d gold' % idx)
         print('rename uut_%05d gate' % idx)
         print('cd gate')
-        print('opt; wreduce; share; opt; fsm;;')
+        print('opt; wreduce; share%s; opt; fsm;;' % random.choice(['', ' -aggressive']))
         print('cd ..')
         print('miter -equiv -flatten -ignore_gold_x -make_outputs -make_outcmp gold gate miter')
-        print('sat -verify-no-timeout -timeout 20 -seq 5 -set-at 1 in_rst 1 -prove trigger 0 -prove-skip 1 -show-inputs -show-outputs miter')
+        print('sat -verify-no-timeout -timeout 20 -seq 5 -set-at 1 %s_rst 1 -prove trigger 0 -prove-skip 1 -show-inputs -show-outputs miter' % ('gold' if rst2 else 'in'))