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

ULPI не работает

Доброго времени суток.

Уже несколько недель тщетно пытаюсь побороть ULPI. Вроде бы с самим протоколом разобрался и, если я правильно понимаю, моя проблема кроется либо в описании временных ограничений(в этом я не очень силен), либо в колхозности платы(сделано все на макетке, фото приложу ниже). Проблема имеется только с отправкой данных, поэтому далее речь пойдет только о трансмиттере.

Кратко опишу, как это работает. В модуле трансмиттера имеется 2 FIFO буфера. Один нужен для непосредственно данных(TXCMD в том числе), второй для количества передаваемых байт. Соответственно 
1. Сначала детектируется то, что второй буфер не пуст
2. Считывается количество байт
3. Считывается первый байт
4. По сигналу NXT считываются следующие байты
5. По окончанию считывания генерируется STP
6. Из-за разности размера входной и выходной шины FIFO ненужные данные читаются в пустую

FPGA использую EP4CE6E22C8(Intel), трансивер FUSB2805, пишу на SystemVerilog.

Код модуля трансмиттера:

Спойлер
module ULPI_TX(
input CLK,
input DIR,
input NXT,
output bit STP,
output bit [7:0] DATA,

input OUT_FIFO_wrclk,
input OUT_FIFO_wren,
input [31:0] OUT_FIFO_data,
output bit OUT_FIFO_wrempty,
output bit [6:0] OUT_FIFO_wrusedw,

input BYTES_wrclk,
input BYTES_wren,
input [31:0] BYTES_data
);

logic [7:0] DATA_d;

logic rden_trig = 0;
logic rden_trig_d;
logic rden_trig_edge;
always_ff @(posedge CLK)
    rden_trig_d<=rden_trig;
assign rden_trig_edge=rden_trig^rden_trig_d;
    
logic rden;

always_ff @(posedge CLK)
if (rden)
    DATA<=DATA_d;

assign rden = (NXT|rden_trig_edge); 

logic rdempty;

ULPI_MEM_OUT mem_out (
    .data(OUT_FIFO_data),
    .rdclk(CLK),
    .rdreq(rden),
    .wrclk(OUT_FIFO_wrclk),
    .wrreq(OUT_FIFO_wren),
    .q(DATA_d),
    .rdempty(rdempty),
    .wrempty(OUT_FIFO_wrempty),
    .wrusedw(OUT_FIFO_wrusedw)
);
logic [31:0] BYTES_q;
logic BYTES_rden;
logic BUFE;                                                //Buffer empty

ULPI_MEM_OUT_bytes mem_out_b (
    .data(BYTES_data),
    .rdclk(CLK),
    .rdreq(BYTES_rden),
    .wrclk(BYTES_wrclk),
    .wrreq(BYTES_wren),
    .q(BYTES_q),
    .rdempty(BUFE)
);

logic [31:0] bytes_cnt;

enum bit [2:0] {BUFE_detecting, BUFFER_broadcast, NOT_VALID_BYTES_flush} STAGE = BUFE_detecting;

logic [1:0] minor_substages = 0;

always_ff @(posedge CLK)
begin
    if (STAGE==BUFE_detecting)
    begin
        case (minor_substages)
            0:    if (!BUFE)
                begin
                    minor_substages<=minor_substages+1'b1;
                    BYTES_rden<=1;
                end
                
            1:    begin
                    BYTES_rden<=0;
                    minor_substages<=minor_substages+1'b1;
                end
            2:    begin
                    if (!DIR)
                    begin
                        minor_substages<=minor_substages+1'b1;
                        rden_trig<=!rden_trig;
                    end
                end
            3:    begin
                    bytes_cnt<=BYTES_q-1;
                    minor_substages<=0;
                    STAGE<=BUFFER_broadcast;
                    rden_trig<=!rden_trig;
                end
        endcase
    end
    
    if (STAGE==BUFFER_broadcast)
    begin
        if (NXT)
            bytes_cnt<=bytes_cnt-1;
        if ((bytes_cnt==0)&(NXT))
        begin
            STP<=1;
            STAGE<=NOT_VALID_BYTES_flush;
        end
    end
    
    if (STAGE==NOT_VALID_BYTES_flush)
    begin
        STP<=0;
        if (!rdempty)
            rden_trig<=!rden_trig;
        else
            STAGE<=BUFE_detecting;
    end
end
endmodule

 

