1 | # generate a BMM file, catch all information from BRAM properties
|
2 | proc generate_one_bmm_file { instance } {
|
3 |
|
4 | if {$instance == ""} {
|
5 | set bram_unsort_list [get_cells -hierarchical -filter { LOC =~ "RAMB*" }]
|
6 | } else {
|
7 | set bram_unsort_list [get_cells -hierarchical -filter "NAME =~ $instance/* && LOC =~ RAMB*"]
|
8 | }
|
9 | # generate list of used BRAM on this instance
|
10 | set bram_list [lsort -dictionary -decreasing $bram_unsort_list]
|
11 | set bram_instance_name [lindex [split [lindex $bram_list 0] "/"] 0]
|
12 | # count instances
|
13 | set bram_count [llength $bram_list]
|
14 | set bram_length [expr $bram_count * 1024]
|
15 | set bram_bytes [expr $bram_length * 4]
|
16 | # defaults
|
17 | set bram_width 0
|
18 | set bram_words $bram_bytes
|
19 | set bram_divisor 1
|
20 |
|
21 | # synthesis specific corrections
|
22 | if {$bram_count == 128} {
|
23 | set bram_divisor 4
|
24 | } elseif {$bram_count == 64} {
|
25 | set bram_divisor 2
|
26 | } elseif {$bram_count == 32} {
|
27 | } elseif {$bram_count == 16} {
|
28 | } elseif {$bram_count == 8} {
|
29 | } elseif {$bram_count == 4} {
|
30 | } elseif {$bram_count == 2} {
|
31 | set bram_words [expr $bram_bytes / 2]
|
32 | } elseif {$bram_count == 1} {
|
33 | set bram_words [expr $bram_bytes / 4]
|
34 | } elseif {$bram_count == 0} {
|
35 | puts "found no brams in instance $instance"
|
36 | return
|
37 | } else {
|
38 | puts "currently unsupported BRAM size ($instance: $bram_count)"
|
39 | return
|
40 | }
|
41 |
|
42 | # format nr. of bytes or words
|
43 | set hex_start [format %08X 0]
|
44 | set hex_end [format %08X [expr $bram_words - 1]]
|
45 |
|
46 | # count bit width over bram instances
|
47 | foreach bram $bram_list {
|
48 | set bram_width [expr $bram_width + [get_property READ_WIDTH_A [get_cells $bram]]]
|
49 | }
|
50 |
|
51 | # fix bit width
|
52 | set bram_width [expr $bram_width / $bram_divisor]
|
53 |
|
54 | # check width, select memory type
|
55 | if {$bram_width == 32} {
|
56 | set mtype "RAMB32"
|
57 | } elseif {$bram_width == 36} {
|
58 | set mtype "RAMB36 WORD_ADDRESSING"
|
59 | } else {
|
60 | puts "currently unsupported BRAM width ($instance: $bram_width)"
|
61 | return
|
62 | }
|
63 |
|
64 | set memory_layout "${bram_length}x${bram_width}"
|
65 | #puts "memory layout: $memory_layout"
|
66 |
|
67 | # filename
|
68 | if {$instance == ""} {
|
69 | set bmm_file_name "gen_${memory_layout}.bmm"
|
70 | } else {
|
71 | set bmm_file_name "gen_${instance}_${memory_layout}.bmm"
|
72 | }
|
73 | # open bmm file for writing
|
74 | set bmm_file [open $bmm_file_name w]
|
75 |
|
76 | if {$bram_divisor > 1} {
|
77 | # build COMBINED rams
|
78 | puts $bmm_file "ADDRESS_SPACE $bram_instance_name COMBINED [0x$hex_start:0x$hex_end]"
|
79 | for {set range_index 0} {$range_index < $bram_divisor} {incr range_index} {
|
80 | puts $bmm_file " ADDRESS_RANGE $mtype"
|
81 | puts $bmm_file " BUS_BLOCK"
|
82 | foreach bram $bram_list {
|
83 | # cut instance (e.g. ram_instance/ram_reg_1_2)
|
84 | set leaf [lindex [split $bram "/"] 1]
|
85 | # get elements (e.g. ram_reg_1_2)
|
86 | set elements [split $leaf "_"]
|
87 | # get second-to-last element (e.g. 1)
|
88 | set range [lindex $elements end-1]
|
89 | if {$range == $range_index} {
|
90 | set lane_begin [get_property bram_slice_begin [get_cells $bram]]
|
91 | set lane_end [get_property bram_slice_end [get_cells $bram]]
|
92 | set loc [get_property LOC [get_cells $bram]]
|
93 | # cut BEL from LOC
|
94 | set loc [lindex [split $loc "_"] end]
|
95 | puts $bmm_file " $bram [$lane_end:$lane_begin] LOC=$loc;"
|
96 | }
|
97 | }
|
98 | puts $bmm_file " END_BUS_BLOCK;"
|
99 | puts $bmm_file " END_ADDRESS_RANGE;"
|
100 | }
|
101 | puts $bmm_file "END_ADDRESS_SPACE;"
|
102 | } else {
|
103 | # build all other rams
|
104 | puts $bmm_file "ADDRESS_SPACE $bram_instance_name $mtype [0x$hex_start:0x$hex_end]"
|
105 | puts $bmm_file " BUS_BLOCK"
|
106 | foreach bram $bram_list {
|
107 | set lane_begin [get_property bram_slice_begin [get_cells $bram]]
|
108 | set lane_end [get_property bram_slice_end [get_cells $bram]]
|
109 | set loc [get_property LOC [get_cells $bram]]
|
110 | # cut BEL from LOC
|
111 | set loc [lindex [split $loc "_"] end]
|
112 | puts $bmm_file " $bram [$lane_end:$lane_begin] LOC=$loc;"
|
113 | }
|
114 | puts $bmm_file " END_BUS_BLOCK;"
|
115 | puts $bmm_file "END_ADDRESS_SPACE;"
|
116 | }
|
117 | close $bmm_file
|
118 | puts "bmm file generated ($bmm_file_name)"
|
119 | }
|