Перейти к содержанию
    

Spartan 6 использование сигналов с DCM с комбинаторной логикой

Есть входной сигнал clk_pll_in 50МГц, который поступает на вход DCM_SP. С него снимаются сигналы clk_in 50 Мгц с фазой 0, clk_ram 50 МГц с фазой 90, clk_main 25 МГц с фазой 0. На выходе каждого тактового сигнала стоит буфер BUFG, так как без него развести сигналы невозможно.

Дальше логика работы организована таким образом. Есть набор логических условий, которые становятся истинными в зависимости от состояния системы. Некоторые тактовые сигналы объединены по И с некоторыми условиями и выведены на пины. Некоторые используются в Always-блоках.  Постоянно появляется ошибка 1136 (This design contains a global buffer instance, <main1/pll_main/clkout2_buf>, driving the net, <main1/clk_main>, that is  driving the following (first 30) non-clock load pins.). Но возникает она в двух разных местах:

1) Ошибка на сигналах, которые выводятся на пины. К примеру:

reg S_flag;
reg [2:0] state;

wire S=clk_main & S_flag;
wire L=clk_main & (state==03);

Где S и L - сигналы уровня top level. То есть необходима именно схема DCM->BUFG->Логика->PIN. По сути это Gated clock, что нехорошо. Заменила BUFG на BUFGCE и подключила на вход условия, работает, но на Gated clock'е  только одно И, поэтому мучает вопрос, что быстрее: комбинаторная логика или переключение буфера.

2) Ошибки на сигналах в Always-блоке. Например:

reg ram_enable;

wire generate_new_address=clk_in & ram_enable;

always @(posedge clk)
	//изменяется ram_enable

always @(posedge generate_new_address)
	//что то присваивается

always @(negedge generate_new_address)
	//что то присваивается

Тут ругается так: This design contains a global buffer instance, <main1/pll_main/clkout2_buf>, driving the net, <main1/clk_in>, that is  driving the following (first 30) non-clock load pins. < PIN: main1/main_ram/generate_new_addr_169.A4; >.  

Если в первом случае проблема решаема сменой типа буфера, то во втором случае вобще нет идей. Там даже сигнал generate_new_address не выводится наружу, только внутренний.

Подскажите пожалуйста, как можно решить эту проблему, буду очень благодарна.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Так а задача какая? Потому что варнинги сами по себе не несут вреда. Если всё работает как нужно то проблемы нет. 
Если всё же есть проблема то хотелось бы про неё услышать.

Т.е. в приведённом коде нету криминала на мой взгляд. При правильной генерации сигнала выполняющего роль СЕ будет работать.

Ещё можно завести клок на DDR триггер выходной на который поданы 0 и 1 на входы. Он будет на выходе повторять клок. Вот на него можно подать СЕ и будет вообще всё по феншую.

 

 

 

Вот это уже можно считать криминалом

Цитата

always @(posedge generate_new_address)

Если это что-то внутреннее то клок заводиться везде один. А СЕ заводится на каждый кусок который должен или работать или не работать.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

4 hours ago, MegaVolt said:

Так а задача какая? Потому что варнинги сами по себе не несут вреда. Если всё работает как нужно то проблемы нет

Там система чтения RAM. В основном цикле clk_main основной автомат, в котором определяется, когда надо читать, посредством установки ram_enable. Сама ram тактируется сдвинутым по фазе сигналом clk_ram. Генерация адреса и запись результата происходят по обоим фронтам generate_new_address, который зависит от clk_in (частота такая же, как clk_ram, но другая фаза).

Вот в том и беда, что это эрроры, а не варнинги, даже до конца процесс не доходит, на place&route доходит до ошибок и все :(

4 hours ago, MegaVolt said:

При правильной генерации сигнала выполняющего роль СЕ будет работать.

Можете поподробнее описать что это должен быть за сигнал и как его использовать?

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

10 часов назад, Eluv сказал:

Там система чтения RAM. В основном цикле clk_main основной автомат, в котором определяется, когда надо читать, посредством установки ram_enable. Сама ram тактируется сдвинутым по фазе сигналом clk_ram. Генерация адреса и запись результата происходят по обоим фронтам generate_new_address, который зависит от clk_in (частота такая же, как clk_ram, но другая фаза).

Вот в том и беда, что это эрроры, а не варнинги, даже до конца процесс не доходит, на place&route доходит до ошибок и все :(

Можете поподробнее описать что это должен быть за сигнал и как его использовать?

 

Если совсем кратко то все внешние сигналы в идеале должны формироваться на выходных триггерах используя единую для всех частоту. 

Если же есть задача строить GATED Clock то бумага выше в помощь. Задача организовать управляющий сигнал  так чтобы он ГАРАНТИРОВАННО изменялся только во время того когда управляемый клок в нуле. Например как указано в бумаге выше для это применяется не триггер а защёлка. SPARTAN если не ошибаюсь это может. 

Ссылка на документ тут : http://mitpublications.org/yellow_images/1315565167_logo_13.pdf

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

16 часов назад, Eluv сказал:

 

2) Ошибки на сигналах в Always-блоке. Например:


reg ram_enable;

wire generate_new_address=clk_in & ram_enable;

always @(posedge clk)
	//изменяется ram_enable

always @(posedge generate_new_address)
	//что то присваивается

always @(negedge generate_new_address)
	//что то присваивается

Подскажите пожалуйста, как можно решить эту проблему, буду очень благодарна.

У Вас довольно низкая частота - всего 50Мгц, а потому нет смысла устраивать "negedge generate_new_address" и "posedge generate_new_address"... 

Если не хочется все сделать на 50 Мгц, то уж на 100Мгц всяко можно разложить все по тактам. И весь проект сделать синхронным.

А плодить какие-то "события" для always это значит, что компилятору требуется задействовать для цепей синхронизации часть клокового дерева. Вот ему это очень не нравится..

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

12 minutes ago, MegaVolt said:

Если совсем кратко то все внешние сигналы в идеале должны формироваться на выходных триггерах используя единую для всех частоту. 

Если же есть задача строить GATED Clock то бумага выше в помощь. Задача организовать управляющий сигнал  так чтобы он ГАРАНТИРОВАННО изменялся только во время того когда управляемый клок в нуле. Например как указано в бумаге выше для это применяется не триггер а защёлка. SPARTAN если не ошибаюсь это может. 

Ссылка на документ тут : http://mitpublications.org/yellow_images/1315565167_logo_13.pdf

Что то я вобще растерялась) Что за управляющий сигнал вы имеете ввиду?

