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

Схожу с ума от синтеза ...

Имею поток последовательных данных Data_in_A и Data_in_B.

По фронтам которых (фронт Data_in_A или фронт Data_in_B) нужно задвигать данные в сдвиговый регистр. Листинг формирования стробов (Rising_data_B и Rising_data_А) привожу ниже. Arinc_rise_time это десятикратная чатота Data_in_Х, асинхронна относительно Data_in_Х но синхронна с "clc".

Синтез Synplify7.5.

В общем, получается слишком большая ошибка потери данных, "теряются" стробы Rising_data_Х :(

Что обидно, синтезирую c XST, все нормально работает. :wacko:

Предложения типа "ищите в другом месте кода", логичны, но я все перепроверил и не раз, подозрение только на этот участок.

RTL у Synplify посмотреть не могу, т.к. работаю чрез X-ы на удаленной машине и Synplify, не знаю за что он там зацепился, запускается только в пакетном режиме.

 

always @(posedge clc)
if(rst)
  tRising_A[2:0]<=3'b000;
else
  if(Arinc_rise_time==`H)
    tRising_A[2:0]<={tRising_A[1:0],Data_in_A};
  else
    tRising_A <= tRising_A;
always @(posedge clc)
if(rst)
  tRising_B[2:0]<=3'b000;
else
  if(Arinc_rise_time==`H)
     tRising_B[2:0]<={tRising_B[1:0],Data_in_B};
  else
    tRising_B <= tRising_B;
always @(posedge clc)
if(rst)
  Rising_data_A<=`L;
else
  if((Arinc_rise_time==`H)&&(tRising_A[2:0]==3'b011))
        Rising_data_A<=`H;
  else
    Rising_data_A<=`L;
always @(posedge clc)
if(rst)
  Rising_data_B<=`L;
else
  if((Arinc_rise_time==`H)&&(tRising_B[2:0]==3'b011))
    Rising_data_B<=`H;
  else
    Rising_data_B<=`L;

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


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

Если речь идет об arinc-429, мне кажется Вы намудрили. Достаточно глобального клока. Ведь на выходе

приемника Вы получаете data_plus и data_minus. Тогда клок arinc это

assign clk_arinc = data_plus | data_minus;

Тогда всего один сдвигающий регистр. на который Вы подаете data_plus. А клок на этот сдвигающий регистр это грубо говоря сдвинутый clk_arinc. Это просто все посадить на глобальный клок.

Все прозрачно. работать будет везде.

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


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

В предлагаемом Вами варианте я получаю еще один клоковый домен, соответсвенно, ему тогда либо глобальный буфер подавай, либо за MAXSKEW следи.

"Мудреж" умышленный, чтоб корка была исключительно синхронна относительно глобального тактового и "рваные" фронты мне жить не мешали.

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


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

Похоже, что Data_in_X ассинхронна по отношению к clc. Потому я думаю, что проблема кроется в метастабильности входного триггера tRising_X. Как синхронизатор tRising_X работать будет плохо, потому как имеет некоторое количество логики между триггерами.

 

Для начала я бы попробовал поставить дополнительных два триггера на Data_in_X без enables, resets, etc. Может быть поможет.

 

А еще посмотрел бы на способ формирования Arinc_rise_time - возможно ее перепад совпадает с изменением данных. На сколько я понимаю - Arinc_rise_time - это enable, подстроенный под бодовую частоту.

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


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

Действительно, намудрил, а нулевой бит tRising_X не подумал выкинуть при анализе фронта, в понедельник попробую.

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


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

Хотя это и было ошибкой, но не она оказывает такое влияние :(

Никак понять не могу, чего такого "умного" делает с описанием Synplify чего не делает XST, сколько разных вариантов перебрал, а результат один.

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


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

Может Вы приведете полный модуль. Потому как ошибки я не заметил. Здесь наверно логическая ошибка. Протокол приема не может быть сложным.

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


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

Тады надо смотреть взаимные отношения между Arinc_rise_time и Data_in_X. Возможно моменты их изменений совпадают или "плавают" вокруг совпадения. Я бы попытался "подвигать" строб разрешения данных по импульсу взад-вперед для проявления полной картины.

 

В чем разница синтеза. Это хороший вопрос. Похоже, что вы пользуетесь одной из последних версий ISE и сравнительно старой версией Synplify. ISE в последнее время поменял стратегию размещения элементов на кристалле для минимизации интерконнектов между элементами схемы, а Synplify вашей версии все еще размещал элементы геометрически. Возможно в этом есть вопрос. Еще - возможно включена опция ретайминга. В этих случаях Synplify умеет активно двигать триггера по ассинхронным цепочкам для максимизации рабочей частоты. Это тоже может быть проблемой в вашем случае.

 

Ну вот и все мои идеи и предположения. На схему из десятка триггеров с двумя компараторами больше ничего придумать не получается :( Был бы очень заинтересован услышать окончание истории, потому как ситуация очень нестандартна.

 

А в общем - чудес не бывает. Это означает, что данное поведение имеет какое-то рациональное объяснение. Как я понимаю, ваши рабочие частоты очень далеки от критических, потому схему обязательно надо подружить с Synplify или понять что идет не так. Потому как в последствии эта ошибка может проявиться при перемещении элементов по кристаллу или при большом заполнении кристалла.

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


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

Стробы я двигал, это не влияло.

Версия Synplify похоже то же не причем, я попроболвал собрать этот проект в ISE7.1+Syn8.1, результат не меняется:

Вот еще часть кода:

`define L 1'b0
`define H 1'b1
module Arinc_core_RX(
  clc,
  rst,
  ARINC_select_clc,
  Enable_compare_data,
  Data_in_A,
  Data_in_B,
  FIFO_clear,
  FIFO_err,
  FIFO_have_data,
  FIFO_read_strobe,
  Error_Count,
  Data_out);
  input clc;
  input rst;
  input Data_in_A;
  input Data_in_B;
  input FIFO_clear;
  input FIFO_read_strobe;
  input [1:0] ARINC_select_clc;
  input Enable_compare_data;

  output [31:0] Data_out;
  output FIFO_err;
  output FIFO_have_data;

  output [7:0] Error_Count;

  parameter FREQUENCY_CLC=50000000;
  parameter FIX_CLOCK_DEVIDER="FALSE";
  parameter FIX_CLOCK_DEVIDER_VALUE=16'd150;
  parameter RAM_WIDTH = 32;
  parameter RAM_ADDR_BITS = 5;
  parameter COMPARE_INPUT_DATA = "TRUE";

reg [31:0] Data_out;
reg FIFO_err;
reg FIFO_have_data;
reg [7:0] Error_Count;

reg Arinc_rise_time/* synthesis syn_preserve=1 */; // 1/10 of period
reg Interword_delay/* synthesis syn_preserve=1 */;
reg Rising_data_A/* synthesis syn_preserve=1 */;
reg Rising_data_B/* synthesis syn_preserve=1 */;
reg Parity_Control;
reg Data_Ready;
reg [31:0] Data_shift_reg;
reg [31:0] Data_shift_reg_swap;

wire [31:0] RAM_compare_data;
reg compare_result;
reg RAM_compare_WE;
reg [31:0] RAM_compare_WEt1;

reg lock_rise_A;
reg lock_rise_B;


//----------------------------------- Start descripion

reg [15:0] clc_counter_1;
always @(posedge clc)
if(rst)
  begin
    clc_counter_1<=0;
    Arinc_rise_time<=`L;
  end
else
  if(FIX_CLOCK_DEVIDER=="FALSE")
    begin
      if(ARINC_select_clc==2'b00) //12,5kHz
        begin
          if(clc_counter_1==((FREQUENCY_CLC/100000)-1))
            begin
              clc_counter_1<=0;
              Arinc_rise_time<=`H;
            end
          else
            begin
              clc_counter_1<=clc_counter_1+1;
              Arinc_rise_time<=`L;
            end
        end
      else
      if(ARINC_select_clc==2'b01) //50kHz
          begin
            if(clc_counter_1==((FREQUENCY_CLC/500000)-1))
              begin
                clc_counter_1<=0;
                Arinc_rise_time<=`H;
              end
            else
              begin
                clc_counter_1<=clc_counter_1+1;
                Arinc_rise_time<=`L;
              end
          end
        else
          if(ARINC_select_clc==2'b10) //100kHz
            begin
              if(clc_counter_1==((FREQUENCY_CLC/1000000)-1))
                begin
                  clc_counter_1<=0;
                  Arinc_rise_time<=`H;
                end
              else
                begin
                  clc_counter_1<=clc_counter_1+1;
                  Arinc_rise_time<=`L;
                end
            end
          else;
    end
  else
    begin
      if(clc_counter_1==(FIX_CLOCK_DEVIDER_VALUE-1))
        begin
          clc_counter_1<=0;
          Arinc_rise_time<=`H;
        end
      else
        begin
          clc_counter_1<=clc_counter_1+1;
          Arinc_rise_time<=`L;
        end
    end

reg [4:0] clc_counter_2;
always @(posedge clc)
if(rst)
  begin
    clc_counter_2<=0;
    Interword_delay<=`L;
  end
else
  begin
    if( (Data_in_A==`H) || (Data_in_B==`H) )
      begin
        clc_counter_2<=0;
        Interword_delay<=`L;
      end
    else
      if(clc_counter_2!=5'd31)
        if(Arinc_rise_time==`H)
          begin
            if(clc_counter_2==5'd29)
              Interword_delay<=`H;
            clc_counter_2<=clc_counter_2+1;
          end
        else
          begin
            Interword_delay<=`L;
          end 
  end

reg [3:0] tRising_A/* synthesis syn_preserve=1 */;
reg [3:0] tRising_B/* synthesis syn_preserve=1 */;
reg [1:0] tData_in_A;
reg [1:0] tData_in_B;

always @(posedge clc)
begin
  tData_in_A <= {tData_in_A[0],Data_in_A};
end
always @(posedge clc)
begin
  tData_in_B <= {tData_in_B[0],Data_in_B};
end

always @(posedge clc)
if(rst)
  begin
    tRising_A[3:0]<=4'b0000;
  end
else
  if(Arinc_rise_time==`H)
    begin
      tRising_A[3:0]<={tRising_A[2:0],tData_in_A[1]};
    end
  else;

always @(posedge clc)
if(rst)
  begin
    tRising_B[3:0]<=4'b0000;
  end
else
  if(Arinc_rise_time==`H)
    begin
        tRising_B[3:0]<={tRising_B[2:0],tData_in_B[1]};
    end
  else;

always @(posedge clc)
if(rst)
  Rising_data_A<=`L;
else
  if(Arinc_rise_time==`H)
    if((tRising_A[3:1]==3'b011))
      Rising_data_A<=`H;
    else
      Rising_data_A<=`L;
  else Rising_data_A<=`L;

always @(posedge clc)
if(rst)
  Rising_data_B<=`L;
else
  if(Arinc_rise_time==`H)
    if((tRising_B[3:1]==3'b011))
      Rising_data_B<=`H;
    else
      Rising_data_B<=`L;
  else Rising_data_B<=`L;


reg [3:0] tmp_11;
always @(posedge clc)
begin
  tmp_11 <= {tmp_11,Interword_delay};
end

reg [1:0] Data_ticks_count;
always @(posedge clc)
if(rst)
  begin
    Data_ticks_count=0;
  end
else 
  if(tmp_11[1])
    Data_ticks_count=0;
  else
    if(Rising_data_A || Rising_data_B)
      Data_ticks_count = Data_ticks_count + 1;

always @(posedge clc)
if(rst)
  begin
    Data_shift_reg<=0;
  end
else  
    if(Rising_data_A)
      Data_shift_reg[31:0]<={Data_shift_reg[30:0],`H};  
    else
      if(Rising_data_B)
        Data_shift_reg[31:0]<={Data_shift_reg[30:0],`L};  
      else 
        Data_shift_reg <= Data_shift_reg;  

always @(*) //(*)
begin
  Parity_Control=((Data_shift_reg[0])^(Data_shift_reg[1])^(Data_shift_reg[2])^(Data_shift_reg[3])
^(Data_shift_reg[4])^(Data_shift_reg[5])^(Data_shift_reg[6])^(Data_shift_reg[7])^(Data_shift_reg[8])
^(Data_shift_reg[9])^(Data_shift_reg[10])^(Data_shift_reg[11])^(Data_shift_reg[12])^(Data_shift_reg[13
])^(Data_shift_reg[14])^(Data_shift_reg[15])^(Data_shift_reg[16])^(Data_shift_reg[17])
^(Data_shift_reg[18])^(Data_shift_reg[19])^(Data_shift_reg[20])^(Data_shift_reg[21])
^(Data_shift_reg[22])^(Data_shift_reg[23])^(Data_shift_reg[24])^(Data_shift_reg[25])
^(Data_shift_reg[26])^(Data_shift_reg[27])^(Data_shift_reg[28])^(Data_shift_reg[29])
^(Data_shift_reg[30]));
end

always @(posedge clc)
if(rst)
  begin
    Error_Count=0;
    Data_Ready=`L;
  end
else
  if(Interword_delay)
//    if((Parity_Control==Data_shift_reg[31])&&(Data_ticks_count==5'd32))
    if((Parity_Control==Data_shift_reg[31]))
      begin
        Data_Ready=`H;
      end
    else
      Error_Count=Error_Count+1;  
  else
    Data_Ready=`L;

always @(posedge clc)
if(Data_Ready)
  begin
    Data_shift_reg_swap[0] =  Data_shift_reg[31];
    ...
    Data_shift_reg_swap[31] =  Data_shift_reg[0];
  end


  ...
  ...
  ...

endmodule

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


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

Хи-хи, выложил код, сам внимательней присмотрелся :). Вобщем, перенес синхронизаторы на вход всего блока. все встало на свои места. Ребята, спасибо за участие.

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


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

Странно все это. Почему это от переноса чего то, работающего на одной частоте что то должно изменяться. разве что исправили это

reg [3:0] tmp_11;

always @(posedge clc)

begin

tmp_11 <= {tmp_11,Interword_delay};

end

И еще вопрос. А понятие пауза у Вас где нибудь встречается?

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


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

ресет для arinc без надобности. Система должна самовосстанавливаться. Без паузы никак.

 

module arinc_429

(

input clk_50mHz,

input data_plus,

input data_minus,

input [1:0] sel_arinc,

output reg [31:0] kod

);

 

reg [1:0] shift_rg;

reg [13:0] ct_pauze;

reg [4:0] ct_bit;

reg [10:0] ct_int;

reg [31:0] shift_right_rg;

 

reg [13:0] zapret_ct_pauze;

reg [10:0] enable_wr;

reg temp;

 

wire istina;

 

always @ (sel_arinc)

case (sel_arinc)

2'b00: {zapret_ct_pauze, enable_wr} = {14'd14000, 11'd1000}; //12.5 kHz

2'b01: {zapret_ct_pauze, enable_wr} = {14'd3645, 11'd260}; //48 kHz

2'b10: {zapret_ct_pauze, enable_wr} = {14'd1750, 11'd125}; //100 kHz

default : {zapret_ct_pauze, enable_wr} = {14'd14000, 11'd1000}; //12.5 kHz

endcase

 

assign istina = ^shift_right_rg;

 

always @(posedge clk_50mHz) begin

shift_rg <= {shift_rg[0], (data_plus | data_minus)}; // метастабильность

if (shift_rg[1]) ct_pauze <= 14'd0;

else if (ct_pauze != zapret_ct_pauze) ct_pauze <= ct_pauze + 1'b1;

if (shift_rg[1] == 1'b0) ct_int <= 11'd0;

else ct_int <= ct_int + 1'b1;

if (ct_pauze == zapret_ct_pauze) ct_bit <= 5'd0;

else if (ct_int == enable_wr) ct_bit <= ct_bit + 1'b1;

if (ct_int == enable_wr) shift_right_rg <= {data_plus, shift_right_rg[31:1]};

temp <= (ct_int == enable_wr) & (ct_bit == 5'd31);

if (temp & istina) kod <= shift_right_rg; end

 

endmodule

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


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

2 sazh

Исправил разрешение Interword_delay, он и есть детектор паузы.

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


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

Люди помогите пожалуйста. У меня стоит задача написать модуль для декодирования сигнала Аринк Я взял ваш код загнал его в САПР ModelSim откомпилировал. А запустил симуляцию. Подскажите по входам что нужно подавать. Я очень прошу напишите полное описание всех сигналов модуля которые просматриваются через САПР и вообщем как вся эта штука работает. Просто я только начал заниматься всем этим и сразу мне поставили задачу с этим Аринком....сессия на носу а курсовую очень надо....Автора кода очень прошу отозваться либо аську свою напишите или мобильный...Мне очень нужна ваша помощь! Заранее благодарен!!!!

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


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

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

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

Гость
К сожалению, ваш контент содержит запрещённые слова. Пожалуйста, отредактируйте контент, чтобы удалить выделенные ниже слова.
Ответить в этой теме...

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

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

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

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

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

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