_Ivan_
-
Постов
617 -
Зарегистрирован
-
Посещение
Сообщения, опубликованные _Ivan_
-
-
Добрый день.
Подскажите, пожалуйста, а в какой сапр лучше всего отлаживать блоки вычислителя с фиксированной точкой? Видел связку матлаб + моделсим точно, в исиме представление числа с фиксированной точкой не нашел. Еще видел что можно копать в сторону VHDL, но все написано на верилоге. А какие есть еще варианты? Можно конечно попробовать написать что-то свое на систем верилоге, но пока ищу готовые решения
-
огромное спасибо!
-
ого, даже так!
а где почитать про временные переменные?
что-то я с таким сталкиваюсь впервые
вообщем получается что код работать будет, но нестабильно?
-
if (Look_Up_Table_k_1 == 6'b100000) begin end else begin Look_Up_Table_k_1 = Look_Up_Table_k_1 + 1; end
-
Добрый день.
Интересует следующий вопрос.
Вот есть код, сгенерируемый симулинком из модели.Это просто 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 МГц. И защелок в проекте нет вообще. Хотя все-таки остается ощущение, что если будут всякие температурные скачки, то возможно появление метастабильного состояния выходного регистра.
Можно ли использовать данный код в проекте?
-
Спасибо за разъяснения, des00, но моя совесть должна быть чиста, ибо проект будет использоваться и на альтере и на ксайлинксе и не хотелось бы полагаться на САПРы чипов заморских...
-
Увы, saturation стоит осознанно. То что синтезом будут добавляться новые регистры - знал, но то, что это очень сильно исправит тайминги - нет. Буду иметь в виду, хотя по всей видимости придется все дописывать ручками.
-
Ну хотелось бы 1 регистр на входе, 1 после умножения, 1 на выходе у вычитания и 1 на выходе блока по насыщению. Как то это не по феншую, что 3 регистра конвейера просто на входе, какой смысл тогда делать конвейеризацию, если остальная часть дизайна утянет значение тактовой вниз. Или я что-то много требую от этого САПР?
-
`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
-
Еще вопрос - что то не получается у меня сделать конвеиеризацию дизайна. Я нашел в свойствах только HDL Block Properties и там есть Input pipeline и output pipeline, а также включение distributed pipelining. Но что-то не помогает. Подскажите, куда копать?
-
-
а вот еще вопрос - у меня получилось так, что длина слова меньше, чем длина дробной части - это глюк или фича? может я что-то недопонимаю, или прога мне намекает, что надо увеличить ширину слова?
-
Все-таки остался висеть следующий вопрос:
Вот я сделал модель, прогнал симуляцию, перевел все в fixed-point, прогнал симуляцию, сравнил результаты. Теперь я генерю hdl код. Он у меня делается как wire, без регистров. Если вставить туда блок delay z^-1 то выходной график сдвигается на 2 единицы времени относительно модель без блока delay и отбрасываются биты дробной части из-за чего график становится угловатым. HDL код вообще не генерится. Что я делаю не так?
-
Я раньше игрался с кордиком в матлабе и увидел реализацию тригонометрической функции в верилоге - да, это кордик. Круто же!
Описание блоков нашел в справке матлаба. Вообщем, вопросы пока что кончились.
Крутая штука этот hdl coder...
-
Я посмотрел вот это видео https://www.mathworks.com/videos/introducin...link-81554.html и вроде разобрался
Получил ошибку в 3*10^-3, что для меня приемлимо при ширине слова в 16 бит.
А есть ли документик, где есть описание всех блоков HDL кодера, а то на сайте матворкса утверждают, что у меня нет на него лицензии :rolleyes:
И все таки интересует реализация синуса и корня у HDL кодера в матлабе - это сделано на кордике и есть прям незашифрованный верилог или вхдл файл для установки экземпляра ядра?
-
RHnd, спасибо, что-то я завис. Можно еще тупо построить 2 графика из командной строки матлаба - с помощью plot & hold on
syoma, круто! А минимальные и максимальные значения мы задаем на входе первого элемента схемы или это делается где-то в свойствах системы? А где посмотреть про то, как добавлять задержки?(имеется ввиду ступени конвейера, регистровые). И получается есть какой-то другой способ перегона модели в hdl код, кроме code -> hdl code -> generate hdl? Я еще тут немного поигрался, получается все блоки типа синуса, корня и так далее этот генератор делает как экземпляры, а разработчик уже дальше вставляет свой код ядра для вычисления этих величин?
Fat Robot, насчет соизмеримости - мне кажется, что вся эта игра с разрядностями для выбора оптимальной погрешности на выходе все-таки очень сильно облегчается с помощью симулинка... Кучу раз переписывать hdl код и симулировать, прикидывать что да как - реально с ним экономится время...
-
Добрый день.
Требуется совет на следующую задачу.
У меня есть алгоритм расчета нескольких величин(алгоритм управления), где присутствуют синусы, косинусы, возведения в квадрат, извлечение корня, деление, а также функции заданные поточечно в том числе двух аргументов...
Мне нужно сделать этот алгоритм в плис, и ксайлинкса и альтеры. Использовать ядра библиотек производителей - лучше не надо...
Для начала мне нужно определиться fixed point или float point арифметику мне использовать. Я изначально выбрал первое, так как если самому все писать с нуля, то очень много времени пройдет.
Потом стал вопрос об ошибке расчета величин из-за погрешности перевода fixed-point из float. Для этих целей я хочу использовать матлаб, чтобы если что в некоторых местах изменять разрядность данных, дабы оптимизировать проект по площади. Допустим я делаю простую модель в симулинке, где есть из источника ramp и она расходится на 2 ветки - double и fixed и умножается на коэффициент усиления. Как мне найти ошибку между результатом double и fixed?
-
спасибо за советы!
-
Добрый день.
Разрабатываю один вычислитель и использую 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
Подскажите, пожалуйста, как смухлевать в этой ситуации и получить правильный результат?
блин... правильно сформулированный вопрос дает некоторую часть ответа, попробую инвертировать дробную часть...
-
спасибо!
еще вопрос:
вот я сгенерил корку, добавил из вкладки utility axi external master connector и slave connector, дальше я во вкладке ports делаю порты внешними, у меня они автоматом генерятся как S00_S_AXI_AWADDR_pin, к примеру. А как сделать так, чтоб автоматом генерилось S00_AXI_AWADDR, можно конечно ручками переделать, но что-то многовато править...?
-
Добрый день.
Нужно сгенерить систему из axi интерконнекта и мастеров, слейвов. В общих чертах как это сделать я разобрался. Но дьявол кроется в деталях)))
Подскажите, пожалуйста, следующие вещи:
1) Порекомендуйте вменяемую доку на сей САПР, что то на сайте хилых найти ничего не могу
2) При генерации пустого проекта нам предлагается выбрать микроблейз. В дальнейшем я его выкидываю. Стоит ли выкидывать clock generator из проекта и просто сделать вход тактовый внешним?
Выкидывать блок сброса, я так понимаю, стоит?
-
Добрый день!
Имеется связка десериализатора SN65LV1224B и ПЛИС.
Данные от десериализатора идут по тактовому сигналу, восстановленному из последовательной шины.
Сейчас у меня тактовый сигнал модуля плисины в 5 раз больше, чем восстановленный тактовый сигнал десериализатора. Так я отлавливаю фронт клока десериализатора и беру данные.
Плата разведена так, что восстановленный тактовый сигнал подается на обычную ножку плисины. Вопрос таков: надежнее ли мне подать тактовый сигнал на такой же вход триггера плисины, чтоб защелкнуть эти данные?
Не будет ли так, что эти триггеры уйдут в метастабильное состояние, если тактовый сигнал десериализатора будет нестабильным?
-
Господа, спасибо большое!
Отсутствие опыта - оно такое. Потратил на эту фичу около недели)))
-
так получается что запись тупо изменяет биты из 1 в 0, а из 0 в 1 нет?
Так зачем же нужны ПЛИС
в Работаем с ПЛИС, области применения, выбор
Опубликовано · Пожаловаться
Вся фигня в том, что ТС смотрит на радиолюбительские сайты и находит там какие-то поделки вроде помигать светодиодом на плис или какой-нибудь марсоход. Все это песочница. Но когда он пойдет на работу где реально применяются плисы - он столкнется с реальностью - частотами в несколько сотен МГц, задержками вычисления определенного алгоритма и скоростями обработки данных в несколько десятков Гбит в сек.
У меня у самого был диплом - разработка PCI-E интерфейса и теоретическая скорость могла доходить до 20 Гбит в сек. Мало какому процессору это под силу. Поэтому не стоит недооценивать ПЛИС. На светлую сторону силы переходи ты! :cheers: