|
|
  |
Проблемы с генератором ПСП |
|
|
|
Aug 10 2013, 11:06
|
Участник

Группа: Участник
Сообщений: 60
Регистрация: 26-11-10
Пользователь №: 61 201

|
Делаю имитатор сигнала глонасс на плисе от xilinx. Естественно в проекте нужен генератор ПСП. И вот столкнулся с проблемой, что если в проект пихнуть, например, десять таких генераторов, то из десяти два-три работать не будут. ПСП на выходе будет неправильная. В результате чтения отчета Place & Route выяснил, что не работают те генераторы, у которых больший перекос по тактовой цепи чем у остальных. Например, если перекос всего 2 ns, то генератор может не работать. После задания ограничения MAXSKEW = "0.9 ns" вроде бы все заработало. Но меня не покидает ощущение, что это неправильный костыль. Может подскажете в чем дело и как правильно делать? Есть подозрения, что надо как-то описать тактовую цепь генератора ПСП, но как непонятно. Её частота поидее всего ~511 кГц, фронт естественно гуляет шагами кратными 10 ns, т.к. сделана она из старшего разряда аккумулятора обычного на 32 разряда работающего на 100 МHz. Генераторов ПСП перепробовал кучу, результат примерно одинаков, всегда найдутся косячные. Генератор тактовой частоты ПСП работает на 100 МГц. На неё установлен констрэйн в UCF файле PERIOD = "8.75 ns". Цепь заведена на BUFG. Больше никаких настроек не делал. Далее код из проекта. Генератор ПСП: Код module prs_sa_gl( clk, rst, prs_out, prs_sync ); (* maxskew = "0.9 ns" *) input clk; input rst; output prs_out; output prs_sync; parameter sr_init = 9'b111111111; reg [8:0] sr = sr_init; reg prs_sync = 0; assign prs_out = sr[6]; wire rst_net; strobe s( .clk(clk ), .i (rst ), .o (rst_net) ); always @(posedge clk) begin sr <= rst_net ? sr_init : {sr[7:0], (sr[4] ^ sr[8])}; prs_sync <= (sr == sr_init); end endmodule Генератор тактовой частоты для ПСП: Код module prs_cnt( clk, value, wr, clk_out, phase, rst ); input clk; input [31:0] value; input wr; output clk_out; output [31:0] phase; input rst; reg [31:0] index = 0; reg [31:0] incr = 32'h00000000; reg [31:0] incr0 = 32'h00000000; wire wr_net; assign phase = index; assign clk_out = index[31]; always @(posedge clk or posedge rst) begin if (rst) begin index <= 0; end else begin index <= index + incr; end end strobe s( .clk(clk ), .i (wr ), .o (wr_net) ); always @(posedge clk) begin incr0 <= wr_net ? value : incr0; incr <= incr0; end
endmodule Синхронизатор импульсов сброса/записи: Код module strobe( clk, i, o ); input clk; input i; output o; reg clr = 0; reg o = 0; always @(posedge i or posedge o) begin clr <= o ? 0 : 1; end always @(negedge clk) begin o <= clr; end endmodule
|
|
|
|
|
Aug 10 2013, 12:21
|

я только учусь...
     
Группа: Модераторы
Сообщений: 3 447
Регистрация: 29-01-07
Из: Украина
Пользователь №: 24 839

|
Цитата(elzaro @ Aug 10 2013, 14:06)  Есть подозрения, что надо как-то описать тактовую цепь генератора ПСП, но как непонятно. Её частота поидее всего ~511 кГц, фронт естественно гуляет шагами кратными 10 ns, т.к. сделана она из старшего разряда аккумулятора обычного на 32 разряда работающего на 100 МHz. а использовать DCM для деления тактовой частоты не пробовали? Просто в Вашем случае частота после счетчика локальная, а не глобальная, т.е. распространяется в ПЛИС по локальным цепям, а не по глобальным цепям, отсюда и проблемы...
--------------------
If it doesn't work in simulation, it won't work on the board.
"Ты живешь в своих поступках, а не в теле. Ты — это твои действия, и нет другого тебя" Антуан де Сент-Экзюпери повесть "Маленький принц"
|
|
|
|
|
Aug 10 2013, 13:49
|
Участник

Группа: Участник
Сообщений: 60
Регистрация: 26-11-10
Пользователь №: 61 201

|
DCM не устраивает, т.к. код частоты надо постоянно переписывать, частота должна меняться, да и на кристалле их явно не десять штук. Может есть смысл пустить выход через BUFG или BUFR?
|
|
|
|
|
Aug 10 2013, 14:49
|
Знающий
   
Группа: Свой
Сообщений: 802
Регистрация: 11-05-07
Из: Томск
Пользователь №: 27 650

|
Цитата(elzaro @ Aug 10 2013, 20:49)  DCM не устраивает, т.к. код частоты надо постоянно переписывать, частота должна меняться, да и на кристалле их явно не десять штук. Может есть смысл пустить выход через BUFG или BUFR? Перестраиваемый NCO (numeric clock oscillator) вам в впомощь. Пара замечаний по коду : always @(posedge i or posedge o) begin clr <= o ? 0 : 1; end Что это за бред??? Во что превращается такая конструкция после синтеза? always @(negedge clk) begin o <= clr; end Зачем здесь negedge? Вас разве не учили, что negedge - абсолютное и безусловное зло? Кругом асинхронные сбросы, вы в курсе что их тоже надо применять с осторожностью? Вот это : assign clk_out = index[31]; есть источник gated clock, от него у вас все проблемы. Резюме : этот код ужасен! Вы бы хоть книжки почитали, примеры посмотрели что-ли...
|
|
|
|
|
Aug 10 2013, 15:23
|
Участник

