Tengo un problema con la escritura del código Verilog HDL. Quiero diseñar un controlador PID simple en FPGA. Estoy usando la familia Cyclone II. Quiero retroalimentar mi valor de salida como una entrada en una etapa previa de cálculos. La ecuación se ve así: u (n) = u (n-1) + x (x se calcula correctamente), así que creé un registro para guardar el valor de salida y lo conecté a una etapa anterior en mi diseño.
Lamentablemente, esta solución no funciona cuando simulo esto. Obtengo un valor 'desconocido' en el registro en el que estoy guardando el valor de salida y el valor de salida en sí mismo también es 'desconocido' (por desconocido quiero decir 'x') .
¿Es posible crear un circuito de retroalimentación entre ciertos componentes en el diseño HDL? ¿Cómo puede hacerse esto? ¿Debo intentar resolver este problema haciendo los cálculos paso a paso en un FSM?
EDITAR: Este es mi código según lo solicitado
Módulo PID
module pid(clk,rst_n,Kp_in, Kd_in, Ki_in,temp_data_in,setpoint,pwm_out);
parameter N = 8;
parameter M = 16;
input clk;
input rst_n;
input [N-1:0]temp_data_in;
input [N-1:0]setpoint;
input [N-1:0]Kp_in;
input [N-1:0]Kd_in;
input [N-1:0]Ki_in;
output [N-1:0]pwm_out;
wire clk;
wire rst_n;
reg [N-1:0]temp_data_reg;
reg [N-1:0]setpoint_reg;
reg [N-1:0]pwm_out_reg;
localparam [1:0] idle = 2'b00, load = 2'b01, run= 2'b10;
localparam k = 2;
reg [1:0] state_reg, state_next;
always@(posedge clk, negedge rst_n) begin
if(!rst_n) begin
state_reg <= idle;
end else
state_reg <= state_next;
end
reg sum_out_old_reg_en;
reg [N-1:0]K0;
reg [N-1:0]K1;
reg [N-1:0]K2;
wire [N-1:0] ex0;
wire [N-1:0] ex1;
wire [N-1:0] ex2;
wire [2*N-1:0] out0;
wire [2*N-1:0] out1;
wire [2*N-1:0] out2;
wire [2*N-1:0] sum1;
wire [2*N-1:0] sum2;
wire [2*N-1:0] sum_out_old;
wire [2*N-1:0] sum_out;
register e0(clk,rst_n,(temp_data_in-setpoint),ex0);
register e1(clk,rst_n,ex0,ex1);
register e2(clk,rst_n,ex1,ex2);
mult u_mult1(ex0,K0,out0);
mult u_mult2(ex1,K1,out1);
mult u_mult3(ex2,K2,out2);
adder u_adder1(out0,out1,sum1);
adder u_adder2(out2,sum_out_old,sum2);
adder u_adder3(sum1,sum2,sum_out);
register16b u_old(clk,rst_n,sum_out,sum_out_old);
always@(posedge clk) begin
state_next = state_reg;
case(state_reg)
idle: begin
state_next = load;
end
load: begin
K0 = Kp_in + Kd_in + Ki_in;
K1 = -Kp_in + (-2)*Kd_in;
K2 = Kd_in;
state_next = run;
end
run: begin
state_next = run;
end
endcase
end
endmodule