DSP-style block with inputs and outputs registered using separate clocks

A combinational DSP block with registered inputs and outputs. Separate clock is used for inputs and outputs. Modeled as a complex block.

/home/docs/checkouts/readthedocs.org/user_builds/python-symbiflow-v2x/checkouts/latest/docs/examples/dsp/dsp_inout_registered_dualclk/dsp_inout_registered_dualclk.sim.v

tests/dsp/dsp_inout_registered_dualclk/dsp_inout_registered_dualclk.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
`include "./dff/dff.sim.v"
`include "./dsp_combinational/dsp_combinational.sim.v"

/* DSP Block with register on both the inputs and the output, which use different clocks */
module DSP_INOUT_REGISTERED_DUALCLK (iclk, oclk, a, b, m, out);
  localparam DATA_WIDTH = 4;

  input wire iclk;
  input wire oclk;
  input wire [DATA_WIDTH/2-1:0] a;
  input wire [DATA_WIDTH/2-1:0] b;
  input wire m;
  output wire [DATA_WIDTH-1:0] out;

  /* Input registers on iclk */
  (* pack="DFF-DSP" *)
  wire [DATA_WIDTH/2-1:0] q_a;
  (* pack="DFF-DSP" *)
  wire [DATA_WIDTH/2-1:0] q_b;
  (* pack="DFF-DSP" *)
  wire q_m;

  genvar i;
  for (i=0; i<DATA_WIDTH/2; i=i+1) begin: input_dffs_gen
    DFF q_a_ff(.D(a[i]), .Q(q_a[i]), .CLK(iclk));
    DFF q_b_ff(.D(b[i]), .Q(q_b[i]), .CLK(iclk));
  end
  DFF m_ff(.D(m), .Q(q_m), .CLK(iclk));

  /* Combinational logic */
  (* pack="DFF-DSP" *)
  wire [DATA_WIDTH-1:0] c_out;
  DSP_COMBINATIONAL comb (.a(q_a), .b(q_b), .m(q_m), .out(c_out));

  /* Output register on oclk */
  wire [DATA_WIDTH-1:0] q_out;
  genvar j;
  for (j=0; j<DATA_WIDTH; j=j+1) begin: output_dffs_gen
    DFF q_out_ff(.D(c_out[j]), .Q(out[j]), .CLK(oclk));
  end

endmodule
dsp_inout_registered_dualclk.model.xml
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
<?xml version="1.0"?>
<models>
  <model name="DFF">
    <input_ports>
      <port is_clock="1" name="CLK"/>
      <port clock="CLK" name="D"/>
    </input_ports>
    <output_ports>
      <port clock="CLK" name="Q"/>
    </output_ports>
  </model>
  <model name="DSP_COMBINATIONAL">
    <input_ports>
      <port combinational_sink_ports="out" name="a"/>
      <port combinational_sink_ports="out" name="b"/>
      <port combinational_sink_ports="out" name="m"/>
    </input_ports>
    <output_ports>
      <port name="out"/>
    </output_ports>
  </model>
