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

    

alex1985

Участник
  • Публикаций

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

  • Посещение

Репутация

0 Обычный

Информация о alex1985

  • Звание
    Частый гость

Посетители профиля

1 102 просмотра профиля
  1. Странно, вроде бы 23 пин - это dedicated clock..
  2. Доброго всем времени суток! Делал проект на Cyclone III в Quartus 9.1, затем потребовалось перенести его на Cyclone IV EP4CE6E22I7, сейчас работаю в Quartus 15.0.0. pll добавлял из IP catalog, все настройки ставил по дефолту: один входной клок: 8МГц и два выходных: 200МГц и 32МГц. На вкладке "Operation mode" выбрал "Normal mode". И вроде все нормально, камни очень похожие, но при компиляции появляется варнинг такого содержания: RTL симуляция выглядит так: Сигнал, поступающий на вход (inclk0 8МГц) объявлен как Global Clock и определен на ногу 23. Тактирование идет с микроконтроллера. В констрейнах объявляю клоки следующим образом: create_clock -name clk -period 8MHz [get_ports {clk}] create_generated_clock -name clk_200MHz -source [get_ports {clk}] -multiply_by 25 [get_nets {pll_ena_inst1|pll1|altpll_component|auto_generated|wire_pll1_clk[0]}] create_generated_clock -name clk_adc -source [get_ports {clk}] -multiply_by 4 [get_nets {pll_ena_inst1|pll1|altpll_component|auto_generated|wire_pll1_clk[1]}] Прошу совета - насколько критичен этот варнинг? Заранее спасибо!
  3. Прошу прощения :laughing: Но за советы все равно спасибо!
  4. Иосиф Григорьевич, спасибо! Все ясно и понятно! Тему можно считать закрытой.
  5. Спасибо всем, кто принимал участие в обсуждении! Все получилось, остался один вопрос: при компиляции проекта выдается ограничение по частоте в 200Мгц: Где именно ограничивается минимальный период и можно ли это поправить?
  6. Спасибо за подробный и развернутый ответ! :biggrin: Компилятор ARM v5
  7. Спасибо! А можно уложить эти данные по определенному адресу? Или придется пробегать весь hex в поисках этих строк?
  8. Доброго времени суток! Камень: stm32f407. Нужно сохранить информацию о версии прошивки в самом файле прошивки (hex), желательно по указанному адресу, чтобы ее потом можно было извлечь. Возможно ли это? Информация о версии определяется в тексте программы (на данный момент просто дефайном). Заранее спасибо!
  9. _Anatoliy, спасибо большое! :beer: Посмотрю обязательно!
  10. Вобщем посмотрел Time-report простейшей цепи и сделал вывод: setup и hold отстают друг от друга на один такт. В моем случае - та же простейшая цепь с одним клоком, просто данные захватываются с задержкой в 6 тактов. Поставил hold-time на 1 меньше setup и варнинги пропали. Осталось легкое недопонимание относительно hold( set_multicycle_path -from {pid:pid1|err_reg[*]} -to {pid:pid1|I_limits_reg[*]*} -hold -end 6 set_multicycle_path -from {pid:pid1|err_reg[*]} -to {pid:pid1|I_limits_reg[*]*} -setup -end 7
  11. Задам вопрос по другому. Есть 1 общий клок и цепочка D-триггеров: В момент прихода импульса на первый триггер (1) в регистры заносятся некоторые данные, например err_reg[]. Далее с ними проводятся манипуляции (сложение/умножение/сравнение) и к моменту поступления импульса на шестой триггер (6) берется результат (F_limits_reg[]). Периодичность поступления импульсов на цепочку триггеров намного больше 6. Как правильно описать данный констрейн с помощью set_multicycle_path? Делаю так: set_multicycle_path -from {pid:pid1|err_reg[*]} -to {pid:pid1|F_limits_reg[*]*} -setup -end 6 На картинке снизу изображения временного отчета по setup(слева) и hold(справа). По setup все более-менее понятно: мы указываем когда защелкиваются данные, соответственно сами данные должны прибыть ДО Latch-фронта. А вот с hold не знаю что делать, смысл его для меня пока загадка. Из каких соображений определяется констрейн для hold?
  12. Спасибо за оперативные ответы! Извиняюсь, что пишу так поздно. Проблема была в невыставленном set_multicycle_path. Я почему то полагал, что TimeQuest чуть умнее и сам додумается, т.к. вычисления разнесены по цепочке D-триггеров, но как выяснилось - нужно все прописывать самому. Пришлось добавить целую портянку кода: set_multicycle_path -from {pid:pid1|err_reg[*]} -to {pid:pid1|F_reg[*]} -setup -end 4 set_multicycle_path -from {pid:pid1|Ki_reg[*]} -to {pid:pid1|F_reg[*]} -setup -end 4 set_multicycle_path -from {pid:pid1|err_reg[*]} -to {pid:pid1|F_limits_reg[0]_OTERM3} -setup -end 4 set_multicycle_path -from {pid:pid1|Ki_reg[*]} -to {pid:pid1|F_limits_reg[0]_OTERM3} -setup -end 4 set_multicycle_path -from {pid:pid1|err_reg[*]} -to {pid:pid1|F_limits_reg[0]_OTERM5} -setup -end 4 set_multicycle_path -from {pid:pid1|Ki_reg[*]} -to {pid:pid1|F_limits_reg[0]_OTERM5} -setup -end 4 set_multicycle_path -from {pid:pid1|err_reg[*]} -to {pid:pid1|F_reg[24]_OTERM217} -setup -end 4 set_multicycle_path -from {pid:pid1|Ki_reg[*]} -to {pid:pid1|F_reg[24]_OTERM217} -setup -end 4 set_multicycle_path -from {pid:pid1|err_reg[*]} -to {pid:pid1|F_reg[*]_OTERM235} -setup -end 4 set_multicycle_path -from {pid:pid1|Ki_reg[*]} -to {pid:pid1|F_reg[*]_OTERM235} -setup -end 4 set_multicycle_path -from {pid:pid1|err_reg[*]} -to {pid:pid1|F_limits_reg[0]_OTERM7_OTERM153_OTERM223_OTERM251} -setup -end 4 set_multicycle_path -from {pid:pid1|Ki_reg[*]} -to {pid:pid1|F_limits_reg[0]_OTERM7_OTERM153_OTERM223_OTERM251} -setup -end 4 set_multicycle_path -from {pid:pid1|err_reg[*]} -to {pid:pid1|F_limits_reg[0]_OTERM7_OTERM155_OTERM221_OTERM239_OTERM299} -setup -end 4 set_multicycle_path -from {pid:pid1|Ki_reg[*]} -to {pid:pid1|F_limits_reg[0]_OTERM7_OTERM155_OTERM221_OTERM239_OTERM299} -setup -end 4 set_multicycle_path -from {pid:pid1|err_reg[*]} -to {pid:pid1|F_reg[*]_OTERM281} -setup -end 4 set_multicycle_path -from {pid:pid1|Ki_reg[*]} -to {pid:pid1|F_reg[*]_OTERM281} -setup -end 4 set_multicycle_path -from {pid:pid1|err_reg[*]} -to {pid:pid1|F_reg[*]_OTERM287} -setup -end 4 set_multicycle_path -from {pid:pid1|Ki_reg[*]} -to {pid:pid1|F_reg[*]_OTERM287} -setup -end 4 set_multicycle_path -from {pid:pid1|err_reg[*]} -to {pid:pid1|F_reg[*]_OTERM291} -setup -end 4 set_multicycle_path -from {pid:pid1|Ki_reg[*]} -to {pid:pid1|F_reg[*]_OTERM291} -setup -end 4 set_multicycle_path -from {pid:pid1|err_reg[*]} -to {pid:pid1|F_reg[*]_OTERM295} -setup -end 4 set_multicycle_path -from {pid:pid1|Ki_reg[*]} -to {pid:pid1|F_reg[*]_OTERM295} -setup -end 4 set_multicycle_path -from {pid:pid1|err_reg[*]} -to {pid:pid1|I_limits_reg[0]_OTERM13_OTERM215_OTERM233_OTERM275} -setup -end 4 set_multicycle_path -from {pid:pid1|Ki_reg[*]} -to {pid:pid1|I_limits_reg[0]_OTERM13_OTERM215_OTERM233_OTERM275} -setup -end 4 set_multicycle_path -from {pid:pid1|err_reg[*]} -to {pid:pid1|F_limits_reg[0]_OTERM7_OTERM149_OTERM227_OTERM247_OTERM307} -setup -end 4 set_multicycle_path -from {pid:pid1|Ki_reg[*]} -to {pid:pid1|F_limits_reg[0]_OTERM7_OTERM149_OTERM227_OTERM247_OTERM307} -setup -end 4 set_multicycle_path -from {pid:pid1|err_reg[*]} -to {pid:pid1|F_limits_reg[0]_OTERM7_OTERM149_OTERM227_OTERM245_OTERM303} -setup -end 4 set_multicycle_path -from {pid:pid1|Ki_reg[*]} -to {pid:pid1|F_limits_reg[0]_OTERM7_OTERM149_OTERM227_OTERM245_OTERM303} -setup -end 4 set_multicycle_path -from {pid:pid1|err_reg[*]} -to {pid:pid1|F_reg[12]_OTERM325} -setup -end 4 set_multicycle_path -from {pid:pid1|Ki_reg[*]} -to {pid:pid1|F_reg[12]_OTERM325} -setup -end 4 set_multicycle_path -from {pid:pid1|err_reg[*]} -to {pid:pid1|I_limits_reg[0]_OTERM13_OTERM215_OTERM233_OTERM273} -setup -end 4 set_multicycle_path -from {pid:pid1|Ki_reg[*]} -to {pid:pid1|I_limits_reg[0]_OTERM13_OTERM215_OTERM233_OTERM273} -setup -end 4 Ситуация выправилась, но осталась куча слаков по Hold, вот один из них: Если я правильно понимаю, то Hold time (th) - это время, которое сигнал должен удерживаться после фронта clk приёмника. Как понимать эту диаграмму? Данные (Data Arrival) пришли раньше фронта Latch clock, что не так?
  13. Доброго дня всем! Есть модуль ПИ-регулятора, проект собирается на cyclone III, таймквест ругается, выдает слаки. Код: module pid ( input clk, input use_pid, //Если 1 - включается ПИД-регулятор, иначе выдаем pwm_cur = pwm_fixed input [24:0] pwm_fixed, //Фиксированное значение ШИМ (используется при use_pid=0) input start_pulse, //Импульс начала вычислений input [11:0] ADC_REF, //АЦП уставки, max: 4096 (12 bit) input [11:0] ADC_FAKT, //АЦП фактическое, max: 4096 (12 bit) input [15:0] Ki, //Интегральный коэффициент input [15:0] Kp, //Пропорциональный коэффициент input [24:0] pwm_min, //Минимальная граница ШИМ input [24:0] pwm_max, //Макчимальная граница ШИМ output reg [24:0] pwm_cur, //Выходное значение ШИМ output reg is_pwm_max, //Если 1 - то ШИМ максимальный output end_pulse //Импульс окончания вычислений ); reg signed [25:0] I_reg; reg signed [26:0] F_reg; reg signed [24:0] I_prev_reg; reg [24:0] pwm_fixed_reg; reg [1:0] F_limits_reg; reg [1:0] I_limits_reg; reg [11:0] adc_ref_reg; reg [11:0] adc_fakt_reg; reg signed [12:0] err_reg; reg [9:0] Kp_reg; reg [9:0] Ki_reg; initial begin I_prev_reg = 25'd1000; is_pwm_max = 0; pwm_cur = 0; end wire [1:0] w_F_limits; wire [1:0] w_I_limits; wire signed [25:0] w_I; wire signed [23:0] w_P; wire signed [26:0] w_F; wire signed [12:0] w_err; wire w_start_pulse2; wire w_start_pulse3; wire w_start_pulse4; wire w_start_pulse5; wire w_start_pulse6; //--------------------------------- // PID-calculating //--------------------------------- assign w_err =$signed({1'b0, ADC_REF}) - $signed({1'b0, ADC_FAKT}); //max: 13 bit assign w_I = use_pid? ($signed({1'b0, Ki_reg}) * err_reg + I_prev_reg) : ($signed({1'b0, pwm_fixed_reg})); //max: (10+1) * 13 + 25 = 26 bit assign w_P = $signed({1'b0, Kp_reg}) * err_reg; //max: (10+1) * 13 = 24 bit assign w_F = use_pid? (w_I + w_P) : ($signed({1'b0, pwm_fixed_reg})); //max: 26 + 24 = 27 bit; assign w_F_limits[0] = (w_F < $signed({1'b0, pwm_min}))? 1'b1 : 1'b0; assign w_F_limits[1] = (w_F > $signed({1'b0, pwm_max}))? 1'b1 : 1'b0; assign w_I_limits[0] = (w_I < $signed({1'b0, pwm_min}))? 1'b1 : 1'b0; assign w_I_limits[1] = (w_I > $signed({1'b0, pwm_max}))? 1'b1 : 1'b0; //============================================ delay delay1(.in(start_pulse), .clk(clk), .out(w_start_pulse2)); delay delay2(.in(w_start_pulse2), .clk(clk), .out(w_start_pulse3)); delay delay3(.in(w_start_pulse3), .clk(clk), .out(w_start_pulse4)); delay delay4(.in(w_start_pulse4), .clk(clk), .out(w_start_pulse5)); delay delay5(.in(w_start_pulse5), .clk(clk), .out(w_start_pulse6)); delay delay6(.in(w_start_pulse6), .clk(clk), .out(end_pulse)); //============================================ always @ (posedge clk) begin //======================================== // Начало вычислений, захватываем входные данные //======================================== if (start_pulse) begin Ki_reg = Ki[9:0]; Kp_reg = Kp[9:0]; err_reg <= w_err; pwm_fixed_reg <= pwm_fixed; end //======================================== // Даем 3 такта на вычисления, помещаем результат в регистры //======================================== else if (w_start_pulse4) begin I_reg <= w_I; F_reg <= w_F; I_limits_reg <= w_I_limits; F_limits_reg <= w_F_limits; end //======================================== // Выдаем результат, учитывая ограничения //======================================== else if (w_start_pulse5) begin //Ограничиваем выходное воздействие case (F_limits_reg) 2'b01: begin pwm_cur <= pwm_min; is_pwm_max <= 0; end 2'b10: begin pwm_cur <= pwm_max; is_pwm_max <= 1; end default: begin pwm_cur <= F_reg[24:0]; is_pwm_max <= 0; end endcase //Ограничиваем интегральную составляющую case (I_limits_reg) 2'b01: I_prev_reg <= pwm_min; 2'b10: I_prev_reg <= pwm_max; default: I_prev_reg <= I_reg[24:0]; endcase end end //============================================ endmodule Модуль delay: module delay #(parameter WIDTH = 1) ( input [WIDTH-1:0] in, input clk, output reg [WIDTH-1:0] out ); always @(posedge clk) out <= in; endmodule Идея такова: в момент прихода стартового импульса (start_pulse) происходит захват входных значений в регистры, цепочка из элементов delay производит задержку входного сигнала на 6 тактов для того, чтобы вся эта "колбаса" успела посчитаться к моменту выдачи импульса завершения (end_pulse). Таймквест выдает ошибки: Но регистр err_reg захватывается на 3 такта раньше чем производится вычисление F_reg, неужели 3 такта недостаточно для умножения? Файл констрейнов: derive_clock_uncertainty create_clock -name clk -period 36.1MHz [get_ports {clk}] create_generated_clock -name clk_216MHz -source [get_ports {clk}] -multiply_by 6 [get_nets {pll_ena_inst1|pll1|altpll_component|auto_generated|wire_pll1_clk[0]}] create_generated_clock -name clk_adc -source [get_ports {clk}] -divide_by 17 -multiply_by 15 [get_nets {pll_ena_inst1|pll1|altpll_component|auto_generated|wire_pll1_clk[1]}] set_false_path -from pll_ena_inst1|pll1|altpll_component|auto_generated|pll1|clk[1] -to adc_inst:adc_inst1|sync:sync_adc|sync[0] Какие констрейны прописать для устранения ошибок? Заранее спасибо!
  14. Спасибо за замечание! Но значение I_prev_reg, а значит и интегральная составляющая (w_I) у меня ограничивается максимальным и минимальным значениями (out_max и out_min), которые имеют разрядность 16 бит, так что криминала быть не должно. Не совсем понял фразу "щелкает каждый такт", но мысль уловил. Переписал немного добавив регистр (flag): reg flag; always @ (posedge clk) begin //-------------------------------- // Gets I and F values //-------------------------------- if (ena_pulse) begin I_reg <= w_I; F_reg <= w_F; I_limits_reg <= w_I_limits; F_limits_reg <= w_F_limits; flag <= 1'b1; end //-------------------------------- // Integral and out limitation //-------------------------------- else if (flag) begin case (F_limits_reg) 2'b01: out <= out_min; 2'b10: out <= out_max; default: out <= F_reg; endcase case (I_limits_reg) 2'b01: I_prev_reg <= out_min; 2'b10: I_prev_reg <= out_max; default: I_prev_reg <= I_reg; endcase flag <= 1'b0; end end В чем вообще разница между стэйт-машиной и регистром в данном случае? Что предпочтительнее использовать? Результат симуляции в обоих случаях одинаковый.