[prim_arb_tree/rv_plic_target] Remove TODOs due to a Vivado tool bug

This tool bug has been fixed in Vivado 2020.2.

Fix #1408

Signed-off-by: Michael Schaffner <msf@google.com>
diff --git a/hw/ip/prim/rtl/prim_arbiter_tree.sv b/hw/ip/prim/rtl/prim_arbiter_tree.sv
index 16281fb..7b6be73 100644
--- a/hw/ip/prim/rtl/prim_arbiter_tree.sv
+++ b/hw/ip/prim/rtl/prim_arbiter_tree.sv
@@ -141,33 +141,25 @@
           // local helper variable
           logic sel;
 
-          // TODO: The always_comb code is split into two blocks to allow Verilator to schedule them
-          //       separately (avoiding a spurious UNOPTFLAT warning). The whole lot would probably
-          //       be clearer as a set of continuous assignments, rather than using always_comb
-          //       blocks. Unfortunately, we can't currently do that because of a Vivado bug,
-          //       reported in January 2020. This is tracked with OpenTitan issue #1408. There's
-          //       currently no information about a Vivado version with this fixed.
-          always_comb begin : p_sel
-            // forward path (requests and data)
-            // each node looks at its two children, and selects the one with higher priority
-            sel = ~req_tree[C0] | ~prio_tree[C0] & prio_tree[C1];
-          end
-          always_comb begin : p_node
-            // propagate requests
-            req_tree[Pa]  = req_tree[C0] | req_tree[C1];
-            prio_tree[Pa] = prio_tree[C1] | prio_tree[C0];
-            // data and index muxes
-            idx_tree[Pa]  = (sel) ? idx_tree[C1]  : idx_tree[C0];
-            data_tree[Pa] = (sel) ? data_tree[C1] : data_tree[C0];
+          // forward path (requests and data)
+          // each node looks at its two children, and selects the one with higher priority
+          assign sel = ~req_tree[C0] | ~prio_tree[C0] & prio_tree[C1];
+          // propagate requests
+          assign req_tree[Pa]  = req_tree[C0] | req_tree[C1];
+          assign prio_tree[Pa] = prio_tree[C1] | prio_tree[C0];
+          // data and index muxes
+          // Note: these ternaries have triggered a synthesis bug in Vivado versions older
+          // than 2020.2. If the problem resurfaces again, have a look at issue #1408.
+          assign idx_tree[Pa]  = (sel) ? idx_tree[C1]  : idx_tree[C0];
+          assign data_tree[Pa] = (sel) ? data_tree[C1] : data_tree[C0];
 
-            // backward path (grants and prefix sum)
-            // this propagates the selction index back and computes a hot one mask
-            sel_tree[C0] = sel_tree[Pa] & ~sel;
-            sel_tree[C1] = sel_tree[Pa] &  sel;
-            // this performs a prefix sum for masking the input requests in the next cycle
-            mask_tree[C0] = mask_tree[Pa];
-            mask_tree[C1] = mask_tree[Pa] | sel_tree[C0];
-          end
+          // backward path (grants and prefix sum)
+          // this propagates the selction index back and computes a hot one mask
+          assign sel_tree[C0] = sel_tree[Pa] & ~sel;
+          assign sel_tree[C1] = sel_tree[Pa] &  sel;
+          // this performs a prefix sum for masking the input requests in the next cycle
+          assign mask_tree[C0] = mask_tree[Pa];
+          assign mask_tree[C1] = mask_tree[Pa] | sel_tree[C0];
         end
       end : gen_level
     end : gen_tree
diff --git a/hw/ip/rv_plic/rtl/rv_plic_target.sv b/hw/ip/rv_plic/rtl/rv_plic_target.sv
index 2447e78..ded960e 100644
--- a/hw/ip/rv_plic/rtl/rv_plic_target.sv
+++ b/hw/ip/rv_plic/rtl/rv_plic_target.sv
@@ -79,32 +79,17 @@
         end
       // this creates the node assignments
       end else begin : gen_nodes
-        // NOTE: the code below has been written in this way in order to work
-        // around a synthesis issue in Vivado 2018.3 and 2019.2 where the whole
-        // module would be optimized away if these assign statements contained
-        // ternary statements to implement the muxes.
-        //
-        // TODO: rewrite these lines with ternary statmements onec the problem
-        // has been fixed in the tool.
-        //
-        // See also originating issue:
-        // https://github.com/lowRISC/opentitan/issues/1355
-        // Xilinx issue:
-        // https://forums.xilinx.com/t5/Synthesis/
-        // Simulation-Synthesis-Mismatch-with-Vivado-2018-3/m-p/1065923#M33849
-
         logic sel; // local helper variable
         // in case only one of the parent has a pending irq_o, forward that one
         // in case both irqs are pending, forward the one with higher priority
         assign sel = (~is_tree[C0] & is_tree[C1]) |
                      (is_tree[C0] & is_tree[C1] & logic'(max_tree[C1] > max_tree[C0]));
         // forwarding muxes
-        assign is_tree[Pa]  = (sel               & is_tree[C1])  |
-                              ((~sel)            & is_tree[C0]);
-        assign id_tree[Pa]  = ({SrcWidth{sel}}   & id_tree[C1])  |
-                              ({SrcWidth{~sel}}  & id_tree[C0]);
-        assign max_tree[Pa] = ({PrioWidth{sel}}  & max_tree[C1]) |
-                              ({PrioWidth{~sel}} & max_tree[C0]);
+        // Note: these ternaries have triggered a synthesis bug in Vivado versions older
+        // than 2020.2. If the problem resurfaces again, have a look at issue #1408.
+        assign is_tree[Pa]  = (sel) ? is_tree[C1]  : is_tree[C0];
+        assign id_tree[Pa]  = (sel) ? id_tree[C1]  : id_tree[C0];
+        assign max_tree[Pa] = (sel) ? max_tree[C1] : max_tree[C0];
       end
     end : gen_level
   end : gen_tree