firrtl icon indicating copy to clipboard operation
firrtl copied to clipboard

Support synthesis directives thru annotations (/* ... */)

Open carlosedp opened this issue 3 years ago • 3 comments

Checklist

  • [x] Did you write out a description of the feature you want to see?
  • [x] Did you look around for any related features?
  • [x] Did you specify relevant external information?

Feature Description

This feature request objective is to provide an annotation type to allow adding synthesis directives into the generated Verilog code for the synthesys tools.

The idea is that the annotation would allow generic, unfiltered text bound to a target. The targets could be reg, module, input, output, case, wire and maybe others.

Below some examples collected from synthesis manuals:

reg net_reg1 /* synthesis syn_preserve = 1 */ ;
reg net_reg2 /* verilator clock_enable */ ;
reg [3:0] curstate /* synthesis syn_state_machine=0 */ ;
reg [5:0] q, q_a, q_b, q_c, q_d /* synthesis syn_preserve=1 */;
reg [1:0] mem [7:0] /* synthesis syn_ramstyle="no_rw_check" */;
reg [1:0] mem [7:0] /* synthesis ram_init_file = "memoryFile.hex" */;

module fifo(out, in) /* synthesis syn_hier = "hard“ */;

// To attach multiple attributes or directives to the same object, separate the attributes with white spaces
case state /* synthesis full_case parallel_case */;

wire in1a /*synthesis syn_keep = 1*/;

input  wire [3:0] ina  /* synthesis ace_useioff=1 */;
output reg        z0   /* synthesis ace_useioff=1 */;

The content of this annotation is user's responsibility and in Firrtl we could add some validations like avoiding multiple synthesys words in case of multiple attributes.

Firrtl annotation would be exposed similarly as below in Chisel code:

  val mem = SyncReadMem(words, UInt(bitWidth.W))
  if (memoryFile.trim().nonEmpty) {
    loadMemoryFromFileInline(mem, memoryFile)
  }
  annotate(new ChiselAnnotation {
    override def toFirrtl = SynthesizerDirective(
      mem.toTarget,
      s"""synthesis ram_init_file = "$memoryFile""""
    )
  })

An easier interface could be added afterwards in Chisel.

Type of Feature

  • new feature/API

carlosedp avatar Mar 18 '21 20:03 carlosedp

I have already started a draft implementation of this feature but the main problem where I'm stuck is how to place these directives inline with the declaration before the object's ;.

I might need some help here.

carlosedp avatar Mar 18 '21 20:03 carlosedp

I think you can take a look at AttributeAnnotation implementation: Basically, you need to extend from DescriptionAnnotation. check the the all DescriptionAnnotation usages in VerilogEmitter: Here are some places you can take a look: https://github.com/chipsalliance/firrtl/blob/master/src/main/scala/firrtl/backends/verilog/VerilogEmitter.scala#L410 https://github.com/chipsalliance/firrtl/blob/master/src/main/scala/firrtl/backends/verilog/VerilogEmitter.scala#L526-L527 https://github.com/chipsalliance/firrtl/blob/94d1bee4c23bd3d8f99dae3ca431ffaa5dc1410d/src/main/scala/firrtl/backends/verilog/VerilogEmitter.scala#L960 You may need to add your implementation at: https://github.com/chipsalliance/firrtl/blob/94d1bee4c23bd3d8f99dae3ca431ffaa5dc1410d/src/main/scala/firrtl/backends/verilog/VerilogEmitter.scala#L643 : reg / wire https://github.com/chipsalliance/firrtl/blob/94d1bee4c23bd3d8f99dae3ca431ffaa5dc1410d/src/main/scala/firrtl/backends/verilog/VerilogEmitter.scala#L944-L957 : ports

sequencer avatar Mar 18 '21 20:03 sequencer

I plan on looking into this again, I wonder what's the best approach and syntax to use this, Verilog-1995 or Verilog-2001.

As an example here: https://www.intel.com/content/www/us/en/support/programmable/articles/000074381.html:

Verilog-1995: output reg my_reg /* synthesis syn_preserve = 1 */;

Verilog-2001 (* syn_preserve *) output reg my_reg;

Which is used by the Verilog emitter? While looking at [VerilogEmitterTests.scala], I saw that Verilog-2001 syntax is used in AttributeAnnotation. I wonder if it's the same thing.

carlosedp avatar Nov 23 '21 20:11 carlosedp