реклама на сайте
подробности

 
 
> П-И-регулятор
Sprite
сообщение Jun 11 2018, 08:25
Сообщение #1


Частый гость
**

Группа: Участник
Сообщений: 173
Регистрация: 11-05-08
Пользователь №: 37 414



Добрый день всем!
Пишу ПИ-регулятор, требуется профессиональная критика) Камень - cyclone III, использовано 4 аппаратных умножителя.
Код:
Код
module pid
(
    input     clk,
    input     ena,
    input     signed [15:0] in_ustavka,
    input     signed [15:0] in_fakt,
    input     signed [15:0] Ki,
    input     signed [15:0] Kp,
    input     signed [15:0] out_min,
    input     signed [15:0] out_max,
    output     reg signed [31:0] out
);
    reg signed [31:0] I_reg;
    reg signed [31:0] F_reg;
    reg signed [31:0] I_prev_reg;
    reg [1:0] F_limits_reg;
    reg [1:0] I_limits_reg;
    reg    [1:0] ena_reg;

    reg    state;
    
    initial
    begin
        ena_reg = 2'b00;
        I_prev_reg = 31'd1000;
        out = 0;
        state = 1'b0;
    end
    
    wire ena_risingEdge;
    wire [1:0] w_F_limits;
    wire [1:0] w_I_limits;
    wire signed [31:0] w_F;
    wire signed [31:0] w_I;
    wire signed [31:0] w_P;
    wire signed [15:0] w_err;
    

    //---------------------------------
    // Front detector
    //---------------------------------
    always @(posedge clk)
    begin
        ena_reg <= {ena_reg[0], ena};
    end
    assign ena_risingEdge = (ena_reg == 2'b01);

    //---------------------------------
    // PID-calculating
    //---------------------------------
    assign w_err = in_ustavka - in_fakt;
    assign w_I = Ki*w_err + I_prev_reg;
    assign w_P = Kp*w_err;
    assign w_F = w_I + w_P;
    assign w_F_limits[0] = (w_F < out_min)? 1'b1 : 1'b0;
    assign w_F_limits[1] = (w_F > out_max)? 1'b1 : 1'b0;
    assign w_I_limits[0] = (w_I < out_min)? 1'b1 : 1'b0;
    assign w_I_limits[1] = (w_I > out_max)? 1'b1 : 1'b0;
    
    
    always @ (posedge clk)
    begin
        case (state)
        //--------------------------------
        // Gets I and F values
        //--------------------------------
        1'b0:
            if (ena_risingEdge)
                begin
                    I_reg <= w_I;
                    F_reg <= w_F;
                    I_limits_reg <= w_I_limits;
                    F_limits_reg <= w_F_limits;
                    state <= 1'b1;
                end
            else
                state <= 1'b0;
        //--------------------------------
        // Integral and out limitation
        //--------------------------------
        1'b1:
            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                        

                state <= 1'b0;
            end
        //--------------------------------
        default:
            state <= 1'b0;
        endcase
        //--------------------------------
    end

Моделсим:

Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов
nice_vladi
сообщение Jun 12 2018, 05:40
Сообщение #2


Участник
*

Группа: Участник
Сообщений: 53
Регистрация: 7-09-16
Из: Томск
Пользователь №: 93 239



Цитата(Sprite @ Jun 11 2018, 09:25) *
Добрый день всем!
Пишу ПИ-регулятор, требуется профессиональная критика) Камень - cyclone III, использовано 4 аппаратных умножителя.

На профессионала не потяну, НО biggrin.gif

Код
    assign w_I = Ki*w_err + I_prev_reg; // 32 бита = (16 бит * 16 бит) + 32 бита -- возможно переполнение

Всегда дико заморочно следить за разрядностями, но иногда из-за этого все ломается.

А вместо машины на два состояния, которая щелкает каждый такт (если я правильно понял) можно сделать простой однобитный счетчик, который будет по какому-то событию перекидываться 0-1-0-1... мне кажется и лаконичнее и писанины меньше (хотя, наверное, дело религии).