</models>
dsp_inout_registered_dualclk.pb_type.xml
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 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
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
<?xml version="1.0"?>
<pb_type xmlns:xi="http://www.w3.org/2001/XInclude" name="DSP_INOUT_REGISTERED_DUALCLK" num_pb="1">
  <clock name="iclk" num_pins="1"/>
  <clock name="oclk" num_pins="1"/>
  <input name="a" num_pins="2"/>
  <input name="b" num_pins="2"/>
  <input name="m" num_pins="1"/>
  <output name="out" num_pins="4"/>
  <pb_type blif_model=".subckt DSP_COMBINATIONAL" name="comb" num_pb="1">
    <input name="a" num_pins="2"/>
    <input name="b" num_pins="2"/>
    <input name="m" num_pins="1"/>
    <output name="out" num_pins="4"/>
    <delay_constant in_port="DSP_COMBINATIONAL.a" max="30e-12" out_port="DSP_COMBINATIONAL.out"/>
    <delay_constant in_port="DSP_COMBINATIONAL.b" max="30e-12" out_port="DSP_COMBINATIONAL.out"/>
    <delay_constant in_port="DSP_COMBINATIONAL.m" max="10e-12" out_port="DSP_COMBINATIONAL.out"/>
  </pb_type>
  <pb_type blif_model=".subckt DFF" name="input_dffs_gen_q_a_ff_0" num_pb="1">
    <clock name="CLK" num_pins="1"/>
    <input name="D" num_pins="1"/>
    <output name="Q" num_pins="1"/>
    <T_setup clock="CLK" port="DFF.D" value="10e-12"/>
    <T_hold clock="CLK" port="DFF.D" value="10e-12"/>
    <T_clock_to_Q clock="CLK" max="10e-12" port="DFF.Q"/>
  </pb_type>
  <pb_type blif_model=".subckt DFF" name="input_dffs_gen_q_a_ff_1" num_pb="1">
    <clock name="CLK" num_pins="1"/>
    <input name="D" num_pins="1"/>
    <output name="Q" num_pins="1"/>
    <T_setup clock="CLK" port="DFF.D" value="10e-12"/>
    <T_hold clock="CLK" port="DFF.D" value="10e-12"/>
    <T_clock_to_Q clock="CLK" max="10e-12" port="DFF.Q"/>
  </pb_type>
  <pb_type blif_model=".subckt DFF" name="input_dffs_gen_q_b_ff_0" num_pb="1">
    <clock name="CLK" num_pins="1"/>
    <input name="D" num_pins="1"/>
    <output name="Q" num_pins="1"/>
    <T_setup clock="CLK" port="DFF.D" value="10e-12"/>
    <T_hold clock="CLK" port="DFF.D" value="10e-12"/>
    <T_clock_to_Q clock="CLK" max="10e-12" port="DFF.Q"/>
  </pb_type>
  <pb_type blif_model=".subckt DFF" name="input_dffs_gen_q_b_ff_1" num_pb="1">
    <clock name="CLK" num_pins="1"/>
    <input name="D" num_pins="1"/>
    <output name="Q" num_pins="1"/>
    <T_setup clock="CLK" port="DFF.D" value="10e-12"/>
    <T_hold clock="CLK" port="DFF.D" value="10e-12"/>
    <T_clock_to_Q clock="CLK" max="10e-12" port="DFF.Q"/>
  </pb_type>
  <pb_type blif_model=".subckt DFF" name="m_ff" num_pb="1">
    <clock name="CLK" num_pins="1"/>
    <input name="D" num_pins="1"/>
    <output name="Q" num_pins="1"/>
    <T_setup clock="CLK" port="DFF.D" value="10e-12"/>
    <T_hold clock="CLK" port="DFF.D" value="10e-12"/>
    <T_clock_to_Q clock="CLK" max="10e-12" port="DFF.Q"/>
  </pb_type>
  <pb_type blif_model=".subckt DFF" name="output_dffs_gen_q_out_ff_0" num_pb="1">
    <clock name="CLK" num_pins="1"/>
    <input name="D" num_pins="1"/>
    <output name="Q" num_pins="1"/>
    <T_setup clock="CLK" port="DFF.D" value="10e-12"/>
    <T_hold clock="CLK" port="DFF.D" value="10e-12"/>
    <T_clock_to_Q clock="CLK" max="10e-12" port="DFF.Q"/>
  </pb_type>
  <pb_type blif_model=".subckt DFF" name="output_dffs_gen_q_out_ff_1" num_pb="1">
    <clock name="CLK" num_pins="1"/>
    <input name="D" num_pins="1"/>
    <output name="Q" num_pins="1"/>
    <T_setup clock="CLK" port="DFF.D" value="10e-12"/>
    <T_hold clock="CLK" port="DFF.D" value="10e-12"/>
    <T_clock_to_Q clock="CLK" max="10e-12" port="DFF.Q"/>
  </pb_type>
  <pb_type blif_model=".subckt DFF" name="output_dffs_gen_q_out_ff_2" num_pb="1">
    <clock name="CLK" num_pins="1"/>
    <input name="D" num_pins="1"/>
    <output name="Q" num_pins="1"/>
    <T_setup clock="CLK" port="DFF.D" value="10e-12"/>
    <T_hold clock="CLK" port="DFF.D" value="10e-12"/>
    <T_clock_to_Q clock="CLK" max="10e-12" port="DFF.Q"/>
  </pb_type>
  <pb_type blif_model=".subckt DFF" name="output_dffs_gen_q_out_ff_3" num_pb="1">
    <clock name="CLK" num_pins="1"/>
    <input name="D" num_pins="1"/>
    <output name="Q" num_pins="1"/>
    <T_setup clock="CLK" port="DFF.D" value="10e-12"/>
    <T_hold clock="CLK" port="DFF.D" value="10e-12"/>
    <T_clock_to_Q clock="CLK" max="10e-12" port="DFF.Q"/>
  </pb_type>
  <interconnect>
    <direct input="output_dffs_gen_q_out_ff_0.Q" name="DSP_INOUT_REGISTERED_DUALCLK-out[0]" output="DSP_INOUT_REGISTERED_DUALCLK.out[0]"/>
    <direct input="output_dffs_gen_q_out_ff_1.Q" name="DSP_INOUT_REGISTERED_DUALCLK-out[1]" output="DSP_INOUT_REGISTERED_DUALCLK.out[1]"/>
    <direct input="output_dffs_gen_q_out_ff_2.Q" name="DSP_INOUT_REGISTERED_DUALCLK-out[2]" output="DSP_INOUT_REGISTERED_DUALCLK.out[2]"/>
    <direct input="output_dffs_gen_q_out_ff_3.Q" name="DSP_INOUT_REGISTERED_DUALCLK-out[3]" output="DSP_INOUT_REGISTERED_DUALCLK.out[3]"/>
    <direct input="input_dffs_gen_q_a_ff_0.Q" name="comb-a[0]" output="comb.a[0]">
      <pack_pattern in_port="input_dffs_gen_q_a_ff_0.Q" name="pack-DFF-DSP" out_port="comb.a[0]"/>
    </direct>
    <direct input="input_dffs_gen_q_a_ff_1.Q" name="comb-a[1]" output="comb.a[1]">
      <pack_pattern in_port="input_dffs_gen_q_a_ff_1.Q" name="pack-DFF-DSP" out_port="comb.a[1]"/>
    </direct>
    <direct input="input_dffs_gen_q_b_ff_0.Q" name="comb-b[0]" output="comb.b[0]">
      <pack_pattern in_port="input_dffs_gen_q_b_ff_0.Q" name="pack-DFF-DSP" out_port="comb.b[0]"/>
    </direct>
    <direct input="input_dffs_gen_q_b_ff_1.Q" name="comb-b[1]" output="comb.b[1]">
      <pack_pattern in_port="input_dffs_gen_q_b_ff_1.Q" name="pack-DFF-DSP" out_port="comb.b[1]"/>
    </direct>
    <direct input="m_ff.Q" name="comb-m" output="comb.m">
      <pack_pattern in_port="m_ff.Q" name="pack-DFF-DSP" out_port="comb.m"/>
    </direct>
    <direct input="DSP_INOUT_REGISTERED_DUALCLK.iclk" name="input_dffs_gen_q_a_ff_0-CLK" output="input_dffs_gen_q_a_ff_0.CLK"/>
    <direct input="DSP_INOUT_REGISTERED_DUALCLK.a[0]" name="input_dffs_gen_q_a_ff_0-D" output="input_dffs_gen_q_a_ff_0.D"/>
    <direct input="DSP_INOUT_REGISTERED_DUALCLK.iclk" name="input_dffs_gen_q_a_ff_1-CLK" output="input_dffs_gen_q_a_ff_1.CLK"/>
    <direct input="DSP_INOUT_REGISTERED_DUALCLK.a[1]" name="input_dffs_gen_q_a_ff_1-D" output="input_dffs_gen_q_a_ff_1.D"/>
    <direct input="DSP_INOUT_REGISTERED_DUALCLK.iclk" name="input_dffs_gen_q_b_ff_0-CLK" output="input_dffs_gen_q_b_ff_0.CLK"/>
    <direct input="DSP_INOUT_REGISTERED_DUALCLK.b[0]" name="input_dffs_gen_q_b_ff_0-D" output="input_dffs_gen_q_b_ff_0.D"/>
    <direct input="DSP_INOUT_REGISTERED_DUALCLK.iclk" name="input_dffs_gen_q_b_ff_1-CLK" output="input_dffs_gen_q_b_ff_1.CLK"/>
    <direct input="DSP_INOUT_REGISTERED_DUALCLK.b[1]" name="input_dffs_gen_q_b_ff_1-D" output="input_dffs_gen_q_b_ff_1.D"/>
    <direct input="DSP_INOUT_REGISTERED_DUALCLK.iclk" name="m_ff-CLK" output="m_ff.CLK"/>
    <direct input="DSP_INOUT_REGISTERED_DUALCLK.m" name="m_ff-D" output="m_ff.D"/>
    <direct input="DSP_INOUT_REGISTERED_DUALCLK.oclk" name="output_dffs_gen_q_out_ff_0-CLK" output="output_dffs_gen_q_out_ff_0.CLK"/>
    <direct input="comb.out[0]" name="output_dffs_gen_q_out_ff_0-D" output="output_dffs_gen_q_out_ff_0.D">
      <pack_pattern in_port="comb.out[0]" name="pack-DFF-DSP" out_port="output_dffs_gen_q_out_ff_0.D"/>
    </direct>
    <direct input="DSP_INOUT_REGISTERED_DUALCLK.oclk" name="output_dffs_gen_q_out_ff_1-CLK" output="output_dffs_gen_q_out_ff_1.CLK"/>
    <direct input="comb.out[1]" name="output_dffs_gen_q_out_ff_1-D" output="output_dffs_gen_q_out_ff_1.D">
      <pack_pattern in_port="comb.out[1]" name="pack-DFF-DSP" out_port="output_dffs_gen_q_out_ff_1.D"/>
    </direct>
    <direct input="DSP_INOUT_REGISTERED_DUALCLK.oclk" name="output_dffs_gen_q_out_ff_2-CLK" output="output_dffs_gen_q_out_ff_2.CLK"/>
    <direct input="comb.out[2]" name="output_dffs_gen_q_out_ff_2-D" output="output_dffs_gen_q_out_ff_2.D">
      <pack_pattern in_port="comb.out[2]" name="pack-DFF-DSP" out_port="output_dffs_gen_q_out_ff_2.D"/>
    </direct>
    <direct input="DSP_INOUT_REGISTERED_DUALCLK.oclk" name="output_dffs_gen_q_out_ff_3-CLK" output="output_dffs_gen_q_out_ff_3.CLK"/>
    <direct input="comb.out[3]" name="output_dffs_gen_q_out_ff_3-D" output="output_dffs_gen_q_out_ff_3.D">
      <pack_pattern in_port="comb.out[3]" name="pack-DFF-DSP" out_port="output_dffs_gen_q_out_ff_3.D"/>
    </direct>
  </interconnect>
</pb_type>

Detection of combinational connections

  • Output has combinational connection with input

  • pack_pattern defined on wire connections with pack attribute

Blackbox detection

  • Model of the leaf pb_type is generated

  • Leaf pb_type XML is generated

  • All dependency models and pb_types are included in the output files