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

_Ivan_

Свой
  • Постов

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

  • Посещение

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


  1. Вся фигня в том, что ТС смотрит на радиолюбительские сайты и находит там какие-то поделки вроде помигать светодиодом на плис или какой-нибудь марсоход. Все это песочница. Но когда он пойдет на работу где реально применяются плисы - он столкнется с реальностью - частотами в несколько сотен МГц, задержками вычисления определенного алгоритма и скоростями обработки данных в несколько десятков Гбит в сек.

    У меня у самого был диплом - разработка PCI-E интерфейса и теоретическая скорость могла доходить до 20 Гбит в сек. Мало какому процессору это под силу. Поэтому не стоит недооценивать ПЛИС. На светлую сторону силы переходи ты! :cheers:

  2. Добрый день.

     

    Подскажите, пожалуйста, а в какой сапр лучше всего отлаживать блоки вычислителя с фиксированной точкой? Видел связку матлаб + моделсим точно, в исиме представление числа с фиксированной точкой не нашел. Еще видел что можно копать в сторону VHDL, но все написано на верилоге. А какие есть еще варианты? Можно конечно попробовать написать что-то свое на систем верилоге, но пока ищу готовые решения

  3. Добрый день.

     

    Интересует следующий вопрос.

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

     

    `timescale 1 ns / 1 ns
    
    module Sine
             (
              clk,
              reset_n,
              enb,
              u,
              sin_2_pi_u
             );
    
    
     input   clk;
     input   reset_n;
     input   enb;
     input   [15:0] u;  // ufix16_En19
     output  signed [15:0] sin_2_pi_u;  // sfix16_En14
    
    
     reg [15:0] u_1;  // ufix16_En19
     wire [15:0] CastU16En16_out1;  // ufix16_En16
     wire LTEp50_relop1;
     wire [15:0] Amp50_out1;  // ufix16_En16
     wire [15:0] QuadHandle1_out1;  // ufix16_En16 
     wire LTEp25_relop1;
     wire [15:0] p50mA_out1;  // ufix16_En16
     wire [15:0] QuadHandle2_out1;  // ufix16_En16
     reg signed [15:0] Look_Up_Table_out1;  // sfix16_En14
     wire signed [16:0] Negate_cast;  // sfix17_En14
     wire signed [15:0] Negate_out1;  // sfix16_En14
     wire signed [15:0] SignCorrected_out1;  // sfix16_En14
     reg signed [15:0] Sine_out1;  // sfix16_En14 
     reg signed [15:0] Look_Up_Table_dout_low_1;  // sfix16_En14
     reg [5:0] Look_Up_Table_k_1;  // ufix6
     reg [31:0] Look_Up_Table_f_1;  // ufix32_En31
     reg signed [15:0] Look_Up_Table_t_0_0_1 [0:32];  // sfix16_En14 [33]
     reg [15:0] Look_Up_Table_div_temp_1;  // ufix16
     reg [46:0] Look_Up_Table_div_temp_0_1;  // ufix47_En31
     reg [15:0] Look_Up_Table_cast_1;  // ufix16_En16
     reg [31:0] Look_Up_Table_mul_temp_1;  // ufix32_En32
     reg [15:0] Look_Up_Table_sub_temp_1;  // ufix16_En16
     reg signed [48:0] Look_Up_Table_add_cast_2;  // sfix49_En45
     reg signed [32:0] Look_Up_Table_cast_0_1;  // sfix33_En31
     reg signed [15:0] Look_Up_Table_sub_temp_0_1;  // sfix16_En14
     reg signed [48:0] Look_Up_Table_mul_temp_0_1;  // sfix49_En45
     reg signed [47:0] Look_Up_Table_add_cast_0_1;  // sfix48_En45
     reg signed [48:0] Look_Up_Table_add_cast_1_1;  // sfix49_En45
     reg signed [48:0] Look_Up_Table_add_temp_1;  // sfix49_En45
    
    
     always @(posedge clk)
       begin : in_0_pipe_process
         if (reset_n == 1'b0) begin
           u_1 <= 16'b0000000000000000;
         end
         else if (enb) begin
           u_1 <= u;
         end
       end
    
    
    
     // <S7>/CastU16En16
     assign CastU16En16_out1 = u_1[15:3];
    
    
    
     // <S7>/LTEp50
     assign LTEp50_relop1 = (CastU16En16_out1 <= 16'b1000000000000000 ? 1'b1 :
                 1'b0);
    
    
    
     // <S7>/Amp50
     assign Amp50_out1 = CastU16En16_out1 - 32768;
    
    
    
     // <S7>/QuadHandle1
     assign QuadHandle1_out1 = (LTEp50_relop1 == 1'b0 ? Amp50_out1 :
                 CastU16En16_out1);
    
    
    
     // <S7>/LTEp25
     assign LTEp25_relop1 = (QuadHandle1_out1 <= 16'b0100000000000000 ? 1'b1 :
                 1'b0);
    
    
    
     // <S7>/p50mA
     assign p50mA_out1 = 32768 - QuadHandle1_out1;
    
    
    
     // <S7>/QuadHandle2
     assign QuadHandle2_out1 = (LTEp25_relop1 == 1'b0 ? p50mA_out1 :
                 QuadHandle1_out1);
    
    
    
     // <S6>/Look-Up Table
     always @(QuadHandle2_out1) begin
       Look_Up_Table_t_0_0_1[0] = 16'sb0000000000000000;
       Look_Up_Table_t_0_0_1[1] = 16'sb0000001100100100;
       Look_Up_Table_t_0_0_1[2] = 16'sb0000011001000110;
       Look_Up_Table_t_0_0_1[3] = 16'sb0000100101100100;
       Look_Up_Table_t_0_0_1[4] = 16'sb0000110001111100;
       Look_Up_Table_t_0_0_1[5] = 16'sb0000111110001101;
       Look_Up_Table_t_0_0_1[6] = 16'sb0001001010010100;
       Look_Up_Table_t_0_0_1[7] = 16'sb0001010110010000;
       Look_Up_Table_t_0_0_1[8] = 16'sb0001100001111110;
       Look_Up_Table_t_0_0_1[9] = 16'sb0001101101011101;
       Look_Up_Table_t_0_0_1[10] = 16'sb0001111000101011;
       Look_Up_Table_t_0_0_1[11] = 16'sb0010000011100111;
       Look_Up_Table_t_0_0_1[12] = 16'sb0010001110001110;
       Look_Up_Table_t_0_0_1[13] = 16'sb0010011000100000;
       Look_Up_Table_t_0_0_1[14] = 16'sb0010100010011010;
       Look_Up_Table_t_0_0_1[15] = 16'sb0010101011111011;
       Look_Up_Table_t_0_0_1[16] = 16'sb0010110101000001;
       Look_Up_Table_t_0_0_1[17] = 16'sb0010111101101100;
       Look_Up_Table_t_0_0_1[18] = 16'sb0011000101111001;
       Look_Up_Table_t_0_0_1[19] = 16'sb0011001101101000;
       Look_Up_Table_t_0_0_1[20] = 16'sb0011010100110111;
       Look_Up_Table_t_0_0_1[21] = 16'sb0011011011100101;
       Look_Up_Table_t_0_0_1[22] = 16'sb0011100001110001;
       Look_Up_Table_t_0_0_1[23] = 16'sb0011100111011011;
       Look_Up_Table_t_0_0_1[24] = 16'sb0011101100100001;
       Look_Up_Table_t_0_0_1[25] = 16'sb0011110001000010;
       Look_Up_Table_t_0_0_1[26] = 16'sb0011110100111111;
       Look_Up_Table_t_0_0_1[27] = 16'sb0011111000010101;
       Look_Up_Table_t_0_0_1[28] = 16'sb0011111011000101;
       Look_Up_Table_t_0_0_1[29] = 16'sb0011111101001111;
       Look_Up_Table_t_0_0_1[30] = 16'sb0011111110110001;
       Look_Up_Table_t_0_0_1[31] = 16'sb0011111111101100;
       Look_Up_Table_t_0_0_1[32] = 16'sb0100000000000000;
       if (QuadHandle2_out1 <= 16'b0000000000000000) begin
         Look_Up_Table_k_1 = 6'b000000;
       end
       else if (QuadHandle2_out1 >= 16'b0100000000000000) begin
         Look_Up_Table_k_1 = 6'b100000;
       end
       else begin
         Look_Up_Table_div_temp_1 = QuadHandle2_out1 / 512;
         Look_Up_Table_k_1 = Look_Up_Table_div_temp_1[5:0];
       end
       if ((QuadHandle2_out1 <= 16'b0000000000000000) || (QuadHandle2_out1 >= 16'b0100000000000000)) begin
         Look_Up_Table_f_1 = 32'b00000000000000000000000000000000;
       end
       else begin
         Look_Up_Table_cast_1 = 16'b0000000000000000;
         // CSD Encoding (512) : 1000000000; Cost (Adders) = 0
         Look_Up_Table_mul_temp_1 = {Look_Up_Table_cast_1, 9'b000000000};
         Look_Up_Table_sub_temp_1 = QuadHandle2_out1 - Look_Up_Table_mul_temp_1[31:16];
         Look_Up_Table_div_temp_0_1 = ({Look_Up_Table_sub_temp_1, 31'b0000000000000000000000000000000}) / 512;
         Look_Up_Table_f_1 = Look_Up_Table_div_temp_0_1[31:0];
       end
       Look_Up_Table_dout_low_1 = Look_Up_Table_t_0_0_1[Look_Up_Table_k_1];
       if (Look_Up_Table_k_1 == 6'b100000) begin
       end
       else begin
         Look_Up_Table_k_1 = Look_Up_Table_k_1 + 1;
       end
       Look_Up_Table_add_cast_2 = {{2{Look_Up_Table_dout_low_1[15]}}, {Look_Up_Table_dout_low_1, 31'b0000000000000000000000000000000}};
       Look_Up_Table_cast_0_1 = Look_Up_Table_f_1;
       Look_Up_Table_sub_temp_0_1 = Look_Up_Table_t_0_0_1[Look_Up_Table_k_1] - Look_Up_Table_dout_low_1;
       Look_Up_Table_mul_temp_0_1 = Look_Up_Table_cast_0_1 * Look_Up_Table_sub_temp_0_1;
       Look_Up_Table_add_cast_0_1 = Look_Up_Table_mul_temp_0_1[47:0];
       Look_Up_Table_add_cast_1_1 = {Look_Up_Table_add_cast_0_1[47], Look_Up_Table_add_cast_0_1};
       Look_Up_Table_add_temp_1 = Look_Up_Table_add_cast_2 + Look_Up_Table_add_cast_1_1;
       Look_Up_Table_out1 = Look_Up_Table_add_temp_1[46:31];
     end
    
    
    
     // <S7>/Negate
     assign Negate_cast =  - ({Look_Up_Table_out1[15], Look_Up_Table_out1});
     assign Negate_out1 = Negate_cast[15:0];
    
    
    
     // <S7>/SignCorrected
     assign SignCorrected_out1 = (LTEp50_relop1 == 1'b0 ? Negate_out1 :
                 Look_Up_Table_out1);
    
    
    
     always @(posedge clk)
       begin : out_0_pipe_process
         if (reset_n == 1'b0) begin
           Sine_out1 <= 16'sb0000000000000000;
         end
         else if (enb) begin
           Sine_out1 <= SignCorrected_out1;
         end
       end
    
    
    
     assign sin_2_pi_u = Sine_out1;
    
    endmodule  // Sine
    

     

    Я тут вижу 2 регистра, входной - по которому защелкиваются данные и выходной, по которому посчитанные данные защелкиваются.

    Между ними идет какая-то асинхронщина. Меня смущает вот эта строчка always @(QuadHandle2_out1) . Причем там есть еще счетчик - т.е. по идее это должен быть регистр-защелка для счетчика.

    Причем синтезатор показывает, что код может работать на частоте в почти 84 МГц. И защелок в проекте нет вообще. Хотя все-таки остается ощущение, что если будут всякие температурные скачки, то возможно появление метастабильного состояния выходного регистра.

    Можно ли использовать данный код в проекте?

  4. Спасибо за разъяснения, des00, но моя совесть должна быть чиста, ибо проект будет использоваться и на альтере и на ксайлинксе и не хотелось бы полагаться на САПРы чипов заморских...

  5. Увы, saturation стоит осознанно. То что синтезом будут добавляться новые регистры - знал, но то, что это очень сильно исправит тайминги - нет. Буду иметь в виду, хотя по всей видимости придется все дописывать ручками.

  6. Ну хотелось бы 1 регистр на входе, 1 после умножения, 1 на выходе у вычитания и 1 на выходе блока по насыщению. Как то это не по феншую, что 3 регистра конвейера просто на входе, какой смысл тогда делать конвейеризацию, если остальная часть дизайна утянет значение тактовой вниз. Или я что-то много требую от этого САПР? :blush:

  7. `timescale 1 ns / 1 ns
    
    module Calc_X4
             (
              clk,
              reset_n,
              clk_enable,
              In1,
              ce_out,
              Out1
             );
    
    
     input   clk;
     input   reset_n;
     input   clk_enable;
     input   signed [15:0] In1;  // sfix16_En10
     output  ce_out;
     output  signed [15:0] Out1;  // sfix16_En10
    
    
     wire enb;
     reg signed [15:0] in_0_pipe_reg [0:2];  // sfix16 [3]
     wire signed [15:0] in_0_pipe_reg_next [0:2];  // sfix16_En10 [3]
     wire signed [15:0] In1_1;  // sfix16_En10
     wire signed [31:0] Gain4_mul_temp;  // sfix32_En24
     wire signed [15:0] Gain4_out1;  // sfix16_En10
     wire signed [15:0] Add6_out1;  // sfix16_En10
     wire signed [15:0] Saturation4_out1;  // sfix16_En10
     reg signed [15:0] Saturation4_out1_1;  // sfix16_En10
    
    
     assign enb = clk_enable;
    
     always @(posedge clk)
       begin : in_0_pipe_process
         if (reset_n == 1'b0) begin
           in_0_pipe_reg[0] <= 16'sb0000000000000000;
           in_0_pipe_reg[1] <= 16'sb0000000000000000;
           in_0_pipe_reg[2] <= 16'sb0000000000000000;
         end
         else if (enb) begin
           in_0_pipe_reg[0] <= in_0_pipe_reg_next[0];
           in_0_pipe_reg[1] <= in_0_pipe_reg_next[1];
           in_0_pipe_reg[2] <= in_0_pipe_reg_next[2];
         end
       end
    
     assign In1_1 = in_0_pipe_reg[2];
     assign in_0_pipe_reg_next[0] = In1;
     assign in_0_pipe_reg_next[1] = in_0_pipe_reg[0];
     assign in_0_pipe_reg_next[2] = in_0_pipe_reg[1];
    
    
    
     assign Gain4_mul_temp = 21105 * In1_1;
     assign Gain4_out1 = Gain4_mul_temp[29:14];
    
    
    
     assign Add6_out1 = 10222 - Gain4_out1;
    
    
    
     assign Saturation4_out1 = (Add6_out1 > 16'sb0100110000000000 ? 16'sb0100110000000000 :
                 (Add6_out1 < 16'sb1011010000000000 ? 16'sb1011010000000000 :
                 Add6_out1));
    
    
    
     always @(posedge clk)
       begin : out_0_pipe_process
         if (reset_n == 1'b0) begin
           Saturation4_out1_1 <= 16'sb0000000000000000;
         end
         else if (enb) begin
           Saturation4_out1_1 <= Saturation4_out1;
         end
       end
    
    
    
     assign Out1 = Saturation4_out1_1;
    
     assign ce_out = clk_enable;
    
    endmodule  // Calc_X4

     

     

    что-то не то...

     

     

    в модели delays блоков не ставил, поставил distributed pipelining в on, input pipieline - 3, output pipeline - 1

  8. Еще вопрос - что то не получается у меня сделать конвеиеризацию дизайна. Я нашел в свойствах только HDL Block Properties и там есть Input pipeline и output pipeline, а также включение distributed pipelining. Но что-то не помогает. Подскажите, куда копать?

  9. а вот еще вопрос - у меня получилось так, что длина слова меньше, чем длина дробной части - это глюк или фича? может я что-то недопонимаю, или прога мне намекает, что надо увеличить ширину слова?

  10. Все-таки остался висеть следующий вопрос:

     

    Вот я сделал модель, прогнал симуляцию, перевел все в fixed-point, прогнал симуляцию, сравнил результаты. Теперь я генерю hdl код. Он у меня делается как wire, без регистров. Если вставить туда блок delay z^-1 то выходной график сдвигается на 2 единицы времени относительно модель без блока delay и отбрасываются биты дробной части из-за чего график становится угловатым. HDL код вообще не генерится. Что я делаю не так?

  11. Я раньше игрался с кордиком в матлабе и увидел реализацию тригонометрической функции в верилоге - да, это кордик. Круто же!

    Описание блоков нашел в справке матлаба. Вообщем, вопросы пока что кончились.

    Крутая штука этот hdl coder...

  12. Я посмотрел вот это видео https://www.mathworks.com/videos/introducin...link-81554.html и вроде разобрался

    Получил ошибку в 3*10^-3, что для меня приемлимо при ширине слова в 16 бит.

    А есть ли документик, где есть описание всех блоков HDL кодера, а то на сайте матворкса утверждают, что у меня нет на него лицензии :rolleyes:

    И все таки интересует реализация синуса и корня у HDL кодера в матлабе - это сделано на кордике и есть прям незашифрованный верилог или вхдл файл для установки экземпляра ядра?

     

  13. RHnd, спасибо, что-то я завис. Можно еще тупо построить 2 графика из командной строки матлаба - с помощью plot & hold on

     

    syoma, круто! А минимальные и максимальные значения мы задаем на входе первого элемента схемы или это делается где-то в свойствах системы? А где посмотреть про то, как добавлять задержки?(имеется ввиду ступени конвейера, регистровые). И получается есть какой-то другой способ перегона модели в hdl код, кроме code -> hdl code -> generate hdl? Я еще тут немного поигрался, получается все блоки типа синуса, корня и так далее этот генератор делает как экземпляры, а разработчик уже дальше вставляет свой код ядра для вычисления этих величин?

     

    Fat Robot, насчет соизмеримости - мне кажется, что вся эта игра с разрядностями для выбора оптимальной погрешности на выходе все-таки очень сильно облегчается с помощью симулинка... Кучу раз переписывать hdl код и симулировать, прикидывать что да как - реально с ним экономится время...

  14. Добрый день.

     

    Требуется совет на следующую задачу.

     

    У меня есть алгоритм расчета нескольких величин(алгоритм управления), где присутствуют синусы, косинусы, возведения в квадрат, извлечение корня, деление, а также функции заданные поточечно в том числе двух аргументов...

    Мне нужно сделать этот алгоритм в плис, и ксайлинкса и альтеры. Использовать ядра библиотек производителей - лучше не надо...

    Для начала мне нужно определиться fixed point или float point арифметику мне использовать. Я изначально выбрал первое, так как если самому все писать с нуля, то очень много времени пройдет.

    Потом стал вопрос об ошибке расчета величин из-за погрешности перевода fixed-point из float. Для этих целей я хочу использовать матлаб, чтобы если что в некоторых местах изменять разрядность данных, дабы оптимизировать проект по площади. Допустим я делаю простую модель в симулинке, где есть из источника ramp и она расходится на 2 ветки - double и fixed и умножается на коэффициент усиления. Как мне найти ошибку между результатом double и fixed?

     

  15. Добрый день.

     

    Разрабатываю один вычислитель и использую fixed point представление числа.

    Допустим у нас формат 1 бит - знак, 2 бита - целая часть, 15 бит дробная...

    если умножать a * b и они положительны, то все нормально.

    Но если к примеру либо a, либо b отрицательно, то получается неверный результат

    При умножении мы в голове держим fixed-point, а сами умножаем как integer.

    Но ведь -1 в integer это 18'b1_11_1111_1111_1111_111

    а в fixed point это 18'b1_11_0000_0000_0000_000

    Подскажите, пожалуйста, как смухлевать в этой ситуации и получить правильный результат?

     

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

  16. спасибо!

     

    еще вопрос:

     

    вот я сгенерил корку, добавил из вкладки utility axi external master connector и slave connector, дальше я во вкладке ports делаю порты внешними, у меня они автоматом генерятся как S00_S_AXI_AWADDR_pin, к примеру. А как сделать так, чтоб автоматом генерилось S00_AXI_AWADDR, можно конечно ручками переделать, но что-то многовато править...?

  17. Добрый день.

     

    Нужно сгенерить систему из axi интерконнекта и мастеров, слейвов. В общих чертах как это сделать я разобрался. Но дьявол кроется в деталях)))

    Подскажите, пожалуйста, следующие вещи:

     

    1) Порекомендуйте вменяемую доку на сей САПР, что то на сайте хилых найти ничего не могу

     

    2) При генерации пустого проекта нам предлагается выбрать микроблейз. В дальнейшем я его выкидываю. Стоит ли выкидывать clock generator из проекта и просто сделать вход тактовый внешним?

    Выкидывать блок сброса, я так понимаю, стоит?

     

     

  18. Добрый день!

     

    Имеется связка десериализатора SN65LV1224B и ПЛИС.

    Данные от десериализатора идут по тактовому сигналу, восстановленному из последовательной шины.

    Сейчас у меня тактовый сигнал модуля плисины в 5 раз больше, чем восстановленный тактовый сигнал десериализатора. Так я отлавливаю фронт клока десериализатора и беру данные.

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

    Не будет ли так, что эти триггеры уйдут в метастабильное состояние, если тактовый сигнал десериализатора будет нестабильным?

     

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