Verilog Placement Constraints with Generate Statements

梦想的初衷 提交于 2019-12-24 13:22:50

问题


I'm trying to generate an array of latches that are placed adjacent to each other using a Generate statement. I've been trying to use the Xilinx constraint "RLOC" to do this, but I haven't been successful.

The code below won't successfully implement, but should illustrate what I'm trying to obtain. The issue with the code below is that "i" in the constraint call isn't being converted into a string, which is what the call is looking for. Does anyone have experience doing this?

I'm using a Virtex4 with Xilinx ISE 10.1.03 for synthesis and implementation. I'm not entirely sure what version of Verilog I'm using, but I think it's Verilog 2001. I'd be grateful if someone could also tell me how to check what version of Verilog I'm using.

  genvar i;
  generate
    for (i = 0; i < DATA_WIDTH; i = i + 1)
    begin : LATCH
      (* RLOC = {"X0Y", i} *)
      latch inst_latch (
        .d        (data_in[i]),
        .gate     (gate), 
        .reset    (reset),
        .q        (data_out[i])
      ); 
    end
  endgenerate

回答1:


I'm guessing that Xilinx is treating {"X0Y", i} as a literal and not evaluating it. You can use a script to handle the generation for you. You can have the code generated by your preferred programming then use an `include statement in your verilog file. Or you can go with an embedded route:

  • Perl had EP3 : http://metacpan.org/pod/Text::EP3::Verilog
  • Ruby has eRuby : http://www.tutorialspoint.com/ruby/eruby.htm
  • Python has prepro : http://corner-case.com/indproj/prepro.html
  • I'm sure something like it exists for other languages to. Such as Tcl, JavaScript, C, etc.

Concept is the same, just a difference in embedded language and tool used for conversion.

A down side is the scripts will not treat DATA_WIDTH as a variable/parameter. You'll have to pass the script a numerical constant or find some fancy way to transfer the values.




回答2:


I ended up using parameterized macros to replace the generate variable with a string when passed to RLOC. It's quite a workaround, and I most likely would have used Greg's solution had I seen it earlier.

Anyway, in case people are actually interested, the macros :

parameter DIGITS = "9876543210";

`define THOUSANDS(x) (x / 1000)
`define  HUNDREDS(x) ((x - (`THOUSANDS(x) * 1000)) / 100)
`define      TENS(x) ((x - (`THOUSANDS(x) * 1000) - (`HUNDREDS(x) * 100)) / 10)
`define      ONES(x) (x - (`THOUSANDS(x) * 1000) - (`HUNDREDS(x) * 100) - (`TENS(x) * 10))

`define     TO_STRING(x) (DIGITS[((8 * (x + 1)) - 1) : (8 * x)])
`define VAR_TO_STRING(x) ({`TO_STRING(`THOUSANDS(x)), `TO_STRING(`HUNDREDS(x)), `TO_STRING(`TENS(x)), `TO_STRING(`ONES(x))})

The macros THOUSANDS(), HUNDREDS(), TENS(), and ONES() return the number of thousands, hundreds, tens, and ones found in x. These macros should always return 1 digit values.

TO_STRING() takes some 1 digit value and "converts" it to a string by returning a portion of parameter DIGITS.

VAR_TO_STRING() uses all of the above macros in conjunction to convert any 4 digit integer into its string equivalent. The code in the question would then be replaced by :

genvar i;
generate
  for (i = 0; i < DATA_WIDTH; i = i + 1)
  begin : LATCH
    (* RLOC = {"X0Y", `VAR_TO_STRING(i)} *)
    latch inst_latch (
      .d        (data_in[i]),
      .gate     (gate), 
      .reset    (reset),
      .q        (data_out[i])
    ); 
  end
endgenerate


来源:https://stackoverflow.com/questions/20481745/verilog-placement-constraints-with-generate-statements

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!