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

likeasm

Участник
  • Постов

    229
  • Зарегистрирован

  • Посещение

Сообщения, опубликованные likeasm


  1. On 2/15/2024 at 4:31 PM, [email protected] said:

    Спасибо за ответы! Сразу встречный вопрос- если запись в драйвере однократная. Что же в таком случае идёт из шины акси после завершения цикла? Что он там досылает, если из драйвера ничего не отправляли? Может ли быть дело в том, что у нас райзер для pcie 30 см? 

    Скорее всего криво формируете пакеты. Там есть особенность: внутри xdma есть fifo, вроде на 64 beat. Кроме того, в доке на xdma имеется описание на рекомендованный размер пакета. Мы работали фиксированными пакетами по 4k байт и проблем не было и это было под linux. Вообще xdma в режиме stream для весьма специфических задач, обычно все стараются поднять режим mm и работать с памятью DDR на плис.

  2. Добрый вечер. Мы разделяем частоту работы JESD от фабрики через dual clock FIFO и ILA ставим на фабрике. В этом решении есть одно но, FIFO тоже криво работает, если нет клока. Разрешение работы такого фифо с порта приема данных от JESD, только после появления частоты. Частомер стоит на стороне фабрики. Сигнал разрешения через CDC из домена фабрики в домен JESD. Тут нужно понимать, что частота фабрики должна быть выше частоты JESD. ЗЫ у вас частота JESD и ПЛИС какая?

  3. Насколько я помню, можно было схематик из Xilinx Foundation 4.1 версии транслировать в VHDL. Среда очень древняя, verilog 2001 она не поддерживала, только 95. Я помнится написал на verilog для XC4000 полином crc16. Скачайте лучше Xilinx Foundation 4.1 там есть больше возможностей. Но по мне такой дичью лучше не заниматься, а переходить на что-то посовременнее типа UltraScale и Vivado.

  4. Вангую, что лучше посчитать не в вентелях, а в ПЛИС от КТЦ ЭЛЕКТРОННИКА. Чтобы заменить один xcku115 по частоте и по ёмкости надо где-то около 1500 5578ТС024, если считать по FF. Ну а по вашему вопросу можно максимальный размер bit stream в битах выдать за вентили.

  5. 4 hours ago, attaboy said:

    А нужно ли это? Если какой-то сигнал не используется, просто не указываете его, и он успешно оптимизируется.

    Ага, xilinx vivado любит тихо без шума и пыли оптимизировать сигналы в их неактивное состояние.  Например, master tready в ноль.

  6. On 10/5/2021 at 2:25 PM, xvr said:

    Нескромный вопрос - что вас заставляет пользоваться средой, почившей в мире более 20 лет назад? Может хотя бы ISE возьмёте? :)

     

    Такое иногда бывает. В 2018 г. меня работа заставила знакомится с серией XC3000 под DOS в среде Xilinx XACT Design Edition, помню это все крутилось на Pentium 166 MMX и имелась ISAшная плата для функционирования данного софта. Эхо НИИ.

  7. 21 hours ago, AVR said:

    Не подскажете, а где ее брать, есть вивадо, но в каталоге phy для jesd204 не виднеется. Про платную корку то понятно, а вот PHY отсутствует, хотя лицензией обеспечен. Это устанавливается дополнительно?

    JESD204 PHY в Vivado 19.1

  8. `timescale 1ns / 1ps
    //////////////////////////////////////////////////////////////////////////////////
    // Company: 
    // Engineer: 
    // 
    // Create Date: 21.04.2021 13:32:39
    // Design Name: 
    // Module Name: axis_tlast_generator
    // Project Name: 
    // Target Devices: 
    // Tool Versions: 
    // Description: 
    // 
    // Dependencies: 
    // 
    // Revision:
    // Revision 0.01 - File Created
    // Additional Comments:
    // 
    //////////////////////////////////////////////////////////////////////////////////
    
    
    module axis_pipe_line
    #( 
    	////////////////////////////////////////////////////////////////////////////
    	//------------------------------- Inputs -----------------------------------
        // Width of AXI stream interfaces in bits
        parameter TDATA_WIDTH = 16,
        // Propagate tkeep signal
        parameter TKEEP_ENABLE = (TDATA_WIDTH>8),
        // tkeep signal width (words per cycle)
        parameter TKEEP_WIDTH = (TDATA_WIDTH/8), 
        // Propagate tid signal       
        parameter TID_ENABLE = 0,
        // tid signal width
        parameter TID_WIDTH = 8,
        // Propagate tdest signal
        parameter TDEST_ENABLE = 0,
        // tdest signal width
        parameter TDEST_WIDTH = 8,
        // Propagate tuser signal 
        parameter TUSER_ENABLE = 1,
        // tuser signal width
        parameter TUSER_WIDTH = 1,              
        // Propagate tlast signal  
        parameter TLAST_ENABLE = 1,
        // Output register type
        // 0 to bypass, 1 for simple buffer, 2 for skid buffer 
        parameter OUT_REG_TYPE = 2
    
    )
    (
    	//////////////////////////////////////////////////////////////////////////////////////
    	//------------------------------- System signals -------------------------------------
        input aclk,
        input aresetn,
    	//////////////////////////////////////////////////////////////////////////////////////
    	//------------------- (Slave) AXIS Payload Interface ------------------------
        input  wire [TDATA_WIDTH-1:0]  s_axis_tdata,
        input  wire [TKEEP_WIDTH-1:0]  s_axis_tkeep,
        input  wire                   s_axis_tvalid,
        output wire                   s_axis_tready,
        input  wire                   s_axis_tlast,
        input  wire [TID_WIDTH-1:0]    s_axis_tid,
        input  wire [TDEST_ENABLE-1:0]  s_axis_tdest,
        input  wire [TUSER_WIDTH-1:0]  s_axis_tuser,
        //////////////////////////////////////////////////////////////////////////////////////
    	//------------------- (Slave) AXIS Control Interface ------------------------
    
    
    	//////////////////////////////////////////////////////////////////////////////////////
    	//------------------- (Master) AXIS Payload Interface -----------------------
        output wire [TDATA_WIDTH-1:0]  m_axis_tdata,
        output wire [TKEEP_WIDTH-1:0]  m_axis_tkeep,
        output wire                   m_axis_tvalid,
        input  wire                   m_axis_tready,
        output wire                   m_axis_tlast,
        output wire [TID_WIDTH-1:0]    m_axis_tid,
        output wire [TDEST_ENABLE-1:0]  m_axis_tdest,
        output wire [TUSER_WIDTH-1:0]  m_axis_tuser
    );
    
    
    
    
    
    reg [TDATA_WIDTH-1:0] m_axis_tdata_stage_01_ff  = {TDATA_WIDTH{1'b0}};
    reg [TKEEP_WIDTH-1:0] m_axis_tkeep_stage_01_ff  = {TKEEP_WIDTH{1'b0}};
    reg                   m_axis_tvalid_stage_01_ff = 1'b0; 
    reg                   m_axis_tlast_stage_01_ff  = 1'b0;
    reg [TID_WIDTH-1:0]   m_axis_tid_stage_01_ff    = {TID_WIDTH{1'b0}};
    reg [TDEST_WIDTH-1:0] m_axis_tdest_stage_01_ff  = {TDEST_WIDTH{1'b0}};
    reg [TUSER_WIDTH-1:0] m_axis_tuser_stage_01_ff  = {TUSER_WIDTH{1'b0}};
    
    
    
    reg [TDATA_WIDTH-1:0] m_axis_tdata_stage_02_ff  = {TDATA_WIDTH{1'b0}};
    reg [TKEEP_WIDTH-1:0] m_axis_tkeep_stage_02_ff  = {TKEEP_WIDTH{1'b0}};
    reg                   m_axis_tvalid_stage_02_ff = 1'b0; 
    reg                   m_axis_tlast_stage_02_ff  = 1'b0;
    reg [TID_WIDTH-1:0]   m_axis_tid_stage_02_ff    = {TID_WIDTH{1'b0}};
    reg [TDEST_WIDTH-1:0] m_axis_tdest_stage_02_ff  = {TDEST_WIDTH{1'b0}};
    reg [TUSER_WIDTH-1:0] m_axis_tuser_stage_02_ff  = {TUSER_WIDTH{1'b0}};
    
    
    reg [TDATA_WIDTH-1:0] m_axis_tdata_stage_03_ff  = {TDATA_WIDTH{1'b0}};
    reg [TKEEP_WIDTH-1:0] m_axis_tkeep_stage_03_ff  = {TKEEP_WIDTH{1'b0}};
    reg                   m_axis_tvalid_stage_03_ff = 1'b0; 
    reg                   m_axis_tlast_stage_03_ff  = 1'b0;
    reg [TID_WIDTH-1:0]   m_axis_tid_stage_03_ff    = {TID_WIDTH{1'b0}};
    reg [TDEST_WIDTH-1:0] m_axis_tdest_stage_03_ff  = {TDEST_WIDTH{1'b0}};
    reg [TUSER_WIDTH-1:0] m_axis_tuser_stage_03_ff  = {TUSER_WIDTH{1'b0}};
    
    
    
    always @(posedge aclk) begin: proc_s_axis_tlast_rmap_cnt_ff
        if(~aresetn) begin
            m_axis_tvalid_stage_01_ff <= 0;
            m_axis_tvalid_stage_02_ff <= 0;
            m_axis_tvalid_stage_03_ff <= 0;
        end else if(s_axis_tready == 1) begin  
        
            m_axis_tvalid_stage_01_ff  <= s_axis_tvalid;
            m_axis_tvalid_stage_02_ff  <= m_axis_tvalid_stage_01_ff;
            m_axis_tvalid_stage_03_ff  <= m_axis_tvalid_stage_02_ff;
    
            if(s_axis_tvalid == 1) begin
                m_axis_tdata_stage_01_ff  <= s_axis_tdata;
                m_axis_tkeep_stage_01_ff  <= s_axis_tkeep;
                m_axis_tlast_stage_01_ff  <= s_axis_tlast;
                m_axis_tid_stage_01_ff    <= s_axis_tid;
                m_axis_tdest_stage_01_ff  <= s_axis_tdest;
                m_axis_tuser_stage_01_ff  <= s_axis_tuser;     
            end
    
            if(m_axis_tvalid_stage_01_ff == 1) begin
                m_axis_tdata_stage_02_ff  <= m_axis_tdata_stage_01_ff;
                m_axis_tkeep_stage_02_ff  <= m_axis_tkeep_stage_01_ff;
                m_axis_tlast_stage_02_ff  <= m_axis_tlast_stage_01_ff;
                m_axis_tid_stage_02_ff    <= m_axis_tid_stage_01_ff;
                m_axis_tdest_stage_02_ff  <= m_axis_tdest_stage_01_ff;
                m_axis_tuser_stage_02_ff  <= m_axis_tuser_stage_01_ff;     
            end
    
            if(m_axis_tvalid_stage_02_ff == 1) begin
                m_axis_tdata_stage_03_ff  <= m_axis_tdata_stage_02_ff;
                m_axis_tkeep_stage_03_ff  <= m_axis_tkeep_stage_02_ff;
                m_axis_tlast_stage_03_ff  <= m_axis_tlast_stage_02_ff;
                m_axis_tid_stage_03_ff    <= m_axis_tid_stage_02_ff;
                m_axis_tdest_stage_03_ff  <= m_axis_tdest_stage_02_ff;
                m_axis_tuser_stage_03_ff  <= m_axis_tuser_stage_02_ff;     
            end
    
    
        end
    end
    
    
    wire [TDATA_WIDTH-1:0]  out_reg_s_axis_tdata;
    wire [TKEEP_WIDTH-1:0]  out_reg_s_axis_tkeep;
    wire                   out_reg_s_axis_tvalid;
    wire                   out_reg_s_axis_tready;
    wire                   out_reg_s_axis_tlast;
    wire [TID_WIDTH-1:0]    out_reg_s_axis_tid;
    wire [TDEST_ENABLE-1:0]  out_reg_s_axis_tdest;
    wire [TUSER_WIDTH-1:0]  out_reg_s_axis_tuser;
    
    assign out_reg_s_axis_tdata  = m_axis_tdata_stage_03_ff;
    assign out_reg_s_axis_tkeep  = TKEEP_ENABLE ? m_axis_tkeep_stage_03_ff : {TKEEP_WIDTH{1'b1}};
    assign out_reg_s_axis_tvalid = m_axis_tvalid_stage_03_ff;
    assign out_reg_s_axis_tlast  = TLAST_ENABLE ? m_axis_tlast_stage_03_ff : 1'b1;
    assign out_reg_s_axis_tid    = TID_ENABLE   ? m_axis_tid_stage_03_ff   : {TID_WIDTH{1'b0}};
    assign out_reg_s_axis_tdest  = TDEST_ENABLE ? m_axis_tdest_stage_03_ff : {TDEST_WIDTH{1'b0}};
    assign out_reg_s_axis_tuser  = TUSER_ENABLE ? m_axis_tuser_stage_03_ff : {TUSER_WIDTH{1'b0}};
    assign s_axis_tready = out_reg_s_axis_tready;
    
    axis_register 
    #(
        // Width of AXI stream interfaces in bits
        .TDATA_WIDTH(TDATA_WIDTH),
        // Propagate tlast signal
        .TLAST_ENABLE(TLAST_ENABLE),
        // Propagate tid signal
        .TID_ENABLE(TID_ENABLE),
        // tid signal width
        .TID_WIDTH(TID_WIDTH),
        // Propagate tdest signal
        .TDEST_ENABLE(TDEST_ENABLE),
        // tdest signal width
        .TDEST_WIDTH(TDEST_WIDTH),
        // Propagate tuser signal
        .TUSER_ENABLE(TUSER_ENABLE),
        // tuser signal width
        .TUSER_WIDTH(TUSER_WIDTH),
        // Register type
        // 0 to bypass, 1 for simple buffer, 2 for skid buffer
        .REG_TYPE(OUT_REG_TYPE)
    ) axis_register_inst0  
    (
        .clk(aclk),
        .rst(aresetn),
    
        /*
         * AXI Stream input
         */
        .s_axis_tdata(out_reg_s_axis_tdata),
        .s_axis_tkeep(out_reg_s_axis_tkeep),
        .s_axis_tvalid(out_reg_s_axis_tvalid),
        .s_axis_tready(out_reg_s_axis_tready),
        .s_axis_tlast(out_reg_s_axis_tlast),
        .s_axis_tid(out_reg_s_axis_tid),
        .s_axis_tdest(out_reg_s_axis_tdest),
        .s_axis_tuser(out_reg_s_axis_tuser),
    
        /*
         * AXI Stream output
         */
        .m_axis_tdata(m_axis_tdata),
        .m_axis_tkeep(m_axis_tkeep),
        .m_axis_tvalid(m_axis_tvalid),
        .m_axis_tready(m_axis_tready),
        .m_axis_tlast(m_axis_tlast),
        .m_axis_tid(m_axis_tid),
        .m_axis_tdest(m_axis_tdest),
        .m_axis_tuser(m_axis_tuser)
    );
    
    endmodule

    Вот в моем представлении конвейер. Данные я пробросил условно, без математических операций. TREADY имею общий для всех стадий конвейера, как глобальный EN. TVALID свой для каждой стадии обработки. Правильно ли я понимаю, TVALID я двигаю по конвейеру только по TREADY? Вопрос по поводу сброса, достаточно будет сбросить только TVALID во всех стадиях или все триггеры сбрасывать?

  9. 1 hour ago, andrew_b said:

    Всякое продвижение данных по конвейеру происходит тогда и только тогда, когда и master_valid, и slave_ready стоят в единице:

    
    if (master_valid == '1' and slave_ready = '1') then
       slave_data_in <= master_data_out;
    endif;

     

    Сигнал TDATA, TLAST нужно рассматривать как данные, а вот как продвигать сигнал TVALID по конвейеру, я так полагаю по сигналу TREADY от приемника, в данном случае от молуля axis_register.v?

    1 hour ago, des00 said:

    Сомнения в чем: в коде axis_register.v, в вашем понимании стандарта или в чем то еще?

    ИМХО стандарт на AXI крайне желательно прочитать пару раз, там подробно разобраны эти моменты.

    Сомнений по модулю нет, по axi тоже вопросов пока нет, вопрос больше по идеологии построения линии конвейера. Я могу модуль axis_register.v поставить после каждой стадии конвейера, либо в конце и тормозить все стадии конвейера по TREADY, и в последней ситуации не понятно, как тащить TVALID? Я предполагаю, что TVALID будет идти вместе с данным по сигналу TREADY от axis_register.v

  10. Добрый вечер, коллеги. Захотелось мне создать свой модуль конвейерной обработки пакетов по интерфейсу AXI Stream. Имею AXI Stream Slave и Master с сигналами TDATA, TVALID, TREADY, TLAST.  Без сигнала TREADY все просто и понятно, поток идет в одном направление без тормозов и все ок. Как только появляется сигнал обратной связи TREADY, то начинается веселье с торможением конвейера и триггерованием TREADY. На просторах сети в  github нашел код некого Alex'a https://github.com/alexforencich/verilog-axis в модуле axis_register.v и были те заветные буферизированные тормоза конвейера, которые я и поставил на выход своего модуля. Есть некие сомнения в правильности обработки... правильно ли я понимаю, что tvalid я проталкиваю по ступеням конвейера как данные по сигналу s_axis_tready из axis_register.v, а обработку данных веду как по s_axis_tready из axis_register.v, так еще и по tvalid соответствующей ступени конвейера? Может есть у кого пример построения такого конвейера или ссылка на чтиво по данной теме?

  11. Я использовал идеологию построения Serial interface от сюда https://www.fpga4fun.com/SerialInterface.html. Там все написано.

    З.Ы. за падежи прошу понять и простить, последнее время хроническое недосыпание.

  12. У вас, как-то странно реализован Oversampling. Обычно создается аккумулятор, который делит несущую частоту, формируя одиночные импульсы длительностью в такт несущей и периодом в 16 раз больше скорости UART. Далее по этим импульсам(Тick-ам) идет работа вашего rx_in. И доменная синхронизация, и мажоритарный фильтр  надо ставить по Tick, а не по несущей частоте.

  13. Я вам советую сделать частотомер внутри ПЛИС и подключить его к клоковым ресурсам фабрики. Просто в момент подачи сброса на внешнюю PLL, клок от неё гулял +/- 100MHz на таком частотомере. Что там реально на выходе PLL, я не анализировал. Если прикинуть, что такая же муть летит к вам в ПЛИС на dbg_hub, то ничего хорошего не будет.

  14. У меня ушла, после добавления в проект ddr4 mig с частотой в 300Mhz. dbg_hub сам зацепил эту частоту на себя, и проблема ушла. Попробуйте прописать хуже не будет.

  15. ILA подключаются через некий dbg_hub, посмотрите после синтеза какая частота на него заведена. Я на него завёл стабильну частоту от генератора в 300Mhz и проблема исчезла.

  16. https://github.com/analogdevicesinc/hdl тут есть бесплатные библиотеки JESD и примеры проектов от AD.

    Если порыть тут https://github.com/analogdevicesinc/linux, то можно найти управляющие драйверы для linux от AD.

    sysref еще нужно правильно подать относительно времянок опоры, setup и hold никто не отменял, страницы 10, 11 AD9208BBPZ-3000.pdf
     

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