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

Кастомные прошивки под ettus usrp

Добрый день. 

Если есть у кого опыт, буду благодарен.

Интересует вопросы трудоемкости подключения кастомной прошивки. Примерно с чем придется столкнуться. Какие-то свои замечания по опыту.

Сами железки имеются. 

( такие https://www.ettus.com/all-products/x310-kit/)

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

1.

https://github.com/EttusResearch/fpga

Скачивалось, собиралось. Примерно понятно как оттуда выкинуть ddc и resampler на 2 канала и вставить свои демодуляторы.

Но в проектах прошивок ettus пока не нашел готовых RFNoc с поддержкой в UHD для передачи абстрактных 32 бит в прошивку.

Подошло бы просто передавать серию 32х разрядных слов через UHD в прошивку.

По идее для телеметрии демодуляции хотелось бы считывать из прошивки 32х разрядные данные (можно и по одному адресу, аля axi-lite) - видимо это тоже через RFNoc

Пока не совсем понятно - насколько сильно нужно передалть RFNoc со стороны плиса, чтобы скидывать туда свои абстрактные 32 разрядные конфигурационные пакеты.

Может там уже, вообще, есть все готовое и не нужно даже переделывать.

2.

Не понятно сколько времени уделить модификации UHD драйвера под свой кастомный RFNoc. Насколько это запарно. Настройку синтезаторов, АЦП планируется оставить такой же, чтобы по минимуму изменять UHD.

Опять же, может в UHD есть уже готовое и я просто проглядел невнимательно.

Предполагается, что хост и UHD драйвер под винду. 

Всем спасибо!

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


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

с тех пор как Ettus Research продался клмпании National Instruments, теперь это не X310, а NI USRP-294x и NI USRP-295x.

в опенсорс с того момента ничего не пилится, вместо этого продвигается NI LabView. и NI LabVIEW Communications System Design Suite

RFNoC переродился в виде совсем другой концепции в других железок и в рамках бывшего X310 забыт и заброшен.

сами аппаратные платформы NI USRP-29xx пока ещё производятся, но идет активное выдавливание в сторону более дорогих коробочных решений серии FlexRIO и PXI FlexRIO

 

1 hour ago, 7777777alex said:

Предполагается, что хост и UHD драйвер под винду.

готового опенсорс под винду.нет ничего

 

под linux есть Gnu Radio, там кое-что есть опенсорс

про gnu radio для windows забудьте, это страшный сон с cygwin, проще поставить linux и не трахать себе мозги.

 

1 hour ago, 7777777alex said:

Примерно понятно как оттуда выкинуть ddc и resampler на 2 канала и вставить свои демодуляторы.

Вы кажется совсем не понимаете что такое SDR. в рамках этой концепции демодуляторы пишутся в софте на стороне компа.

 

 

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


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

если же говорить про драйвер uhd и что конкретно он делает - формат пакета для SDR Radio стандартизован ICE VITA 49. и в рамках стандартной прошивки для X310 в Ethernet между компом и железкой бегают пакеты именно по этому протоколу

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


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

13 hours ago, krux said:

Вы кажется совсем не понимаете что такое SDR. в рамках этой концепции демодуляторы пишутся в софте на стороне компа.

Добрый день, уважаемый krux.

Благодарю за ответ. Как взаимодействует NI и ettus мы представляем. ( кто кого купил и что "впаривает" простым смертным).

Я нигде не указал в вопросе про SDR, GNU Radio как раз потому, что в задаче не стоит работа с железкой аля GNU Radio или подключение к SDR Sharp.

Мы занимаемся, скажем так, анализом радиоизлучений не один год, и конечно "свистелки" AirSpy HackRFOne и прочие нам известны. 

Устройства, серии X300 и серии NI USRP-294x и NI USRP-295x используются нами, и не только они.

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

Все для этого сделано самим NI ettus и энтузиастами GNU Radio и SDRSharp. Подключил исходники, поставил драйвер, настроил и забирай отсчеты.

В задачах где нужно демодулировать декодировать сигнал непрерывного излучения на десятки или сотни МБод

стандартная SDR концепция даже на ПК с высокопроизводительным GPU (например NVidia 3080 TI) не позволит получить качественный результат.

За плисовым традиционным демодулятором декодером такой концепции SDR с GPU пока не угнаться. Да и стоимость, энергопотребление и т.п. Тем более, если плис итак есть на борту и используется только как простой поставщик отсчетов. Да и вообще, речь не о SDR - как я уже сказал.

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

 

Преимущество ettus железок в рамках решаемой задачи, перед аналогичными железками от NI в том, что у них есть рабочие исходники как плисовой части так и хостовой.

Купить железо за бугром можно. NI аналоги из-за закрытости исходников тут не рассматриваются.

Ethernet соединение так же не рассматривается при работе с X310, используем PCI. При необходимости записать отсчеты на 200 МГц ethernet не поможет. Плисина там жирная, поэтому выкинув оттуда лишнее (ddc resampler уже имеются у демодуляторов) можно уместить даже "толстые" демодуляторы. Проблема только в конфигурировании такого демодулятора. Как залить через uhd настройки фильтров, созвездия, преамбулы и т.п. Все это просто набор 32х разрядных слов - и надо их просто прокинуть не нарушив работу всего остального.

От UHD уходить не хочется чтобы не писать поддержку остальной части железа самим и не делать лишнюю работу. Не поломать настройку АЦП, выбор тактовой несущей, аналогового усиления аттенюации и тп.

Уважаемый krux, вы с какой стороны имеете опыт разработки для ettus железок? со стороны хоста или fpga ?

Спасибо

 

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


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

после демодулятора вы потеряете единую привязку синхронизации между ПЛИС и ПК. И UHD вам в этом не поможет никак. Вы здесь залезли в поле непаханое, поэтому как оттуда выбираться я вам так сразу и не подскажу.

1 hour ago, 7777777alex said:

При необходимости записать отсчеты на 200 МГц ethernet не поможет.

Эх, куда вас понесло. Если задача только записать ВЕСЬ поток 10 GbE на огромные жесткие диски - то эта задача давно решена в рамках требований закона Яровой у операторов связи. На обычных компах, никаких ПЛИС.

А поток 200 МГц 16 бит легко умещается в 10 GbE.

 

1 hour ago, 7777777alex said:

при работе с X310, используем PCI

там нет PCI, есть PCI Express 2.0 x4, и со стороны X310  PCI Express утыкается в заказной ASIC, который производит IDT. Мне не удалось получить NDA на него, там все закрыто-проприетарное. Как с ним работать со стороны ПЛИС достоверно неизвестно, а реверсить я не стал. Поэтому в самой возможности что-то модифицировать в UHD под Win вижу огромные неразрешимые проблемы.

 

1 hour ago, 7777777alex said:

Все это просто набор 32х разрядных слов - и надо их просто прокинуть не нарушив работу всего остального.

Если бы все было так просто вы бы это все уже сделали.

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


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

4 minutes ago, krux said:

после демодулятора вы потеряете единую привязку синхронизации между ПЛИС и ПК. И UHD вам в этом не поможет никак.

Что вы имеете в виду под этим? зачем мне единая привязка синхронизации выхода демодулятора и ПК? или я вас не так понял и эта особенность работы UHD и usrp в каком-то режиме?

Идея была "вклиниться" вместо их стандартного ddc-rsmp. Кто будет забирать отсчеты, жесткие решения или результат декодирования через UHD ему синхронизация не важна.

5 minutes ago, krux said:

там нет PCI, есть PCI Express 2.0 x4,

я опустил слова Express 2.0 x4, предполагая, что собеседник понимает о каком PCI я пишу. Прошу прощения если нарушил "религию".

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


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

37 minutes ago, krux said:

А поток 200 МГц 16 бит легко умещается в 10 GbE.

Согласен, сейчас вспоминаю - причины выбора PCIe были несколько иные, нежели пропускная способность.

Несмотра на то что там 

  • Dual 10 Gigabit Ethernet – 2x RX at 200 MSps per channel

Прошу прощения.

X310_Back-Large_2.jpg

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


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

Уважаемый kruxЯ так понимаю вы работали, и не могли бы тогда пояснить.

Есть у них такой модуль

module noc_block_ddc #(
  parameter NOC_ID            = 64'hDDC0_0000_0000_0000,
  parameter STR_SINK_FIFOSIZE = 11,     //Log2 of input buffer size in 8-byte words (must hold at least 2 MTU packets)
  parameter MTU               = 10,     //Log2 of output buffer size in 8-byte words (must hold at least 1 MTU packet)
  parameter NUM_CHAINS        = 2,
  parameter COMPAT_NUM_MAJOR  = 32'h2,
  parameter COMPAT_NUM_MINOR  = 32'h0,
  parameter NUM_HB            = 3,
  parameter CIC_MAX_DECIM     = 255
)(
  input bus_clk, input bus_rst,
  input ce_clk, input ce_rst,
  input  [63:0] i_tdata, input  i_tlast, input  i_tvalid, output i_tready,
  output [63:0] o_tdata, output o_tlast, output o_tvalid, input  o_tready,
  output [63:0] debug
);