И вместо кейсов на 2-3 состояния красивше писать if-else. Опять же лаконичнее и писанины меньше (но, наверное, это тоже дела религиозные))).
Т.е. получаем вместо:
Код
case (F_limits_reg)
    2'b01:        out <= out_min;
     2'b10:         out <= out_max;
     default:    out <= F_reg;
endcase


Что-то вроде:

Код
    if (F_limits_reg == 2'b01)         out <= out_min;
    else if (F_limits_reg == 2'b10)  out <= out_max;
      else                                     out <= F_reg;





Go to the top of the page
 
+Quote Post
Flip-fl0p
сообщение Jun 12 2018, 05:53
Сообщение #3


В поисках себя...
****

Группа: Свой
Сообщений: 729
Регистрация: 11-06-13
Из: Санкт-Петербург
Пользователь №: 77 140



Цитата(nice_vladi @ Jun 12 2018, 08:40) *
И вместо кейсов на 2-3 состояния красивше писать if-else. Опять же лаконичнее и писанины меньше (но, наверное, это тоже дела религиозные))).
Т.е. получаем вместо:
Код
case (F_limits_reg)
    2'b01:        out <= out_min;
     2'b10:         out <= out_max;
     default:    out <= F_reg;
endcase


Что-то вроде:

Код
    if (F_limits_reg == 2'b01)         out <= out_min;
    else if (F_limits_reg == 2'b10)  out <= out_max;
      else                                     out <= F_reg;


Тут Вы сильно заблуждаетесь.
Во втором случае у вас будет совершенно другая схема синтезироваться, в отличии от case.
Вот тут немного написано про это: https://electronics.stackexchange.com/quest...=google_rich_qa
Go to the top of the page
 
+Quote Post
andrew_b
сообщение Jun 12 2018, 11:00
Сообщение #4


Профессионал
*****

Группа: Свой
Сообщений: 1 975
Регистрация: 30-12-04
Из: Воронеж
Пользователь №: 1 757



Цитата(Flip-fl0p @ Jun 12 2018, 08:53) *
Тут Вы сильно заблуждаетесь.
Во втором случае у вас будет совершенно другая схема синтезироваться, в отличии от case.
Вот тут немного написано про это: https://electronics.stackexchange.com/quest...=google_rich_qa
Сами читали, на что сослались? Всё одно сведётся к логической функции нескольких переменных и ляжет в LUT. Результат будет тот же самый. Соревноваться с оптимизирующим компилятором бессмысленно.
Go to the top of the page
 
+Quote Post
Flip-fl0p
сообщение Jun 12 2018, 18:40
Сообщение #5


В поисках себя...
****

Группа: Свой
Сообщений: 729
Регистрация: 11-06-13
Из: Санкт-Петербург
Пользователь №: 77 140



Цитата(andrew_b @ Jun 12 2018, 14:00) *
Сами читали, на что сослались?

Основной смысл - в картинках rolleyes.gif
Цитата
Результат будет тот же самый. Соревноваться с оптимизирующим компилятором бессмысленно.

Тут Вы правы это я немного поспешил. Тут же не приоритетный шифратор. Эх...
Хотя всё-равно считаю, что описывать через case правильнее, с точки зрения стиля написания. Читается проще.
Go to the top of the page
 
+Quote Post
gin
сообщение Jun 14 2018, 07:56
Сообщение #6


Частый гость
**

Группа: Участник
Сообщений: 183
Регистрация: 17-12-10
Пользователь №: 61 682



Цитата(Flip-fl0p @ Jun 12 2018, 21:40) *
Основной смысл - в картинках rolleyes.gif

Тут Вы правы это я немного поспешил. Тут же не приоритетный шифратор. Эх...
Хотя всё-равно считаю, что описывать через case правильнее, с точки зрения стиля написания. Читается проще.


По поводу описания есть еще один не совсем очевидный момент. Не всегда описание, которое принимается синтезатор, может понять симулятор. Иногда при написании кода приходится помнить, что ModelSim понимает не все конструкции (по крайней мере для VHDL так, не знаю как для Verilog).
Go to the top of the page
 
+Quote Post
andrew_b
сообщение Jun 14 2018, 08:08
Сообщение #7


Профессионал
*****

Группа: Свой
Сообщений: 1 975
Регистрация: 30-12-04
Из: Воронеж
Пользователь №: 1 757



Цитата(gin @ Jun 14 2018, 10:56) *
Иногда при написании кода приходится помнить, что ModelSim понимает не все конструкции (по крайней мере для VHDL так, не знаю как для Verilog).
Я уверен, что вас не затруднит подтвердить слова кодом.
Go to the top of the page
 
+Quote Post
gin
сообщение Jun 14 2018, 08:22
Сообщение #8


Частый гость
**

Группа: Участник
Сообщений: 183
Регистрация: 17-12-10
Пользователь №: 61 682



Цитата(andrew_b @ Jun 14 2018, 11:08) *
Я уверен, что вас не затруднит подтвердить слова кодом.


На память могу ошибиться. но вот как щас помню

объявляем сигнал:

Код
signal cnt : natural range 0 to 5


затем его используем в каком-нить процессе:

Код
if (cnt = cnt'high) then


Квартус это проглатывал, а вот Modelsim ругался.
Версию моделсима щас уже не вспомню


Так же моделсим вот на такую контсрукцию ругается

Код
case? <expression> is
    when <constant_expression> =>
        -- Sequential Statement(s)
    when <constant_expression> =>
        -- Sequential Statement(s)
    when others =>
        -- Sequential Statement(s)
end case?;

Go to the top of the page
 
+Quote Post
andrew_b
сообщение Jun 14 2018, 09:32
Сообщение #9


Профессионал
*****

Группа: Свой
Сообщений: 1 975
Регистрация: 30-12-04
Из: Воронеж
Пользователь №: 1 757



Цитата(gin @ Jun 14 2018, 11:22) *
На память могу ошибиться. но вот как щас помню

объявляем сигнал:

Код
signal cnt : natural range 0 to 5


затем его используем в каком-нить процессе:

Код
if (cnt = cnt'high) then


Квартус это проглатывал, а вот Modelsim ругался.
Я тоже на такое натыкался, но лень было выяснять, Моделсим тут прав или нет. Я просто ввёл новый тип.

Цитата
Так же моделсим вот на такую контсрукцию ругается

Код
case? <expression> is
     when <constant_expression> =>
         -- Sequential Statement(s)
     when <constant_expression> =>
         -- Sequential Statement(s)
     when others =>
         -- Sequential Statement(s)
end case?;
Про vhdl'2008 почти ничего не знаю.
Go to the top of the page
 
+Quote Post
gin
сообщение Jun 14 2018, 13:19
Сообщение #10


Частый гость
**

Группа: Участник
Сообщений: 183
Регистрация: 17-12-10
Пользователь №: 61 682



Цитата(andrew_b @ Jun 14 2018, 12:32) *
Я тоже на такое натыкался, но лень было выяснять, Моделсим тут прав или нет. Я просто ввёл новый тип.

Про vhdl'2008 почти ничего не знаю.


Моделсим его частично поддерживает, по крайней мере в версии 10.2
Там даже отдельный technote есть с описанием того, что и как поддерживается для vhdl2008

Цитата(andrew_b @ Jun 14 2018, 15:09) *
Во-первых, я не вижe там какого-то особого профита.
А кто виноват?
Вот-вот, синтезатор или не полностью его поддерживает. Или может совсем не поддерживать (в случае, если вы пишете код для АСИКа).
А '93 поддерживают все.


В 2008 стандарте есть удобные фишки, тот же список чувствительности процесса можно задать как

Код
process(all)


И case удобно применять для описания приоритетного шифратора. Жизнь упрощает, хотя конечно же и без всего этого можно
Go to the top of the page
 
+Quote Post



Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 28th July 2025 - 11:23
Рейтинг@Mail.ru


Страница сгенерированна за 0.01494 секунд с 7
ELECTRONIX ©2004-2016