/
RAMStyleHint.scala
72 lines (61 loc) · 2.3 KB
/
RAMStyleHint.scala
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
// See LICENSE for license details.
package midas.targetutils.xdc
import chisel3.experimental.ChiselAnnotation
import firrtl.annotations.ReferenceTarget
sealed trait RAMStyle
/**
* Some rough guidance, based on Ultrascale+, is provided in the scala doc for
* each hint. Consult the Xilinx UGs for your target architecture and the
* synthesis UG (UG901).
*/
object RAMStyles {
/**
* From UG901 (v2020.2): Instructs the tool to use the UltraScale+ URAM primitives.
*
* URAMs are 288Kb, 72b wide, 4096 deep.
*/
case object ULTRA extends RAMStyle
/**
* From UG901 (v2020.2): Instructs the tool to infer RAMB type components
*
* In Ultrascale+ (and older families), BRAMs are 36Kb, and have flexible aspect
* ratio: 1b x 64K to 72b x 512
*/
case object BRAM extends RAMStyle
/** From UG901 (v2020.2): Instructs the tool to infer registers instead of RAMs. */
case object REGISTERS extends RAMStyle
/** From UG901 (v2020.2): Instructs the tool to infer the LUT RAMs. */
case object DISTRIBUTED extends RAMStyle
/** Introduced in v2020.2. From UG901 (v2020.2):
*
* Instructs the tool to infer a combination of RAM types designed to minimize the
* amount of space that is unused.
*
* Note: This should probably be avoided for non-emulation-class
* FPGAs (e.g., VU19P), which tend to have rich embedded memory resources, as
* these designs tend to be under heavy LUT pressure. Here sparsely using
* BRAM / URAM resources insead of a space-optimal hybrid is desirable.
*/
case object MIXED extends RAMStyle
}
object RAMStyleHint {
// _reg suffix is applied to memory cells by Vivado, the glob manages
// duplication for multibit memories.
private [midas] def propertyTemplate(style: RAMStyle): String =
s"set_property RAM_STYLE ${style} [get_cells {}_reg*]"
private def annotate(style: RAMStyle, rT: =>ReferenceTarget): Unit = {
chisel3.experimental.annotate(new ChiselAnnotation {
def toFirrtl = XDCAnnotation(
XDCFiles.Synthesis,
propertyTemplate(style),
rT)
})
}
/**
* Annotates a chisel3 Mem indicating it should be implemented with a particular
* Xilinx RAM structure.
*/
def apply(mem: chisel3.MemBase[_], style: RAMStyle): Unit = {
annotate(style, mem.toTarget)
}
}