Question

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
Was it helpful?

Solution 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

OTHER TIPS

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:

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.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top