То есть хоть как примерно можно generate_new_address в чувства привести?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

16 часов назад, Eluv сказал:

С него снимаются сигналы clk_in 50 Мгц с фазой 0, clk_ram 50 МГц с фазой 90, clk_main 25 МГц с фазой 0

 

Во-первых, инверсный — это 180°, любые другие углы делаются аналоговыми способами, а во-вторых, исходного сигнала достаточно без дополнительных и запрещённых манипуляций.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

А я и не говорила, что мне надо 180) Я пользовалась Clock Wizard'ом, потом уже в RTL схеме посмотрела, что он мне DCM_SP поставил. Мне нужно именно 90.

4 minutes ago, Plain said:

Во-первых, инверсный — это 180°

 

Изменено пользователем Eluv

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

12 minutes ago, Eluv said:

управляющий сигнал

Очевидно, сигнал (сигналы) разрешающие/запрещающие прохождение тактовой(ых) частот(ы).

Задача - сделать так, чтобы при разрешении/запрещении клоков не появлялись лишние импульсы.

Если уж только таким способом хотите.

Другой вариант - Вам посоветовали - поднять кратно частоту, добавить состояний автомата, все делать по posedge этой частоты. Не нужно будет запрещать/разрешать clk.

Еще как вариант - если есть готовые библиотечные коммутаторы тактовой частоты с входом clk_enable - применить их.

Изменено пользователем Yuri124

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Приветствую!

11 minutes ago, Eluv said:

Что то я вобще растерялась) Что за управляющий сигнал вы имеете ввиду?

То есть хоть как примерно можно generate_new_address в чувства привести?

Было бы проще если бы вы привели требуемую диаграмму сигналов (с временами) для управления памятью. Тогда станет проще понять как это можно сделать с минимальными затратами.

Успехов!  Rob.

 

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

13 минут назад, Eluv сказал:

Что то я вобще растерялась) Что за управляющий сигнал вы имеете ввиду?

То есть хоть как примерно можно generate_new_address в чувства привести?

Т.е. всё за вас сделать самому? Ладно.

 

//      ODDR2     : In order to incorporate this function into the design,
//     Verilog   : the forllowing instance declaration needs to be placed
//    instance   : in the body of the design code.  The instance name
//   declaration : (ODDR2_inst) and/or the port declarations within the
//      code     : parenthesis may be changed to properly reference and
//               : connect this function to the design.  Delete or comment
//               : out inputs/outs that are not necessary.

//  <-----Cut code below this line---->

   // ODDR2: Output Double Data Rate Output Register with Set, Reset
   //        and Clock Enable.
   //        Spartan-6
   // Xilinx HDL Language Template, version 14.7

   ODDR2 #(
      .DDR_ALIGNMENT("NONE"), // Sets output alignment to "NONE", "C0" or "C1" 
      .INIT(1'b0),    // Sets initial state of the Q output to 1'b0 or 1'b1
      .SRTYPE("SYNC") // Specifies "SYNC" or "ASYNC" set/reset
   ) ODDR2_inst (
      .Q(generate_new_address),   // 1-bit DDR output data
      .C0(clk_in),   // 1-bit clock input
      .C1(~clk_in),   // 1-bit clock input
      .CE(ram_enable), // 1-bit clock enable input
      .D0(1'b0), // 1-bit data input (associated with C0)
      .D1(1'b1), // 1-bit data input (associated with C1)
      .R(R),   // 1-bit reset input
      .S(S)    // 1-bit set input
   );

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Это было если 

generate_new_address

нужно вывести наружу. Если наружу не нужно то следующий код:

always @(posedge generate_new_address)
	//что то присваивается

always @(negedge generate_new_address)
	//что то присваивается

заменяется на:

   always @(posedge clk_in)
      if ram_enable begin
         <reg> <= <signal>;
      end

 

 

Если выход должен изменяться по обоим фронтам клока то использовать ODDR2 приведённый выше.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

14 minutes ago, MegaVolt said:

Т.е. всё за вас сделать самому? Ладно.

Нет. Просто без примера было непонятно.

8 minutes ago, MegaVolt said:

заменяется на:


   always @(posedge clk_in)
      if ram_enable begin
         <reg> <= <signal>;
      end

 

Этих четырех строк оказалось вполне достаточно, чтобы понять как все переделать. Теперь все уяснила. Спасибо!

 

Изменено пользователем Eluv

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

1 час назад, Eluv сказал:

он мне DCM_SP поставил. Мне нужно именно 90

Т.е. поднял частоту до 200 МГц — ну так проще было то же самое сделать в явном виде.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...