Replaced NO_COMB=0 attribute with COMB_INCLUDE_CLOCKS specified on outputs. Signed-off-by: Maciej Kurc <mkurc@antmicro.com>
diff --git a/tests/clock_mux/README.rst b/tests/clock_mux/README.rst index e320863..97d2674 100644 --- a/tests/clock_mux/README.rst +++ b/tests/clock_mux/README.rst
@@ -1,11 +1,12 @@ Clock multiplexing primitive ++++++++++++++++++++++++++++ -This is an example of modeling a clock mux/buffer which has both clock inputs and clock outputs. +This is an example of modeling a clock mux/buffer which utilizes both clock inputs and clock outputs. -According to the "Primitive Block Timing Modeling Tutorial" section "Clock Buffers & Muxes" of the `VTR documentation <https://docs.verilogtorouting.org/en/latest/tutorials/arch/timing_modeling/#clock-muxes>`_, a clock buffer or a clock mux has to have its outputs(s) as combinational sinks of clock input(s). This contradicts with how regular sequential blocks (like flip-flops) have to be modeled. +By default, clocks are excluded from the combinational sink list. IE They do not have `combinational_sink_ports` property associated with them. However, clock multiplexers violate this rule as their input clocks do not drive any sequential logic. They are passed to output(s) instead. VPR requires `Clock buffers & muxes <https://docs.verilogtorouting.org/en/latest/tutorials/arch/timing_modeling/#clock-muxes>`_ to be defined in this way. -V2X provides the attribute `(* NO_COMB *)` that when specified on a clock port and given explicitly the value of 0 will prevent it from getting combinational_sink annotations in XML. + +V2X provides the attribute `(* COMB_INCLUDE_CLOCKS *)` that when specified on an output port makes appear on the `combinational_sink_ports` list of its related input port(s) even if it is marked as a clock input. .. symbolator:: gmux.sim.v @@ -17,7 +18,7 @@ :language: verilog :caption: tests/clock_mux/gmux.sim.v -In this example the `(* NO_COMB *)` attribute is used on clock inputs IP and IC so they don't get any combinational_sink tags. +In this example the `(* COMB_INCLUDE_CLOCKS *)` attribute is set on the `IZ` output making it appear in combinational sinks lists of its associated clock input ports. .. literalinclude:: gmux.model.xml :language: xml
diff --git a/tests/clock_mux/gmux.sim.v b/tests/clock_mux/gmux.sim.v index e56cd47..d5d4492 100644 --- a/tests/clock_mux/gmux.sim.v +++ b/tests/clock_mux/gmux.sim.v
@@ -15,11 +15,11 @@ module GMUX (IP, IC, IS0, IZ); // 1st clock input - (* CLOCK, NO_COMB=0 *) + (* CLOCK *) input wire IP; // 2nd clock input - (* CLOCK, NO_COMB=0 *) + (* CLOCK *) input wire IC; // Select input @@ -29,6 +29,7 @@ (* DELAY_CONST_IP="1e-10" *) (* DELAY_CONST_IC="2e-10" *) (* DELAY_CONST_IS0="3e-10" *) + (* COMB_INCLUDE_CLOCKS *) output wire IZ;
diff --git a/v2x/vlog_to_model.py b/v2x/vlog_to_model.py index ee4240a..88e99a8 100755 --- a/v2x/vlog_to_model.py +++ b/v2x/vlog_to_model.py
@@ -20,13 +20,15 @@ - `(* ASSOC_CLOCK="RDCLK" *)` : force a port's associated clock to a given value - - `(* NO_COMB=1 *)` : Forces removal of all combinational relations of an - input port. + - `(* COMB_INCLUDE_CLOCKS *)` : When specified on a clock input port + allows it to have combinational relations + with other ports. - - `(* NO_COMB=0 *)` : Allows a clock port to have combinational sinks + - `(* NO_COMB *)` : Forces removal of all combinational relations of an + input port. - - `(* NO_SEQ=1 *)` : Forces removal of all sequential relations of an input - port. + - `(* NO_SEQ *)` : Forces removal of all sequential relations of an input + port. The following Verilog attributes are considered on modules: - `(* MODEL_NAME="model" *)` : override the name used for @@ -203,18 +205,6 @@ for name, width, bits, iodir in ports: port_attrs = tmod.port_attrs(name) - # In the end these can be: - # - True when != 1 - # - False when == 0 - # - None when it is not specified - no_comb = tmod.net_attr(name, "NO_COMB") - no_seq = tmod.net_attr(name, "NO_SEQ") - - if no_comb is not None: - no_comb = bool(int(no_comb)) - if no_seq is not None: - no_seq = bool(int(no_seq)) - is_clock = name in clocks or utils.is_clock_name(name) if "CLOCK" in port_attrs: @@ -230,6 +220,14 @@ if is_clock: attrs["is_clock"] = "1" + + # Remove comb sinks that do not have "COMB_INCLUDE_CLOCKS" + # attribute + for sink in sinks: + sink_attrs = tmod.port_attrs(sink) + if int(sink_attrs.get("COMB_INCLUDE_CLOCKS", 0)) == 0: + sinks.remove(sink) + else: clks = list() for clk in clocks: @@ -237,16 +235,12 @@ infiles, top, clk, name, iodir): clks.append(clk) - if clks and no_seq is not True: + if clks and int(port_attrs.get("NO_SEQ", 0)) == 0: attrs["clock"] = " ".join(clks) - # By default do not append combinational sinks to a clock port - # but that may be overriden by (* NO_COMB=0 *) - if len(sinks) > 0 and iodir == "input": - if (not is_clock and no_comb is not True) or \ - (is_clock and no_comb is False): - attrs["combinational_sink_ports"] = " ".join(sinks) - + if len(sinks) > 0 and iodir == "input" and \ + int(port_attrs.get("NO_COMB", 0)) == 0: + attrs["combinational_sink_ports"] = " ".join(sinks) if iodir == "input": ET.SubElement(inports_xml, "port", attrs) elif iodir == "output":