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

 
 
> П-И-регулятор
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



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

 


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


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