Forced non-sequential relations to an input

This is a case when a macro block consisting of a LUT and an FF is to be modeled in VPR as a single primitive. The block has two outputs: the first one sources at the LUT directly and the second one passes through an external register:

../../_images/lut_ff_macro.svg
tests/no_seq/lut_ff_macro.sim.v
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
(* whitebox *)
module LUT_FF_MACRO (I0, I1, I2, I3, CLK, Z, QZ);

    // LUT inputs
    (* NO_SEQ *)
    input  wire  I0;
    (* NO_SEQ *)
    input  wire  I1;
    (* NO_SEQ *)
    input  wire  I2;
    (* NO_SEQ *)
    input  wire  I3;

    // Clock input
    input  wire  CLK;

    // Combinational LUT output
    (* DELAY_CONST_I0="1e-10" *)
    (* DELAY_CONST_I1="1e-10" *)
    (* DELAY_CONST_I2="1e-10" *)
    (* DELAY_CONST_I3="1e-10" *)
    output wire  Z;

    // Registered LUT output
    (* DELAY_CONST_I0="2e-10" *)
    (* DELAY_CONST_I1="2e-10" *)
    (* DELAY_CONST_I2="2e-10" *)
    (* DELAY_CONST_I3="2e-10" *)
    (* CLK_TO_Q="CLK 1e-10" *)
    (* SETUP="CLK 1e-10" *)
    (* HOLD="CLK 1e-10" *)
    output reg   QZ;

    // LUT behavioral model
    parameter [15:0] INIT = 16'd0;
    assign Z = INIT[{I3, I2, I1, I0}];

    // FF behavioral model    
    always @(posedge CLK)
        QZ <= Z;

endmodule

Since relation of LUT inputs is combinational for one output and sequential for another they have to be defined in a special way as required by VPR (see VTR documentation). Due to the presence of the output register all sequential annotations are moved to the output port. Hence LUT inputs must not mention any clock signal. This can be achieved in V2X by specifying the (* NO_SEQ *) attribute on them. The attribute prevents V2X from annotating input ports with any clock relations.

lut_ff_macro.model.xml
<?xml version="1.0"?>
<models>
  <model name="LUT_FF_MACRO">
    <input_ports>
      <port is_clock="1" name="CLK"/>
      <port combinational_sink_ports="QZ Z" name="I0"/>
      <port combinational_sink_ports="QZ Z" name="I1"/>
      <port combinational_sink_ports="QZ Z" name="I2"/>
      <port combinational_sink_ports="QZ Z" name="I3"/>
    </input_ports>
    <output_ports>
      <port clock="CLK" name="QZ"/>
      <port name="Z"/>
    </output_ports>
  </model>
</models>
lut_ff_macro.pb_type.xml
<?xml version="1.0"?>
<pb_type xmlns:xi="http://www.w3.org/2001/XInclude" blif_model=".subckt LUT_FF_MACRO" name="LUT_FF_MACRO" num_pb="1">
  <clock name="CLK" num_pins="1"/>
  <input name="I0" num_pins="1"/>
  <input name="I1" num_pins="1"/>
  <input name="I2" num_pins="1"/>
  <input name="I3" num_pins="1"/>
  <output name="QZ" num_pins="1"/>
  <output name="Z" num_pins="1"/>
  <delay_constant in_port="LUT_FF_MACRO.I0" max="2e-10" out_port="LUT_FF_MACRO.QZ"/>
  <delay_constant in_port="LUT_FF_MACRO.I1" max="2e-10" out_port="LUT_FF_MACRO.QZ"/>
  <delay_constant in_port="LUT_FF_MACRO.I2" max="2e-10" out_port="LUT_FF_MACRO.QZ"/>
  <delay_constant in_port="LUT_FF_MACRO.I3" max="2e-10" out_port="LUT_FF_MACRO.QZ"/>
  <delay_constant in_port="LUT_FF_MACRO.I0" max="1e-10" out_port="LUT_FF_MACRO.Z"/>
  <delay_constant in_port="LUT_FF_MACRO.I1" max="1e-10" out_port="LUT_FF_MACRO.Z"/>
  <delay_constant in_port="LUT_FF_MACRO.I2" max="1e-10" out_port="LUT_FF_MACRO.Z"/>
  <delay_constant in_port="LUT_FF_MACRO.I3" max="1e-10" out_port="LUT_FF_MACRO.Z"/>
  <T_setup clock="CLK" port="LUT_FF_MACRO.QZ" value="1e-10"/>
  <T_hold clock="CLK" port="LUT_FF_MACRO.QZ" value="1e-10"/>
  <T_clock_to_Q clock="CLK" max="1e-10" port="LUT_FF_MACRO.QZ"/>
</pb_type>