Вместо которого пока в теории хотел бы воткнуться.

в нем есть 

1. noc_shell

2. axi_wrapper

3. axi_tag_time

4. axi_rate_change

5. ddc

С ddc все понятно.

С остальной концепцией пока только примерно.

Особенно вопрос с модулями noc_shell, axi_tag_time

В какой мануал можно ткнуться? если таковой имеется или может своими словами скажите, по опыту?

Благодарю

 

Quote

RFNoC Components

The most common mismatch is that between an RFNoC block on the FPGA, and its UHD block controller. There are two levels of compat numbers:

  • noc_shell has its own compat number, which is shared between all blocks and devices (i.e., for any given version of UHD, all RFNoC blocks, regardless on which device, will have the same noc_shell compat number).
  • Blocks itself may (but don't have to) have their own compat number. An example of this are the DDC/DUC blocks. Because of changes at the register level, software and FPGA for those blocks may no longer be compatible.

For users running default images, the solution to resolving a compat number error is to simply download a matching FPGA image and flash it onto the device, typically by running


uhd_images_downloader
uhd_image_loader --args type=$TYPE,addr=$ADDR

For users running their own custom FPGA images, the sequence is a bit more elaborate:

  1. Identify a commit on the FPGA repository that matches the version of UHD you are running. There are multiple ways to do this. If you're on a release tag, then the same release tag will exist on UHD and FPGA repositories. For untagged commits, the submodule pointer in UHD will point to a compatible version of the FPGA repository. For most moments in time, simply using HEAD of the same branch on the two repositories will also work, although this can't be guaranteed. If in doubt, check that the compat numbers in the source are identical.
  2. Rebase your modifications onto that commit of the FPGA repository, or, if your code is out-of-tree (which is the recommended workflow for RFNoC block developers), simply rebuild your blocks against said commit of the FPGA repository.

The newly built FPGA image will then work with your version of UHD.

 

Коды ниже.

noc_shell #(
    .NOC_ID(NOC_ID),
    .INPUT_PORTS(NUM_CHAINS),
    .OUTPUT_PORTS(NUM_CHAINS),
    .STR_SINK_FIFOSIZE({NUM_CHAINS{STR_SINK_FIFOSIZE[7:0]}}),
    .MTU({NUM_CHAINS{MTU[7:0]}}))
  noc_shell (
  .bus_clk(bus_clk), .bus_rst(bus_rst),
    .i_tdata(i_tdata), .i_tlast(i_tlast), .i_tvalid(i_tvalid), .i_tready(i_tready),
    .o_tdata(o_tdata), .o_tlast(o_tlast), .o_tvalid(o_tvalid), .o_tready(o_tready),
    // Computer Engine Clock Domain
    .clk(ce_clk), .reset(ce_rst),
    // Control Sink
    .set_data(set_data), .set_addr(set_addr), .set_stb(set_stb), .set_time(set_time), .set_has_time(set_has_time),
    .rb_stb(rb_stb), .rb_data(rb_data), .rb_addr(rb_addr),
    // Control Source
    .cmdout_tdata(cmdout_tdata), .cmdout_tlast(cmdout_tlast), .cmdout_tvalid(cmdout_tvalid), .cmdout_tready(cmdout_tready),
    .ackin_tdata(ackin_tdata), .ackin_tlast(ackin_tlast), .ackin_tvalid(ackin_tvalid), .ackin_tready(ackin_tready),
    // Stream Sink
    .str_sink_tdata(str_sink_tdata), .str_sink_tlast(str_sink_tlast), .str_sink_tvalid(str_sink_tvalid), .str_sink_tready(str_sink_tready),
    // Stream Source
    .str_src_tdata(str_src_tdata), .str_src_tlast(str_src_tlast), .str_src_tvalid(str_src_tvalid), .str_src_tready(str_src_tready),
    // Stream IDs set by host 
    .src_sid(src_sid),                   // SID of this block
    .next_dst_sid(next_dst_sid),         // Next destination SID
    .resp_in_dst_sid(resp_in_dst_sid),   // Response destination SID for input stream responses / errors
    .resp_out_dst_sid(resp_out_dst_sid), // Response destination SID for output stream responses / errors
    // Misc
    .vita_time(64'd0),
    .clear_tx_seqnum(clear_tx_seqnum),
    .debug(debug));

 

axi_wrapper

 

axi_wrapper #(
        .SIMPLE_MODE(0), .MTU(MTU))
      axi_wrapper (
        .bus_clk(bus_clk), .bus_rst(bus_rst),
        .clk(ce_clk), .reset(ce_rst),
        .clear_tx_seqnum(clear_tx_seqnum[i]),
        .next_dst(next_dst_sid[16*i+15:16*i]),
        .set_stb(set_stb_int), .set_addr(set_addr_int), .set_data(set_data_int),
        .i_tdata(str_sink_tdata[64*i+63:64*i]), .i_tlast(str_sink_tlast[i]), .i_tvalid(str_sink_tvalid[i]), .i_tready(str_sink_tready[i]),
        .o_tdata(str_src_tdata[64*i+63:64*i]), .o_tlast(str_src_tlast[i]), .o_tvalid(str_src_tvalid[i]), .o_tready(str_src_tready[i]),
        .m_axis_data_tdata(m_axis_data_tdata),
        .m_axis_data_tlast(m_axis_data_tlast),
        .m_axis_data_tvalid(m_axis_data_tvalid),
        .m_axis_data_tready(m_axis_data_tready),
        .m_axis_data_tuser(m_axis_data_tuser),
        .s_axis_data_tdata(s_axis_data_tdata),
        .s_axis_data_tlast(s_axis_data_tlast),
        .s_axis_data_tvalid(s_axis_data_tvalid),
        .s_axis_data_tready(s_axis_data_tready),
        .s_axis_data_tuser(s_axis_data_tuser),
        .m_axis_config_tdata(),
        .m_axis_config_tlast(),
        .m_axis_config_tvalid(),
        .m_axis_config_tready(),
        .m_axis_pkt_len_tdata(),
        .m_axis_pkt_len_tvalid(),
        .m_axis_pkt_len_tready());

