-
Notifications
You must be signed in to change notification settings - Fork 0
/
EArch_fixed.xml
1459 lines (1444 loc) · 84.7 KB
/
EArch_fixed.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
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
<!--
Flagship Heterogeneous Architecture with Carry Chains for VTR 7.0.
- 40 nm technology
- General purpose logic block:
K = 6, N = 10, fracturable 6 LUTs (can operate as one 6-LUT or two 5-LUTs with all 5 inputs shared)
with optionally registered outputs
Each 5-LUT has an arithemtic mode that converts it to a single-bit adder with both inputs driven by 4-LUTs (both 4-LUTs share all 4 inputs)
Carry chain links to vertically adjacent logic blocks
- Memory size 32 Kbits, memory aspect ratios vary from a data width of 1 to data width of 64.
Height = 6, found on every (8n+2)th column
- Multiplier modes: one 36x36, two 18x18, each 18x18 can also operate as two 9x9.
Height = 4, found on every (8n+6)th column
- Routing architecture: L = 4, fc_in = 0.15, Fc_out = 0.1
Details on Modelling:
The electrical design of the architecture described here is NOT from an
optimized, SPICED architecture. Instead, we attempt to create a reasonable
architecture file by using an existing commercial FPGA to approximate the area,
delay, and power of the underlying components. This is combined with a reasonable 40 nm
model of wiring and circuit design for low-level routing components, where available.
The resulting architecture has delays that roughly match a commercial 40 nm FPGA, but also
has wiring electrical parameters that allow the wire lengths and switch patterns to be
modified and you will still get reasonable delay results for the new architecture.
The following describes, in detail, how we obtained the various electrical values for this
architecture.
Rmin for nmos and pmos, routing buffer sizes, and I/O pad delays are from the ifar
architecture created by Ian Kuon: K06 N10 45nm fc 0.15 area-delay optimized architecture.
(n10k06l04.fc15.area1delay1.cmos45nm.bptm.cmos45nm.xml)
This routing architecture was optimized for 45 nm, and we have scaled it linearly to 40 nm to
match the overall target (a 40 nm FPGA).
We obtain delay numbers by measuring delays of routing, soft logic blocks,
memories, and multipliers from test circuits on a Stratix IV GX device
(EP4SGX230DF29C2X, i.e. fastest speed grade). For routing, we took the average delay of H4 and V4
wires. Rmetal and Cmetal values for the routing wires were obtained from work done by Charles
Chiasson. We use a 96 nm half-pitch (corresponding to mid-level metal stack 40 nm routing) and
take the R and C data from the ITRS roadmap.
For the general purpose logic block, we assume that the area and delays of the Stratix IV
crossbar is close enough to the crossbar modelled here.
Stratix IV uses 52 inputs and 20 feedback lines, but only a half-populated crossbar, leading to
36:1 multiplexers. We match these parameters in this architecture.
For LUTs, we include LUT
delays measured from Stratix IV which is dependant on the input used (ie. some
LUT inputs are faster than others). The CAD tools at the time of VTR 7 does
not consider differences in LUT input delays.
Adder delays obtained as approximate values from a Stratix IV EP4SE230F29C3 device.
Delay obtained by compiling a 256 bit adder (registered inputs and outputs,
all pins except clock virtual) then measuring the delays in chip-planner,
sumout delay = 0.271ns to 0.348 ns, intra-block carry delay = 0.011 ns,
inter-block carry delay = 0.327 ns. Given this data, I will approximate
sumout 0.3 ns, intra-block carry-delay = 0.01 ns, and
inter-block carry-delay = 0.16 ns (since Altera inter-block carry delay has
overhead that we don't have, I'll approximate the delay of a simpler chain at
one half what they have. This is very rough, anything from 0.01ns to 0.327ns
can be justified).
Logic block area numbers obtained by scaling overall tile area of a 65nm
Stratix III device, (as given in Wong, Betz and Rose, FPGA 2011) to 40 nm, then subtracting out
routing area at a channel width of 300. We use a channel width of 300 because it can route
all the VTR 6.0 benchmark circuits with an approximately 20% safety margin, and is also close to the
total channel width of Stratix IV. Hence this channel width is close to the commercial practice of
choosing a width that provides high routability. The architecture can be routed at different channel
widths, but we estimate the tile size and hence the physical length of routing wires assuming
a channel width of 300.
Sanity checks employed:
1. We confirmed the routing buffer delay is ~1/3rd of total routing delay at L = 4. This matches
common electrical design.
Authors: Jason Luu, Jeff Goeders, Vaughn Betz
-->
<architecture>
<!--
ODIN II specific config begins
Describes the types of user-specified netlist blocks (in blif, this corresponds to
".model [type_of_block]") that this architecture supports.
Note: Basic LUTs, I/Os, and flip-flops are not included here as there are
already special structures in blif (.names, .input, .output, and .latch)
that describe them.
-->
<models>
<model name="multiply">
<input_ports>
<port name="a" combinational_sink_ports="out"/>
<port name="b" combinational_sink_ports="out"/>
</input_ports>
<output_ports>
<port name="out"/>
</output_ports>
</model>
<model name="single_port_ram">
<input_ports>
<port name="we" clock="clk"/>
<!-- control -->
<port name="addr" clock="clk"/>
<!-- address lines -->
<port name="data" clock="clk"/>
<!-- data lines can be broken down into smaller bit widths minimum size 1 -->
<port name="clk" is_clock="1"/>
<!-- memories are often clocked -->
</input_ports>
<output_ports>
<port name="out" clock="clk"/>
<!-- output can be broken down into smaller bit widths minimum size 1 -->
</output_ports>
</model>
<model name="dual_port_ram">
<input_ports>
<port name="we1" clock="clk"/>
<!-- write enable -->
<port name="we2" clock="clk"/>
<!-- write enable -->
<port name="addr1" clock="clk"/>
<!-- address lines -->
<port name="addr2" clock="clk"/>
<!-- address lines -->
<port name="data1" clock="clk"/>
<!-- data lines can be broken down into smaller bit widths minimum size 1 -->
<port name="data2" clock="clk"/>
<!-- data lines can be broken down into smaller bit widths minimum size 1 -->
<port name="clk" is_clock="1"/>
<!-- memories are often clocked -->
</input_ports>
<output_ports>
<port name="out1" clock="clk"/>
<!-- output can be broken down into smaller bit widths minimum size 1 -->
<port name="out2" clock="clk"/>
<!-- output can be broken down into smaller bit widths minimum size 1 -->
</output_ports>
</model>
<model name="adder">
<input_ports>
<port name="a" combinational_sink_ports="cout sumout"/>
<port name="b" combinational_sink_ports="cout sumout"/>
<port name="cin" combinational_sink_ports="cout sumout"/>
</input_ports>
<output_ports>
<port name="cout"/>
<port name="sumout"/>
</output_ports>
</model>
</models>
<tiles>
<tile name="io" area="0">
<sub_tile name="io" capacity="8">
<equivalent_sites>
<site pb_type="io" pin_mapping="direct"/>
</equivalent_sites>
<input name="outpad" num_pins="1"/>
<output name="inpad" num_pins="1"/>
<clock name="clock" num_pins="1"/>
<fc in_type="frac" in_val="0.15" out_type="frac" out_val="0.10"/>
<pinlocations pattern="custom">
<loc side="left">io.outpad io.inpad io.clock</loc>
<loc side="top">io.outpad io.inpad io.clock</loc>
<loc side="right">io.outpad io.inpad io.clock</loc>
<loc side="bottom">io.outpad io.inpad io.clock</loc>
</pinlocations>
</sub_tile>
</tile>
<tile name="clb" area="53894">
<sub_tile name="clb">
<equivalent_sites>
<site pb_type="clb" pin_mapping="direct"/>
</equivalent_sites>
<input name="I1" num_pins="13" equivalent="full"/>
<input name="I2" num_pins="13" equivalent="full"/>
<input name="I3" num_pins="13" equivalent="full"/>
<input name="I4" num_pins="13" equivalent="full"/>
<input name="cin" num_pins="1"/>
<output name="O" num_pins="20" equivalent="none"/>
<output name="cout" num_pins="1"/>
<clock name="clk" num_pins="1"/>
<fc in_type="frac" in_val="0.15" out_type="frac" out_val="0.10">
<fc_override port_name="cin" fc_type="frac" fc_val="0"/>
<fc_override port_name="cout" fc_type="frac" fc_val="0"/>
</fc>
<pinlocations pattern="spread"/>
</sub_tile>
</tile>
<tile name="mult_36" height="4" area="396000">
<sub_tile name="mult_36">
<equivalent_sites>
<site pb_type="mult_36" pin_mapping="direct"/>
</equivalent_sites>
<input name="a" num_pins="36"/>
<input name="b" num_pins="36"/>
<output name="out" num_pins="72"/>
<fc in_type="frac" in_val="0.15" out_type="frac" out_val="0.10"/>
<pinlocations pattern="spread"/>
</sub_tile>
</tile>
<tile name="memory" height="6" area="548000">
<sub_tile name="memory">
<equivalent_sites>
<site pb_type="memory" pin_mapping="direct"/>
</equivalent_sites>
<input name="addr1" num_pins="15"/>
<input name="addr2" num_pins="15"/>
<input name="data" num_pins="64"/>
<input name="we1" num_pins="1"/>
<input name="we2" num_pins="1"/>
<output name="out" num_pins="64"/>
<clock name="clk" num_pins="1"/>
<fc in_type="frac" in_val="0.15" out_type="frac" out_val="0.10"/>
<pinlocations pattern="spread"/>
</sub_tile>
</tile>
</tiles>
<!-- ODIN II specific config ends -->
<!-- Physical descriptions begin -->
<layout>
<auto_layout aspect_ratio="1.0">
<!--Perimeter of 'io' blocks with 'EMPTY' blocks at corners-->
<perimeter type="io" priority="100"/>
<corners type="EMPTY" priority="101"/>
<!--Fill with 'clb'-->
<fill type="clb" priority="10"/>
<!--Column of 'mult_36' with 'EMPTY' blocks wherever a 'mult_36' does not fit. Vertical offset by 1 for perimeter.-->
<col type="mult_36" startx="6" starty="1" repeatx="8" priority="20"/>
<col type="EMPTY" startx="6" repeatx="8" starty="1" priority="19"/>
<!--Column of 'memory' with 'EMPTY' blocks wherever a 'memory' does not fit. Vertical offset by 1 for perimeter.-->
<col type="memory" startx="2" starty="1" repeatx="8" priority="20"/>
<col type="EMPTY" startx="2" repeatx="8" starty="1" priority="19"/>
</auto_layout>
<fixed_layout name="fixed" width="20" height="20">
<!--Perimeter of 'io' blocks with 'EMPTY' blocks at corners-->
<perimeter type="io" priority="100"/>
<corners type="EMPTY" priority="101"/>
<!--Fill with 'clb'-->
<fill type="clb" priority="10"/>
<!--Column of 'mult_36' with 'EMPTY' blocks wherever a 'mult_36' does not fit. Vertical offset by 1 for perimeter.-->
<col type="mult_36" startx="6" starty="1" repeatx="8" priority="20"/>
<col type="EMPTY" startx="6" repeatx="8" starty="1" priority="19"/>
<!--Column of 'memory' with 'EMPTY' blocks wherever a 'memory' does not fit. Vertical offset by 1 for perimeter.-->
<col type="memory" startx="2" starty="1" repeatx="8" priority="20"/>
<col type="EMPTY" startx="2" repeatx="8" starty="1" priority="19"/>
</fixed_layout>
</layout>
<device>
<!-- VB & JL: Using Ian Kuon's transistor sizing and drive strength data for routing, at 40 nm. Ian used BPTM
models. We are modifying the delay values however, to include metal C and R, which allows more architecture
experimentation. We are also modifying the relative resistance of PMOS to be 1.8x that of NMOS
(vs. Ian's 3x) as 1.8x lines up with Jeff G's data from a 45 nm process (and is more typical of
45 nm in general). I'm upping the Rmin_nmos from Ian's just over 6k to nearly 9k, and dropping
RminW_pmos from 18k to 16k to hit this 1.8x ratio, while keeping the delays of buffers approximately
lined up with Stratix IV.
We are using Jeff G.'s capacitance data for 45 nm (in tech/ptm_45nm).
Jeff's tables list C in for transistors with widths in multiples of the minimum feature size (45 nm).
The minimum contactable transistor is 2.5 * 45 nm, so I need to multiply drive strength sizes in this file
by 2.5x when looking up in Jeff's tables.
The delay values are lined up with Stratix IV, which has an architecture similar to this
proposed FPGA, and which is also 40 nm
C_ipin_cblock: input capacitance of a track buffer, which VPR assumes is a single-stage
4x minimum drive strength buffer. -->
<sizing R_minW_nmos="8926" R_minW_pmos="16067"/>
<!-- The grid_logic_tile_area below will be used for all blocks that do not explicitly set their own (non-routing)
area; set to 0 since we explicitly set the area of all blocks currently in this architecture file.
-->
<area grid_logic_tile_area="0"/>
<chan_width_distr>
<x distr="uniform" peak="1.000000"/>
<y distr="uniform" peak="1.000000"/>
</chan_width_distr>
<switch_block type="wilton" fs="3"/>
<connection_block input_switch_name="ipin_cblock"/>
</device>
<switchlist>
<!-- VB: the mux_trans_size and buf_size data below is in minimum width transistor *areas*, assuming the purple
book area formula. This means the mux transistors are about 5x minimum drive strength.
We assume the first stage of the buffer is 3x min drive strength to be reasonable given the large
mux transistors, and this gives a reasonable stage ratio of a bit over 5x to the second stage. We assume
the n and p transistors in the first stage are equal-sized to lower the buffer trip point, since it's fed
by a pass transistor mux. We can then reverse engineer the buffer second stage to hit the specified
buf_size (really buffer area) - 16.2x minimum drive nmos and 1.8*16.2 = 29.2x minimum drive.
I then took the data from Jeff G.'s PTM modeling of 45 nm to get the Cin (gate of first stage) and Cout
(diff of second stage) listed below. Jeff's models are in tech/ptm_45nm, and are in min feature multiples.
The minimum contactable transistor is 2.5 * 45 nm, so I need to multiply the drive strength sizes above by
2.5x when looking up in Jeff's tables.
Finally, we choose a switch delay (58 ps) that leads to length 4 wires having a delay equal to that of SIV of 126 ps.
This also leads to the switch being 46% of the total wire delay, which is reasonable. -->
<switch type="mux" name="0" R="551" Cin=".77e-15" Cout="4e-15" Tdel="58e-12" mux_trans_size="2.630740" buf_size="27.645901"/>
<!--switch ipin_cblock resistance set to yeild for 4x minimum drive strength buffer-->
<switch type="mux" name="ipin_cblock" R="2231.5" Cout="0." Cin="1.47e-15" Tdel="7.247000e-11" mux_trans_size="1.222260" buf_size="auto"/>
</switchlist>
<segmentlist>
<!--- VB & JL: using ITRS metal stack data, 96 nm half pitch wires, which are intermediate metal width/space.
With the 96 nm half pitch, such wires would take 60 um of height, vs. a 90 nm high (approximated as square) Stratix IV tile so this seems
reasonable. Using a tile length of 90 nm, corresponding to the length of a Stratix IV tile if it were square. -->
<segment freq="1.000000" length="4" type="unidir" Rmetal="101" Cmetal="22.5e-15">
<mux name="0"/>
<sb type="pattern">1 1 1 1 1</sb>
<cb type="pattern">1 1 1 1</cb>
</segment>
</segmentlist>
<directlist>
<direct name="adder_carry" from_pin="clb.cout" to_pin="clb.cin" x_offset="0" y_offset="-1" z_offset="0"/>
</directlist>
<complexblocklist>
<!-- Define I/O pads begin -->
<!-- Capacity is a unique property of I/Os, it is the maximum number of I/Os that can be placed at the same (X,Y) location on the FPGA -->
<!-- Not sure of the area of an I/O (varies widely), and it's not relevant to the design of the FPGA core, so we're setting it to 0. -->
<pb_type name="io">
<input name="outpad" num_pins="1"/>
<output name="inpad" num_pins="1"/>
<clock name="clock" num_pins="1"/>
<!-- IOs can operate as either inputs or outputs.
Delays below come from Ian Kuon. They are small, so they should be interpreted as
the delays to and from registers in the I/O (and generally I/Os are registered
today and that is when you timing analyze them.
-->
<mode name="inpad">
<pb_type name="inpad" blif_model=".input" num_pb="1">
<output name="inpad" num_pins="1"/>
</pb_type>
<interconnect>
<direct name="inpad" input="inpad.inpad" output="io.inpad">
<delay_constant max="4.243e-11" in_port="inpad.inpad" out_port="io.inpad"/>
</direct>
</interconnect>
</mode>
<mode name="outpad">
<pb_type name="outpad" blif_model=".output" num_pb="1">
<input name="outpad" num_pins="1"/>
</pb_type>
<interconnect>
<direct name="outpad" input="io.outpad" output="outpad.outpad">
<delay_constant max="1.394e-11" in_port="io.outpad" out_port="outpad.outpad"/>
</direct>
</interconnect>
</mode>
<!-- Every input pin is driven by 15% of the tracks in a channel, every output pin is driven by 10% of the tracks in a channel -->
<!-- IOs go on the periphery of the FPGA, for consistency,
make it physically equivalent on all sides so that only one definition of I/Os is needed.
If I do not make a physically equivalent definition, then I need to define 4 different I/Os, one for each side of the FPGA
-->
<!-- Place I/Os on the sides of the FPGA -->
<power method="ignore"/>
</pb_type>
<!-- Define I/O pads ends -->
<!-- Define general purpose logic block (CLB) begin -->
<!--- Area calculation: Total Stratix IV tile area is about 8100 um^2, and a minimum width transistor
area is 60 L^2 yields a tile area of 84375 MWTAs.
Routing at W=300 is 30481 MWTAs, leaving us with a total of 53000 MWTAs for logic block area
This means that only 37% of our area is in the general routing, and 63% is inside the logic
block. Note that the crossbar / local interconnect is considered part of the logic block
area in this analysis. That is a lower proportion of of routing area than most academics
assume, but note that the total routing area really includes the crossbar, which would push
routing area up significantly, we estimate into the ~70% range.
-->
<pb_type name="clb">
<input name="I1" num_pins="13" equivalent="full"/>
<input name="I2" num_pins="13" equivalent="full"/>
<input name="I3" num_pins="13" equivalent="full"/>
<input name="I4" num_pins="13" equivalent="full"/>
<input name="cin" num_pins="1"/>
<output name="O" num_pins="20" equivalent="none"/>
<output name="cout" num_pins="1"/>
<clock name="clk" num_pins="1"/>
<!-- Describe fracturable logic element.
Each fracturable logic element has a 6-LUT that can alternatively operate as two 5-LUTs with shared inputs.
The outputs of the fracturable logic element can be optionally registered
-->
<pb_type name="fle" num_pb="10">
<input name="in" num_pins="8"/>
<input name="cin" num_pins="1"/>
<output name="out" num_pins="2"/>
<output name="cout" num_pins="1"/>
<clock name="clk" num_pins="1"/>
<mode name="n2_lut5">
<pb_type name="lut5inter" num_pb="1">
<input name="in" num_pins="8"/>
<input name="cin" num_pins="1"/>
<output name="out" num_pins="2"/>
<output name="cout" num_pins="1"/>
<clock name="clk" num_pins="1"/>
<pb_type name="ble5" num_pb="2">
<input name="in" num_pins="5"/>
<input name="cin" num_pins="1"/>
<output name="out" num_pins="1"/>
<output name="cout" num_pins="1"/>
<clock name="clk" num_pins="1"/>
<mode name="blut5">
<pb_type name="flut5" num_pb="1">
<input name="in" num_pins="5"/>
<output name="out" num_pins="1"/>
<clock name="clk" num_pins="1"/>
<!-- Regular LUT mode -->
<pb_type name="lut5" blif_model=".names" num_pb="1" class="lut">
<input name="in" num_pins="5" port_class="lut_in"/>
<output name="out" num_pins="1" port_class="lut_out"/>
<!-- LUT timing using delay matrix -->
<!-- These are the physical delay inputs on a Stratix IV LUT but because VPR cannot do LUT rebalancing,
we instead take the average of these numbers to get more stable results
82e-12
173e-12
261e-12
263e-12
398e-12
-->
<delay_matrix type="max" in_port="lut5.in" out_port="lut5.out">
235e-12
235e-12
235e-12
235e-12
235e-12
</delay_matrix>
</pb_type>
<pb_type name="ff" blif_model=".latch" num_pb="1" class="flipflop">
<input name="D" num_pins="1" port_class="D"/>
<output name="Q" num_pins="1" port_class="Q"/>
<clock name="clk" num_pins="1" port_class="clock"/>
<T_setup value="66e-12" port="ff.D" clock="clk"/>
<T_clock_to_Q max="124e-12" port="ff.Q" clock="clk"/>
</pb_type>
<interconnect>
<direct name="direct1" input="flut5.in" output="lut5.in"/>
<direct name="direct2" input="lut5.out" output="ff.D">
<pack_pattern name="ble5" in_port="lut5.out" out_port="ff.D"/>
</direct>
<direct name="direct3" input="flut5.clk" output="ff.clk"/>
<mux name="mux1" input="ff.Q lut5.out" output="flut5.out">
<delay_constant max="25e-12" in_port="lut5.out" out_port="flut5.out"/>
<delay_constant max="45e-12" in_port="ff.Q" out_port="flut5.out"/>
</mux>
</interconnect>
</pb_type>
<interconnect>
<direct name="direct1" input="ble5.in" output="flut5.in"/>
<direct name="direct2" input="ble5.clk" output="flut5.clk"/>
<direct name="direct3" input="flut5.out" output="ble5.out"/>
</interconnect>
</mode>
<mode name="arithmetic">
<pb_type name="arithmetic" num_pb="1">
<input name="in" num_pins="4"/>
<input name="cin" num_pins="1"/>
<output name="out" num_pins="1"/>
<output name="cout" num_pins="1"/>
<clock name="clk" num_pins="1"/>
<!-- Special dual-LUT mode that drives adder only -->
<pb_type name="lut4" blif_model=".names" num_pb="2" class="lut">
<input name="in" num_pins="4" port_class="lut_in"/>
<output name="out" num_pins="1" port_class="lut_out"/>
<!-- LUT timing using delay matrix -->
<!-- These are the physical delay inputs on a Stratix IV LUT but because VPR cannot do LUT rebalancing,
we instead take the average of these numbers to get more stable results
82e-12
173e-12
261e-12
263e-12
-->
<delay_matrix type="max" in_port="lut4.in" out_port="lut4.out">
195e-12
195e-12
195e-12
195e-12
</delay_matrix>
</pb_type>
<pb_type name="adder" blif_model=".subckt adder" num_pb="1">
<input name="a" num_pins="1"/>
<input name="b" num_pins="1"/>
<input name="cin" num_pins="1"/>
<output name="cout" num_pins="1"/>
<output name="sumout" num_pins="1"/>
<delay_constant max="0.3e-9" in_port="adder.a" out_port="adder.sumout"/>
<delay_constant max="0.3e-9" in_port="adder.b" out_port="adder.sumout"/>
<delay_constant max="0.3e-9" in_port="adder.cin" out_port="adder.sumout"/>
<delay_constant max="0.3e-9" in_port="adder.a" out_port="adder.cout"/>
<delay_constant max="0.3e-9" in_port="adder.b" out_port="adder.cout"/>
<delay_constant max="0.01e-9" in_port="adder.cin" out_port="adder.cout"/>
</pb_type>
<pb_type name="ff" blif_model=".latch" num_pb="1" class="flipflop">
<input name="D" num_pins="1" port_class="D"/>
<output name="Q" num_pins="1" port_class="Q"/>
<clock name="clk" num_pins="1" port_class="clock"/>
<T_setup value="66e-12" port="ff.D" clock="clk"/>
<T_clock_to_Q max="124e-12" port="ff.Q" clock="clk"/>
</pb_type>
<interconnect>
<direct name="clock" input="arithmetic.clk" output="ff.clk"/>
<direct name="lut_in1" input="arithmetic.in[3:0]" output="lut4[0:0].in[3:0]"/>
<direct name="lut_in2" input="arithmetic.in[3:0]" output="lut4[1:1].in[3:0]"/>
<direct name="lut_to_add1" input="lut4[0:0].out" output="adder.a">
</direct>
<direct name="lut_to_add2" input="lut4[1:1].out" output="adder.b">
</direct>
<direct name="add_to_ff" input="adder.sumout" output="ff.D">
<pack_pattern name="chain" in_port="adder.sumout" out_port="ff.D"/>
</direct>
<direct name="carry_in" input="arithmetic.cin" output="adder.cin">
<pack_pattern name="chain" in_port="arithmetic.cin" out_port="adder.cin"/>
</direct>
<direct name="carry_out" input="adder.cout" output="arithmetic.cout">
<pack_pattern name="chain" in_port="adder.cout" out_port="arithmetic.cout"/>
</direct>
<mux name="sumout" input="ff.Q adder.sumout" output="arithmetic.out">
<delay_constant max="25e-12" in_port="adder.sumout" out_port="arithmetic.out"/>
<delay_constant max="45e-12" in_port="ff.Q" out_port="arithmetic.out"/>
</mux>
</interconnect>
</pb_type>
<interconnect>
<direct name="direct1" input="ble5.in[3:0]" output="arithmetic.in"/>
<direct name="carry_in" input="ble5.cin" output="arithmetic.cin">
<pack_pattern name="chain" in_port="ble5.cin" out_port="arithmetic.cin"/>
</direct>
<direct name="carry_out" input="arithmetic.cout" output="ble5.cout">
<pack_pattern name="chain" in_port="arithmetic.cout" out_port="ble5.cout"/>
</direct>
<direct name="direct2" input="ble5.clk" output="arithmetic.clk"/>
<direct name="direct3" input="arithmetic.out" output="ble5.out"/>
</interconnect>
</mode>
</pb_type>
<interconnect>
<direct name="direct1" input="lut5inter.in[4:0]" output="ble5[0:0].in"/>
<direct name="direct2" input="lut5inter.in[7:3]" output="ble5[1:1].in"/>
<direct name="direct3" input="ble5[1:0].out" output="lut5inter.out"/>
<direct name="carry_in" input="lut5inter.cin" output="ble5[0:0].cin">
<pack_pattern name="chain" in_port="lut5inter.cin" out_port="ble5[0:0].cin"/>
</direct>
<direct name="carry_out" input="ble5[1:1].cout" output="lut5inter.cout">
<pack_pattern name="chain" in_port="ble5[1:1].cout" out_port="lut5inter.cout"/>
</direct>
<direct name="carry_link" input="ble5[0:0].cout" output="ble5[1:1].cin">
<pack_pattern name="chain" in_port="ble5[0:0].cout" out_port="ble5[1:1].cout"/>
</direct>
<complete name="complete1" input="lut5inter.clk" output="ble5[1:0].clk"/>
</interconnect>
</pb_type>
<interconnect>
<direct name="direct1" input="fle.in" output="lut5inter.in"/>
<direct name="direct2" input="lut5inter.out" output="fle.out"/>
<direct name="direct3" input="fle.clk" output="lut5inter.clk"/>
<direct name="carry_in" input="fle.cin" output="lut5inter.cin">
<pack_pattern name="chain" in_port="fle.cin" out_port="lut5inter.cin"/>
</direct>
<direct name="carry_out" input="lut5inter.cout" output="fle.cout">
<pack_pattern name="chain" in_port="lut5inter.cout" out_port="fle.cout"/>
</direct>
</interconnect>
</mode>
<!-- n2_lut5 -->
<mode name="n1_lut6">
<pb_type name="ble6" num_pb="1">
<input name="in" num_pins="6"/>
<output name="out" num_pins="1"/>
<clock name="clk" num_pins="1"/>
<pb_type name="lut6" blif_model=".names" num_pb="1" class="lut">
<input name="in" num_pins="6" port_class="lut_in"/>
<output name="out" num_pins="1" port_class="lut_out"/>
<!-- LUT timing using delay matrix -->
<!-- These are the physical delay inputs on a Stratix IV LUT but because VPR cannot do LUT rebalancing,
we instead take the average of these numbers to get more stable results
82e-12
173e-12
261e-12
263e-12
398e-12
397e-12
-->
<delay_matrix type="max" in_port="lut6.in" out_port="lut6.out">
261e-12
261e-12
261e-12
261e-12
261e-12
261e-12
</delay_matrix>
</pb_type>
<pb_type name="ff" blif_model=".latch" num_pb="1" class="flipflop">
<input name="D" num_pins="1" port_class="D"/>
<output name="Q" num_pins="1" port_class="Q"/>
<clock name="clk" num_pins="1" port_class="clock"/>
<T_setup value="66e-12" port="ff.D" clock="clk"/>
<T_clock_to_Q max="124e-12" port="ff.Q" clock="clk"/>
</pb_type>
<interconnect>
<direct name="direct1" input="ble6.in" output="lut6[0:0].in"/>
<direct name="direct2" input="lut6.out" output="ff.D">
<pack_pattern name="ble6" in_port="lut6.out" out_port="ff.D"/>
</direct>
<direct name="direct3" input="ble6.clk" output="ff.clk"/>
<mux name="mux1" input="ff.Q lut6.out" output="ble6.out">
<delay_constant max="25e-12" in_port="lut6.out" out_port="ble6.out"/>
<delay_constant max="45e-12" in_port="ff.Q" out_port="ble6.out"/>
</mux>
</interconnect>
</pb_type>
<interconnect>
<direct name="direct1" input="fle.in[5:0]" output="ble6.in"/>
<direct name="direct2" input="ble6.out" output="fle.out[0:0]"/>
<direct name="direct3" input="fle.clk" output="ble6.clk"/>
</interconnect>
</mode>
<!-- n1_lut6 -->
</pb_type>
<interconnect>
<!-- We use a 50% depop crossbar built using small full xbars to get sets of logically equivalent pins at inputs of CLB
The delays below come from Stratix IV. the delay through a connection block
input mux + the crossbar in Stratix IV is 167 ps. We already have a 72 ps
delay on the connection block input mux (modeled by Ian Kuon), so the remaining
delay within the crossbar is 95 ps.
The delays of cluster feedbacks in Stratix IV is 100 ps, when driven by a LUT.
Since all our outputs LUT outputs go to a BLE output, and have a delay of
25 ps to do so, we subtract 25 ps from the 100 ps delay of a feedback
to get the part that should be marked on the crossbar. -->
<!-- 50% sparsely populated local routing -->
<complete name="lutA" input="clb.I4 clb.I3 fle[1:0].out fle[3:2].out fle[8:8].out" output="fle[9:0].in[0:0]">
<delay_constant max="95e-12" in_port="clb.I4" out_port="fle.in[0:0]"/>
<delay_constant max="95e-12" in_port="clb.I3" out_port="fle.in[0:0]"/>
<delay_constant max="75e-12" in_port="fle[1:0].out" out_port="fle.in[0:0]"/>
<delay_constant max="75e-12" in_port="fle[3:2].out" out_port="fle.in[0:0]"/>
<delay_constant max="75e-12" in_port="fle[8:8].out" out_port="fle.in[0:0]"/>
</complete>
<complete name="lutB" input="clb.I3 clb.I2 fle[3:2].out fle[5:4].out fle[9:9].out" output="fle[9:0].in[1:1]">
<delay_constant max="95e-12" in_port="clb.I3" out_port="fle.in[1:1]"/>
<delay_constant max="95e-12" in_port="clb.I2" out_port="fle.in[1:1]"/>
<delay_constant max="75e-12" in_port="fle[3:2].out" out_port="fle.in[1:1]"/>
<delay_constant max="75e-12" in_port="fle[5:4].out" out_port="fle.in[1:1]"/>
<delay_constant max="75e-12" in_port="fle[9:9].out" out_port="fle.in[1:1]"/>
</complete>
<complete name="lutC" input="clb.I2 clb.I1 fle[5:4].out fle[7:6].out fle[8:8].out" output="fle[9:0].in[2:2]">
<delay_constant max="95e-12" in_port="clb.I2" out_port="fle.in[2:2]"/>
<delay_constant max="95e-12" in_port="clb.I1" out_port="fle.in[2:2]"/>
<delay_constant max="75e-12" in_port="fle[5:4].out" out_port="fle.in[2:2]"/>
<delay_constant max="75e-12" in_port="fle[7:6].out" out_port="fle.in[2:2]"/>
<delay_constant max="75e-12" in_port="fle[8:8].out" out_port="fle.in[2:2]"/>
</complete>
<complete name="lutD" input="clb.I4 clb.I2 fle[1:0].out fle[5:4].out fle[9:9].out" output="fle[9:0].in[3:3]">
<delay_constant max="95e-12" in_port="clb.I4" out_port="fle.in[3:3]"/>
<delay_constant max="95e-12" in_port="clb.I2" out_port="fle.in[3:3]"/>
<delay_constant max="75e-12" in_port="fle[1:0].out" out_port="fle.in[3:3]"/>
<delay_constant max="75e-12" in_port="fle[5:4].out" out_port="fle.in[3:3]"/>
<delay_constant max="75e-12" in_port="fle[9:9].out" out_port="fle.in[3:3]"/>
</complete>
<complete name="lutE" input="clb.I3 clb.I1 fle[3:2].out fle[7:6].out fle[8:8].out" output="fle[9:0].in[4:4]">
<delay_constant max="95e-12" in_port="clb.I3" out_port="fle.in[4:4]"/>
<delay_constant max="95e-12" in_port="clb.I1" out_port="fle.in[4:4]"/>
<delay_constant max="75e-12" in_port="fle[3:2].out" out_port="fle.in[4:4]"/>
<delay_constant max="75e-12" in_port="fle[7:6].out" out_port="fle.in[4:4]"/>
<delay_constant max="75e-12" in_port="fle[8:8].out" out_port="fle.in[4:4]"/>
</complete>
<complete name="lutF" input="clb.I4 clb.I1 fle[1:0].out fle[7:6].out fle[9:9].out" output="fle[9:0].in[5:5]">
<delay_constant max="95e-12" in_port="clb.I4" out_port="fle.in[5:5]"/>
<delay_constant max="95e-12" in_port="clb.I1" out_port="fle.in[5:5]"/>
<delay_constant max="75e-12" in_port="fle[1:0].out" out_port="fle.in[5:5]"/>
<delay_constant max="75e-12" in_port="fle[7:6].out" out_port="fle.in[5:5]"/>
<delay_constant max="75e-12" in_port="fle[9:9].out" out_port="fle.in[5:5]"/>
</complete>
<complete name="lutG" input="clb.I4 clb.I3 fle[1:0].out fle[3:2].out fle[8:8].out" output="fle[9:0].in[6:6]">
<delay_constant max="95e-12" in_port="clb.I4" out_port="fle.in[6:6]"/>
<delay_constant max="95e-12" in_port="clb.I3" out_port="fle.in[6:6]"/>
<delay_constant max="75e-12" in_port="fle[1:0].out" out_port="fle.in[6:6]"/>
<delay_constant max="75e-12" in_port="fle[3:2].out" out_port="fle.in[6:6]"/>
<delay_constant max="75e-12" in_port="fle[8:8].out" out_port="fle.in[6:6]"/>
</complete>
<complete name="lutH" input="clb.I3 clb.I2 fle[3:2].out fle[5:4].out fle[9:9].out" output="fle[9:0].in[7:7]">
<delay_constant max="95e-12" in_port="clb.I3" out_port="fle.in[7:7]"/>
<delay_constant max="95e-12" in_port="clb.I2" out_port="fle.in[7:7]"/>
<delay_constant max="75e-12" in_port="fle[3:2].out" out_port="fle.in[7:7]"/>
<delay_constant max="75e-12" in_port="fle[5:4].out" out_port="fle.in[7:7]"/>
<delay_constant max="75e-12" in_port="fle[9:9].out" out_port="fle.in[7:7]"/>
</complete>
<complete name="clks" input="clb.clk" output="fle[9:0].clk">
</complete>
<!-- This way of specifying direct connection to clb outputs is important because this architecture uses automatic spreading of opins.
By grouping to output pins in this fashion, if a logic block is completely filled by 6-LUTs,
then the outputs those 6-LUTs take get evenly distributed across all four sides of the CLB instead of clumped on two sides (which is what happens with a more
naive specification).
-->
<direct name="clbouts1" input="fle[9:0].out[0:0]" output="clb.O[9:0]"/>
<direct name="clbouts2" input="fle[9:0].out[1:1]" output="clb.O[19:10]"/>
<!-- Carry chain links -->
<direct name="carry_in" input="clb.cin" output="fle[0:0].cin">
<!-- Put all inter-block carry chain delay on this one edge -->
<delay_constant max="0.16e-9" in_port="clb.cin" out_port="fle[0:0].cin"/>
<pack_pattern name="chain" in_port="clb.cin" out_port="fle[0:0].cin"/>
</direct>
<direct name="carry_out" input="fle[9:9].cout" output="clb.cout">
<pack_pattern name="chain" in_port="fle[9:9].cout" out_port="clb.cout"/>
</direct>
<direct name="carry_link" input="fle[8:0].cout" output="fle[9:1].cin">
<pack_pattern name="chain" in_port="fle[8:0].cout" out_port="fle[9:1].cin"/>
</direct>
</interconnect>
</pb_type>
<!-- Define general purpose logic block (CLB) ends -->
<!-- Define fracturable multiplier begin -->
<!-- This multiplier can operate as a 36x36 multiplier that can fracture to two 18x18 multipliers each of which can further fracture to two 9x9 multipliers
For delay modelling, the 36x36 DSP multiplier in Stratix IV has a delay of 1.523 ns + 1.93 ns
= 3.45 ns. The 18x18 mode doesn't need to sum four 18x18 multipliers, so it is a bit
faster: 1.523 ns for the multiplier, and 1.09 ns for the multiplier output block.
For the input and output interconnect delays, unlike Stratix IV, we don't
have any routing/logic flexibility (crossbars) at the inputs. There is some output muxing
in Stratix IV and this architecture to select which multiplier outputs should go out (e.g.
9x9 outputs, 18x18 or 36x36) so those are very close between the two architectures.
We take the conservative (slightly pessimistic)
approach modelling the input as the same as the Stratix IV input delay and the output delay the same as the Stratix IV DSP out delay.
We estimate block area by using the published Stratix III data (which is architecturally identical to Stratix IV)
(H. Wong, V. Betz and J. Rose, "Comparing FPGA vs. Custom CMOS and the Impact on Processor Microarchitecture", FPGA 2011) of 0.2623
mm^2 and scaling from 65 to 40 nm to obtain 0.0993 mm^2. That area is for a DSP block with approximately 2x the functionality of
the block we use (can implement two 36x36 multiplies instead of our 1, eight 18x18 multiplies instead of our 4, etc.). Hence we
divide the area by 2 to obtain 0.0497 mm^2. One minimum-width transistor units = 60 L^2 (where L = 40 nm), so is 518,000 MWTUS.
That area includes routing and the connection block input muxes. Our DSP block is four
rows high, and hence includes four horizontal routing channel segments and four vertical ones, which is 4x the routing of a logic
block (single tile). It also includes 3.6x the outputs of a logic block, and 1.8x the inputs. Hence a slight overestimate of the routing
area associated with our DSP block is four times that of a logic tile, where the routing area of a logic tile was calculated above (at W = 300)
as 30481 MWTAs. Hence the (core, non-routing) area our DSP block is approximately 518,000 - 4 * 30,481 = 396,000 MWTUs.
-->
<pb_type name="mult_36">
<input name="a" num_pins="36"/>
<input name="b" num_pins="36"/>
<output name="out" num_pins="72"/>
<mode name="two_divisible_mult_18x18">
<pb_type name="divisible_mult_18x18" num_pb="2">
<input name="a" num_pins="18"/>
<input name="b" num_pins="18"/>
<output name="out" num_pins="36"/>
<!-- Model 9x9 delay and 18x18 delay as the same. 9x9 could be faster, but in Stratix IV
isn't, presumably because the multiplier layout is really optimized for 18x18.
-->
<mode name="two_mult_9x9">
<pb_type name="mult_9x9_slice" num_pb="2">
<input name="A_cfg" num_pins="9"/>
<input name="B_cfg" num_pins="9"/>
<output name="OUT_cfg" num_pins="18"/>
<pb_type name="mult_9x9" blif_model=".subckt multiply" num_pb="1">
<input name="a" num_pins="9"/>
<input name="b" num_pins="9"/>
<output name="out" num_pins="18"/>
<delay_constant max="1.523e-9" in_port="mult_9x9.a" out_port="mult_9x9.out"/>
<delay_constant max="1.523e-9" in_port="mult_9x9.b" out_port="mult_9x9.out"/>
</pb_type>
<interconnect>
<direct name="a2a" input="mult_9x9_slice.A_cfg" output="mult_9x9.a">
</direct>
<direct name="b2b" input="mult_9x9_slice.B_cfg" output="mult_9x9.b">
</direct>
<direct name="out2out" input="mult_9x9.out" output="mult_9x9_slice.OUT_cfg">
</direct>
</interconnect>
<power method="pin-toggle">
<port name="A_cfg" energy_per_toggle="1.45e-12"/>
<port name="B_cfg" energy_per_toggle="1.45e-12"/>
<static_power power_per_instance="0.0"/>
</power>
</pb_type>
<interconnect>
<direct name="a2a" input="divisible_mult_18x18.a" output="mult_9x9_slice[1:0].A_cfg">
</direct>
<direct name="b2b" input="divisible_mult_18x18.b" output="mult_9x9_slice[1:0].B_cfg">
</direct>
<direct name="out2out" input="mult_9x9_slice[1:0].OUT_cfg" output="divisible_mult_18x18.out">
</direct>
</interconnect>
</mode>
<mode name="mult_18x18">
<pb_type name="mult_18x18_slice" num_pb="1">
<input name="A_cfg" num_pins="18"/>
<input name="B_cfg" num_pins="18"/>
<output name="OUT_cfg" num_pins="36"/>
<pb_type name="mult_18x18" blif_model=".subckt multiply" num_pb="1">
<input name="a" num_pins="18"/>
<input name="b" num_pins="18"/>
<output name="out" num_pins="36"/>
<delay_constant max="1.523e-9" in_port="mult_18x18.a" out_port="mult_18x18.out"/>
<delay_constant max="1.523e-9" in_port="mult_18x18.b" out_port="mult_18x18.out"/>
</pb_type>
<interconnect>
<direct name="a2a" input="mult_18x18_slice.A_cfg" output="mult_18x18.a">
</direct>
<direct name="b2b" input="mult_18x18_slice.B_cfg" output="mult_18x18.b">
</direct>
<direct name="out2out" input="mult_18x18.out" output="mult_18x18_slice.OUT_cfg">
</direct>
</interconnect>
<power method="pin-toggle">
<port name="A_cfg" energy_per_toggle="1.09e-12"/>
<port name="B_cfg" energy_per_toggle="1.09e-12"/>
<static_power power_per_instance="0.0"/>
</power>
</pb_type>
<interconnect>
<direct name="a2a" input="divisible_mult_18x18.a" output="mult_18x18_slice.A_cfg">
</direct>
<direct name="b2b" input="divisible_mult_18x18.b" output="mult_18x18_slice.B_cfg">
</direct>
<direct name="out2out" input="mult_18x18_slice.OUT_cfg" output="divisible_mult_18x18.out">
</direct>
</interconnect>
</mode>
<power method="sum-of-children"/>
</pb_type>
<interconnect>
<!-- Stratix IV input delay of 207ps is conservative for this architecture because this architecture does not have an input crossbar in the multiplier.
Subtract 72.5 ps delay, which is already in the connection block input mux, leading
-->
<direct name="a2a" input="mult_36.a" output="divisible_mult_18x18[1:0].a">
<delay_constant max="134e-12" in_port="mult_36.a" out_port="divisible_mult_18x18[1:0].a"/>
</direct>
<direct name="b2b" input="mult_36.b" output="divisible_mult_18x18[1:0].b">
<delay_constant max="134e-12" in_port="mult_36.b" out_port="divisible_mult_18x18[1:0].b"/>
</direct>
<direct name="out2out" input="divisible_mult_18x18[1:0].out" output="mult_36.out">
<delay_constant max="1.09e-9" in_port="divisible_mult_18x18[1:0].out" out_port="mult_36.out"/>
</direct>
</interconnect>
</mode>
<mode name="mult_36x36">
<pb_type name="mult_36x36_slice" num_pb="1">
<input name="A_cfg" num_pins="36"/>
<input name="B_cfg" num_pins="36"/>
<output name="OUT_cfg" num_pins="72"/>
<pb_type name="mult_36x36" blif_model=".subckt multiply" num_pb="1">
<input name="a" num_pins="36"/>
<input name="b" num_pins="36"/>
<output name="out" num_pins="72"/>
<delay_constant max="1.523e-9" in_port="mult_36x36.a" out_port="mult_36x36.out"/>
<delay_constant max="1.523e-9" in_port="mult_36x36.b" out_port="mult_36x36.out"/>
</pb_type>
<interconnect>
<direct name="a2a" input="mult_36x36_slice.A_cfg" output="mult_36x36.a">
</direct>
<direct name="b2b" input="mult_36x36_slice.B_cfg" output="mult_36x36.b">
</direct>
<direct name="out2out" input="mult_36x36.out" output="mult_36x36_slice.OUT_cfg">
</direct>
</interconnect>
<power method="pin-toggle">
<port name="A_cfg" energy_per_toggle="2.13e-12"/>
<port name="B_cfg" energy_per_toggle="2.13e-12"/>
<static_power power_per_instance="0.0"/>
</power>
</pb_type>
<interconnect>
<!-- Stratix IV input delay of 207ps is conservative for this architecture because this architecture does not have an input crossbar in the multiplier.
Subtract 72.5 ps delay, which is already in the connection block input mux, leading
to a 134 ps delay.
-->
<direct name="a2a" input="mult_36.a" output="mult_36x36_slice.A_cfg">
<delay_constant max="134e-12" in_port="mult_36.a" out_port="mult_36x36_slice.A_cfg"/>
</direct>
<direct name="b2b" input="mult_36.b" output="mult_36x36_slice.B_cfg">
<delay_constant max="134e-12" in_port="mult_36.b" out_port="mult_36x36_slice.B_cfg"/>
</direct>
<direct name="out2out" input="mult_36x36_slice.OUT_cfg" output="mult_36.out">
<delay_constant max="1.93e-9" in_port="mult_36x36_slice.OUT_cfg" out_port="mult_36.out"/>
</direct>
</interconnect>
</mode>
<!-- Place this multiplier block every 8 columns from (and including) the sixth column -->
<power method="sum-of-children"/>
</pb_type>
<!-- Define fracturable multiplier end -->
<!-- Define fracturable memory begin -->
<!-- 32 Kb Memory that can operate from 512x64 to 32Kx1 for single-port mode and 1024x32 to 32Kx1 for dual-port mode.
Area and delay based off Stratix IV 9K and 144K memories (delay from linear interpolation, Tsu(483 ps, 636 ps) Tco(1084ps, 1969ps)).
Input delay = 204ps (from Stratix IV LAB line) - 72ps (this architecture does not lump connection box delay in internal delay)
Output delay = M9K buffer 50ps
Area is obtained by appropriately scaling and adjusting the published Stratix III (which is architecturally identical to Stratix IV)
data from H. Wong, V. Betz and J. Rose, "Comparing FPGA vs. Custom CMOS and the Impact on Processor Microarchitecture", FPGA 2011.
Linearly interpolating (by bit count) between the M9k and M144k areas to obtain an M32k (our RAM size) point yields a 65 nm area of
of 0.153 mm^2. Interpolating based on port count between the RAMs would instead yield an area of 0.209 mm^2 for our 32 kB RAM; since
bit count accounts for more area than ports for a RAM this size we choose the bit count interpolation; however, since the port interpolation
is not radically different this also gives us confidence that interpolating based on bits is OK, but slightly underpredicts area.
Scaling to 40 nm^2 yields .0579 mm^2, and converting to MWTUs at 60 L^2 / MWTU yields 604,000 MWTUs. This includes routing. A Stratix IV
M9K RAM is one row high and hence has one routing tile (one horizonal and one vertical routing segment area). An M144k RAM has 8 such tiles.
Linearly interpolating on
bits to 32 kb yields 2.2 routing tiles incorporated in the area number above. The inter-block routing represents 30% of the area of a logic
tile according to D. Lewis et al, "Architectural Enhancements in Stratix V," FPGA 2013. Hence we should subtract 0.3 * 2.2 * 84,375 MWTUs to
obtain a RAM core area (not including inter-block routing) of 548,000 MWTU areas for our 32 kb RAM in a 40 nm process.
-->
<pb_type name="memory">
<input name="addr1" num_pins="15"/>
<input name="addr2" num_pins="15"/>
<input name="data" num_pins="64"/>
<input name="we1" num_pins="1"/>
<input name="we2" num_pins="1"/>
<output name="out" num_pins="64"/>
<clock name="clk" num_pins="1"/>
<!-- Specify single port mode first -->
<mode name="mem_512x64_sp">
<pb_type name="mem_512x64_sp" blif_model=".subckt single_port_ram" class="memory" num_pb="1">
<input name="addr" num_pins="9" port_class="address"/>
<input name="data" num_pins="64" port_class="data_in"/>
<input name="we" num_pins="1" port_class="write_en"/>
<output name="out" num_pins="64" port_class="data_out"/>
<clock name="clk" num_pins="1" port_class="clock"/>
<T_setup value="509e-12" port="mem_512x64_sp.addr" clock="clk"/>
<T_setup value="509e-12" port="mem_512x64_sp.data" clock="clk"/>
<T_setup value="509e-12" port="mem_512x64_sp.we" clock="clk"/>
<T_clock_to_Q max="1.234e-9" port="mem_512x64_sp.out" clock="clk"/>
<power method="pin-toggle">
<port name="clk" energy_per_toggle="9.0e-12"/>
<static_power power_per_instance="0.0"/>
</power>
</pb_type>
<interconnect>
<direct name="address1" input="memory.addr1[8:0]" output="mem_512x64_sp.addr">
<delay_constant max="132e-12" in_port="memory.addr1[8:0]" out_port="mem_512x64_sp.addr"/>
</direct>
<direct name="data1" input="memory.data[63:0]" output="mem_512x64_sp.data">
<delay_constant max="132e-12" in_port="memory.data[63:0]" out_port="mem_512x64_sp.data"/>
</direct>
<direct name="writeen1" input="memory.we1" output="mem_512x64_sp.we">
<delay_constant max="132e-12" in_port="memory.we1" out_port="mem_512x64_sp.we"/>
</direct>
<direct name="dataout1" input="mem_512x64_sp.out" output="memory.out[63:0]">
<delay_constant max="40e-12" in_port="mem_512x64_sp.out" out_port="memory.out[63:0]"/>
</direct>
<direct name="clk" input="memory.clk" output="mem_512x64_sp.clk">
</direct>
</interconnect>
</mode>
<mode name="mem_1024x32_sp">
<pb_type name="mem_1024x32_sp" blif_model=".subckt single_port_ram" class="memory" num_pb="1">
<input name="addr" num_pins="10" port_class="address"/>
<input name="data" num_pins="32" port_class="data_in"/>
<input name="we" num_pins="1" port_class="write_en"/>
<output name="out" num_pins="32" port_class="data_out"/>
<clock name="clk" num_pins="1" port_class="clock"/>
<T_setup value="509e-12" port="mem_1024x32_sp.addr" clock="clk"/>
<T_setup value="509e-12" port="mem_1024x32_sp.data" clock="clk"/>
<T_setup value="509e-12" port="mem_1024x32_sp.we" clock="clk"/>
<T_clock_to_Q max="1.234e-9" port="mem_1024x32_sp.out" clock="clk"/>
<power method="pin-toggle">
<port name="clk" energy_per_toggle="9.0e-12"/>
<static_power power_per_instance="0.0"/>
</power>
</pb_type>
<interconnect>
<direct name="address1" input="memory.addr1[9:0]" output="mem_1024x32_sp.addr">
<delay_constant max="132e-12" in_port="memory.addr1[9:0]" out_port="mem_1024x32_sp.addr"/>
</direct>
<direct name="data1" input="memory.data[31:0]" output="mem_1024x32_sp.data">
<delay_constant max="132e-12" in_port="memory.data[31:0]" out_port="mem_1024x32_sp.data"/>
</direct>
<direct name="writeen1" input="memory.we1" output="mem_1024x32_sp.we">
<delay_constant max="132e-12" in_port="memory.we1" out_port="mem_1024x32_sp.we"/>
</direct>
<direct name="dataout1" input="mem_1024x32_sp.out" output="memory.out[31:0]">
<delay_constant max="40e-12" in_port="mem_1024x32_sp.out" out_port="memory.out[31:0]"/>
</direct>
<direct name="clk" input="memory.clk" output="mem_1024x32_sp.clk">
</direct>
</interconnect>
</mode>
<mode name="mem_2048x16_sp">
<pb_type name="mem_2048x16_sp" blif_model=".subckt single_port_ram" class="memory" num_pb="1">
<input name="addr" num_pins="11" port_class="address"/>
<input name="data" num_pins="16" port_class="data_in"/>
<input name="we" num_pins="1" port_class="write_en"/>
<output name="out" num_pins="16" port_class="data_out"/>
<clock name="clk" num_pins="1" port_class="clock"/>
<T_setup value="509e-12" port="mem_2048x16_sp.addr" clock="clk"/>
<T_setup value="509e-12" port="mem_2048x16_sp.data" clock="clk"/>
<T_setup value="509e-12" port="mem_2048x16_sp.we" clock="clk"/>
<T_clock_to_Q max="1.234e-9" port="mem_2048x16_sp.out" clock="clk"/>
<power method="pin-toggle">
<port name="clk" energy_per_toggle="9.0e-12"/>
<static_power power_per_instance="0.0"/>
</power>
</pb_type>
<interconnect>
<direct name="address1" input="memory.addr1[10:0]" output="mem_2048x16_sp.addr">
<delay_constant max="132e-12" in_port="memory.addr1[10:0]" out_port="mem_2048x16_sp.addr"/>
</direct>
<direct name="data1" input="memory.data[15:0]" output="mem_2048x16_sp.data">
<delay_constant max="132e-12" in_port="memory.data[15:0]" out_port="mem_2048x16_sp.data"/>
</direct>
<direct name="writeen1" input="memory.we1" output="mem_2048x16_sp.we">
<delay_constant max="132e-12" in_port="memory.we1" out_port="mem_2048x16_sp.we"/>
</direct>
<direct name="dataout1" input="mem_2048x16_sp.out" output="memory.out[15:0]">
<delay_constant max="40e-12" in_port="mem_2048x16_sp.out" out_port="memory.out[15:0]"/>
</direct>
<direct name="clk" input="memory.clk" output="mem_2048x16_sp.clk">
</direct>
</interconnect>
</mode>
<mode name="mem_4096x8_sp">
<pb_type name="mem_4096x8_sp" blif_model=".subckt single_port_ram" class="memory" num_pb="1">
<input name="addr" num_pins="12" port_class="address"/>
<input name="data" num_pins="8" port_class="data_in"/>
<input name="we" num_pins="1" port_class="write_en"/>
<output name="out" num_pins="8" port_class="data_out"/>
<clock name="clk" num_pins="1" port_class="clock"/>
<T_setup value="509e-12" port="mem_4096x8_sp.addr" clock="clk"/>