Группа: Участник
Сообщений: 60
Регистрация: 26-11-10
Пользователь №: 61 201

|
Bad0512 на счет negedge согласен, там вообще posedge было, после экспериментов обратно не вернул. А конструкция этого синхронизатора сброса вообще и сделана для обеспечения синхронного сброса в других модулях. Подсмотрел её хз у кого. Делает из любого импульса непонятной ширины импульс с шириной периода одного такта. Там в результате два триггера получается после синтеза. Если есть более годные конструкции, был бы весьма признателен узнать. Цитата Вот это : assign clk_out = index[31]; есть источник gated clock, от него у вас все проблемы. Как это исправить? Kuzmi4 Цитата Думаю что "clock_enable" должен спасти отца русской демократии cool.gif в этой ситуации Что сделать то надо, добавить в модуль сигнал CE?
|
|
|
|
|
Aug 11 2013, 00:34
|

я только учусь...
     
Группа: Модераторы
Сообщений: 3 447
Регистрация: 29-01-07
Из: Украина
Пользователь №: 24 839

|
Цитата(Kuzmi4 @ Aug 10 2013, 16:48)  2 Maverick тут DCM избыточен.. полностью согласен если б ТС сразу и четко написал, что Цитата(elzaro @ Aug 10 2013, 16:49)  ...код частоты надо постоянно переписывать, частота должна меняться... по поводу Цитата(elzaro @ Aug 10 2013, 18:23)  Что сделать то надо, добавить в модуль сигнал CE? примеры на основе D Flip flop Код always @(posedge <clock> or posedge <reset>) if (<reset>) begin <reg> <= 1'b0; end else if (<clock_enable>) begin <reg> <= <signal>; end и Код always @(posedge <clock>) if (<reset>) begin <reg> <= 1'b0; end else if (<clock_enable>) begin <reg> <= <signal>; end в чем отличия описаний думаю догадаетесь сами  P.S. <...> - уберете и вставите свои имена сигналов
--------------------
If it doesn't work in simulation, it won't work on the board.
"Ты живешь в своих поступках, а не в теле. Ты — это твои действия, и нет другого тебя" Антуан де Сент-Экзюпери повесть "Маленький принц"
|
|
|
|
|
Aug 11 2013, 05:45
|
Участник

Группа: Участник
Сообщений: 60
Регистрация: 26-11-10
Пользователь №: 61 201

|
А почему D-триггер с clock_enable будет лучше и как меня это спасет? Тем более что, я этот сигнал вообще не использую.
|
|
|
|
|
Aug 11 2013, 09:20
|

Гуру
     
Группа: Свой
Сообщений: 3 304
Регистрация: 13-02-07
Из: 55°55′5″ 37°52′16″
Пользователь №: 25 329

|
Цитата(elzaro @ Aug 11 2013, 07:45)  А почему D-триггер с clock_enable будет лучше и как меня это спасет? Тем более что, я этот сигнал вообще не использую. Ну как бы вам так объяснить ....  Понимаете, если бы у вас была альтера или последнее семейство хилых, которые поддерживают SDC-констрейны, тогда можно было бы сделать из prs_cnt.clk_out generated_clock, задать его параметры и (если STA тулза конечно поддерживает эту возможность) получить рабочий дизайн - STA тулза сама всё будет контролировать исходя из заданных параметров. Но, на сколько я знаю, UCF не позволяет так сделать. И в итоге у вас асинхронный дизайн, и вы пытаетесь уменьших "асинхронность" через (* maxskew = "0.9 ns" *) - вот потому наверно и "не покидает ощущение, что это неправильный костыль". Потому вам предлогается использовать полностью синхронный дизайн и как следствие clock_enable. Логики у вас не так у много для 100МГц, так что думаю всё должно получиться
|
|
|
|
|
Aug 11 2013, 12:38
|
Участник

Группа: Участник
Сообщений: 60
Регистрация: 26-11-10
Пользователь №: 61 201

|
Т.е. если добавить в сумматор или сдвиговый регистр сигнал "ce", то он заработает синхронно и поэтому более лучше. Немного не совсем все понятно почему оно так, видимо как-то связано с тем, что цепь "ce" общая на все триггеры. На http://forums.xilinx.com подобные вопросы почитал, но там ответы тоже как-то все расплывачато даны. А саму тактовую цепь все же надо описывать в UCF как TNM_NET на 511 кГц?
|
|
|
|
|
Aug 11 2013, 18:08
|
Участник

Группа: Участник
Сообщений: 60
Регистрация: 26-11-10
Пользователь №: 61 201

|
или надо просто подать на clk 100МГц, на ce подать 511 кГц шириной в такт сотни и тогда весь проект будет шпилить на сотне и это и будет синхронно и круто?
|
|
|
|
|
Aug 18 2013, 16:24
|
Участник

Группа: Участник
Сообщений: 60
Регистрация: 26-11-10
Пользователь №: 61 201

|
дая уже понял, надеюсь, спасибо. сделал второй вариант.
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|