Код временных ограничений:

Спойлер
derive_clock_uncertainty

create_clock -name clk60 -period 60MHz [get_ports {ULPI_CLK}]
create_clock -period 60MHz -name {virt_clk_60}

set_output_delay -clock [ get_clocks {virt_clk_60} ] -max 7 [get_ports {ULPI_DATA[0] ULPI_DATA[1] ULPI_DATA[2] ULPI_DATA[3] ULPI_DATA[4] ULPI_DATA[5] ULPI_DATA[6] ULPI_DATA[7] ULPI_STP}]

set_output_delay -clock [ get_clocks {virt_clk_60} ] -min -1 [get_ports {ULPI_DATA[0] ULPI_DATA[1] ULPI_DATA[2] ULPI_DATA[3] ULPI_DATA[4] ULPI_DATA[5] ULPI_DATA[6] ULPI_DATA[7] ULPI_STP}]

 

Фото платы трансивера:

Спойлер

2zgpip9vyb.jpg2zgpiqb52g.jpg

P.S. Вроде бы всё описал. Слёзно прошу помощи.

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

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


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

38 минут назад, funascan сказал:

Кратко опишу, как это работает. В модуле трансмиттера имеется 2 FIFO буфера. Один нужен для непосредственно данных(TXCMD в том числе), второй для количества передаваемых байт. 

 

 

Система с двумя несинхронными Фифо никогда хорошо работать не будет...

достаточно рассогласовать их на половину кадра и дальше вы никогда не соберёте их вместе.

Гораздо проще сделать к Фифо данных дополнительных теги, то есть дополнительное поле памяти на два Бита и туда писать кодировку "начало кадра", "конец кадра ",  "данных" и "ошибка данных".

На приёмном конце читаете поле тега и ищете начало кадра. дальше вычитывайте данные выбрасываете ошибочные данные и делайте это до момента прихода кодировки "конца кадра".

И ещё тут недавно обсуждали стиль написания текста на верилоге.. Посмотрите там даны хорошие ссылки на статьи...

 

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


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

28 минут назад, iosifk сказал:

Система с двумя несинхронными Фифо никогда хорошо работать не будет...

достаточно рассогласовать их на половину кадра и дальше вы никогда не соберёте их вместе.

Тут я согласен, но я всегда перед записью в фифо проверяю, нет ли там чего. Да, это определенная потеря в производительности, но рассинхрона точно быть не может.

28 минут назад, iosifk сказал:

Гораздо проще сделать к Фифо данных дополнительных теги, то есть дополнительное поле памяти на два Бита и туда писать кодировку "начало кадра", "конец кадра ",  "данных" и "ошибка данных".

На приёмном конце читаете поле тега и ищете начало кадра. дальше вычитывайте данные выбрасываете ошибочные данные и делайте это до момента прихода кодировки "конца кадра".

Думал так сделать, но изначально была задумка сразу из памяти кидать данные в ulpi. Как оказалось, при этом задержка данных больше, поэтому вставил триггер после памяти. Ну и к тому же конечные точки уже под такой способ заточены, а их переписывать слишком уж муторно. А учитывая вышенаписанное может и не нужно.

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

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


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

5 часов назад, des00 сказал:

как именно не работает то?

Энумерация то проходит, то не проходит. Если проходит, то данные не всегда передаются и конечная точка рано или поздно отключается по 3м ошибкам.

На логическом анализаторе виден отправленный пакет(причем правильно отправленный) а ack пакета после него не следует.

Иногда бывает, что при подключении трансивер уходит в Low power Mode. Я так понимаю, что это происходит, когда я пишу в function control, а трансивер что то не правильно принимает и пишет 0 в SuspendM.

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


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

4 minutes ago, funascan said:

На логическом анализаторе виден отправленный пакет(причем правильно отправленный) а ack пакета после него не следует.

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

 

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


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

7 часов назад, des00 сказал:

 Где ваш ack

2zj46blps0.jpg

Происходит вот это, поэтому и ack-а нет. Если я правильно понимаю, то трансивер неправильно захватывает данные, а ошибка хотя бы в одном бите - это сразу же проблема с контрольной суммой.

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

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


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

2zj5glsmmk.png2zj5i6kmho.png2zj5j6v7tu.png2zj5jv6cpt.png

Как-то так это в signal tap выглядит

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

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


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

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

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

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

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

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

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

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

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

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