Ограничения размещения Verilog с операторами генерации

Я пытаюсь сгенерировать массив защелок, которые размещаются рядом друг с другом с помощью оператора Generate. Я пытался использовать для этого ограничение Xilinx «RLOC», но мне это не удалось.

Приведенный ниже код не будет успешно реализован, но он должен иллюстрировать то, что я пытаюсь получить. Проблема с приведенным ниже кодом заключается в том, что «i» в вызове ограничения не преобразуется в строку, что и ищет вызов. У кого-нибудь есть опыт этого?

Я использую Virtex4 с Xilinx ISE 10.1.03 для синтеза и реализации. Я не совсем уверен, какую версию Verilog я использую, но я думаю, что это Verilog 2001. Я был бы признателен, если бы кто-нибудь также сказал мне, как проверить, какую версию Verilog я использую.

  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

person jwp36    schedule 09.12.2013    source источник
comment
Я не думаю, что вы сможете добиться этого с помощью обычного Verilog. Я бы посоветовал написать что-нибудь на perl или на другом языке, чтобы создать файл verilog. Если у меня будет время, я попробую это сам и на самом деле отвечу на вопрос, придумаю ли я успешный код, который сделает то, что вы хотите.   -  person nguthrie    schedule 10.12.2013


Ответы (2)


Я предполагаю, что Xilinx рассматривает {"X0Y", i} как буквальное значение и не оценивает его. Вы можете использовать сценарий для обработки генерации за вас. Вы можете получить код, сгенерированный вашим предпочтительным программированием, а затем использовать оператор include в вашем файле verilog. Или вы можете пойти со встроенным маршрутом:

Концепция та же, только разница во встроенном языке и инструменте, используемом для преобразования.

Обратной стороной является то, что скрипты не будут рассматривать DATA_WIDTH как переменную / параметр. Вам нужно будет передать скрипту числовую константу или найти какой-нибудь необычный способ передачи значений.

person Greg    schedule 11.12.2013

Я закончил тем, что использовал параметризованные макросы для замены генерируемой переменной строкой при передаче в RLOC. Это вполне обходной путь, и я, скорее всего, использовал бы решение Грега, если бы увидел его раньше.

В любом случае, если людям действительно интересно, макросы:

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))})

Макросы THOUSANDS (), HUNDREDS (), TENS () и ONES () возвращают количество тысяч, сотен, десятков и единиц, найденных в x. Эти макросы всегда должны возвращать однозначные значения.

TO_STRING () принимает однозначное значение и «преобразует» его в строку, возвращая часть параметра DIGITS.

VAR_TO_STRING () использует все вышеперечисленные макросы вместе для преобразования любого 4-значного целого числа в его строковый эквивалент. Затем код в вопросе будет заменен на:

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
person jwp36    schedule 11.12.2013