axi_tag_time

axi_tag_time #(
        .NUM_TAGS(1),
        .SR_TAG_ADDRS(SR_FREQ_ADDR))
      axi_tag_time (
        .clk(ce_clk),
        .reset(ce_rst),
        .clear(clear_tx_seqnum[i]),
        .tick_rate(16'd1),
        .timed_cmd_fifo_full(timed_cmd_fifo_full),
        .s_axis_data_tdata(m_axis_data_tdata), .s_axis_data_tlast(m_axis_data_tlast),
        .s_axis_data_tvalid(m_axis_data_tvalid), .s_axis_data_tready(m_axis_data_tready),
        .s_axis_data_tuser(m_axis_data_tuser),
        .m_axis_data_tdata(m_axis_tagged_tdata), .m_axis_data_tlast(m_axis_tagged_tlast),
        .m_axis_data_tvalid(m_axis_tagged_tvalid), .m_axis_data_tready(m_axis_tagged_tready),
        .m_axis_data_tuser(m_axis_tagged_tuser), .m_axis_data_tag(m_axis_tagged_tag),
        .in_set_stb(set_stb_int), .in_set_addr(set_addr_int), .in_set_data(set_data_int),
        .in_set_time(set_time_int), .in_set_has_time(set_has_time_int),
        .out_set_stb(out_set_stb), .out_set_addr(out_set_addr), .out_set_data(out_set_data),
        .timed_set_stb(timed_set_stb), .timed_set_addr(timed_set_addr), .timed_set_data(timed_set_data));

      // Hold off reading additional commands if internal FIFO is full
      assign rb_stb[i] = ~timed_cmd_fifo_full;

axi_rate_change

axi_rate_change #(
        .WIDTH(33),
        .MAX_N(MAX_N),
        .MAX_M(1),
        .SR_N_ADDR(SR_N_ADDR),
        .SR_M_ADDR(SR_M_ADDR),
        .SR_CONFIG_ADDR(SR_CONFIG_ADDR))
      axi_rate_change (
        .clk(ce_clk), .reset(ce_rst), .clear(clear_tx_seqnum[i]), .clear_user(clear_user),
        .src_sid(src_sid[16*i+15:16*i]), .dst_sid(next_dst_sid[16*i+15:16*i]),
        .set_stb(out_set_stb), .set_addr(out_set_addr), .set_data(out_set_data),
        .i_tdata({m_axis_tagged_tag,m_axis_tagged_tdata}), .i_tlast(m_axis_tagged_tlast),
        .i_tvalid(m_axis_tagged_tvalid), .i_tready(m_axis_tagged_tready),
        .i_tuser(m_axis_tagged_tuser),
        .o_tdata({nc,s_axis_data_tdata}), .o_tlast(s_axis_data_tlast), .o_tvalid(s_axis_data_tvalid),
        .o_tready(s_axis_data_tready), .o_tuser(s_axis_data_tuser),
        .m_axis_data_tdata({sample_in_tuser,sample_in_tdata}), .m_axis_data_tlast(sample_in_tlast),
        .m_axis_data_tvalid(sample_in_tvalid), .m_axis_data_tready(sample_in_tready),
        .s_axis_data_tdata({1'b0,sample_out_tdata}), .s_axis_data_tlast(1'b0),
        .s_axis_data_tvalid(sample_out_tvalid), .s_axis_data_tready(sample_out_tready),
        .warning_long_throttle(warning_long_throttle),
        .error_extra_outputs(error_extra_outputs),
        .error_drop_pkt_lockup(error_drop_pkt_lockup));
      
      assign sample_in_eob = m_axis_tagged_tuser[124]; //this should align with last packet output from axi_rate_change

ddc

 

ddc #(
        .SR_FREQ_ADDR(SR_FREQ_ADDR),
        .SR_SCALE_IQ_ADDR(SR_SCALE_IQ_ADDR),
        .SR_DECIM_ADDR(SR_DECIM_ADDR),
        .SR_MUX_ADDR(SR_MUX_ADDR),
        .SR_COEFFS_ADDR(SR_COEFFS_ADDR),
        .NUM_HB(NUM_HB),
        .CIC_MAX_DECIM(CIC_MAX_DECIM))
      ddc (
        .clk(ce_clk), .reset(ce_rst),
        .clear(clear_user | clear_tx_seqnum[i]), // Use AXI Rate Change's clear user to reset block to initial state after EOB
        .set_stb(out_set_stb), .set_addr(out_set_addr), .set_data(out_set_data),
        .timed_set_stb(timed_set_stb), .timed_set_addr(timed_set_addr), .timed_set_data(timed_set_data),
        .sample_in_tdata(sample_in_tdata), .sample_in_tlast(sample_in_tlast),
        .sample_in_tvalid(sample_in_tvalid), .sample_in_tready(sample_in_tready),
        .sample_in_tuser(sample_in_tuser), .sample_in_eob(sample_in_eob),
        .sample_out_tdata(sample_out_tdata), .sample_out_tlast(),
        .sample_out_tvalid(sample_out_tvalid), .sample_out_tready(sample_out_tready)
        );

 

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


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

noc_block это модуль который изначально предназначался для аппаратного offload в рамках того же gnu radio, но впоследстыии был отвергнут сообществом gnu radio как некошерная составляющая SDR. Переделывать проект плис и выкидывать оттуда этот блок тогда никто не стал.

выпиливайте не переживая, оставив заглушку адресации шины AXI, поскольку в UHD оно есть, и если обращение по этим адресам будет, то взаимодействие драйвера с железом может, и скорее всего да, зависнет.

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


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

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

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

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

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

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

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

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

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

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