Search code examples
hardwareverilogfpgaxilinxhdl

Verilog Placement Constraints with Generate Statements


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

Solution

  • 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