Tengo un problema al escribir el 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 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.
Desafortunadamente, 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í también es 'desconocido' (por desconocido me refiero a 'x').
¿Es posible crear un circuito de retroalimentación entre ciertos componentes en el diseño de HDL? ¿Cómo puede hacerse esto? ¿Debo tratar de 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
No veo ningún código que restablezca K0
, K1
y K2
, hasta que se use el estado de carga.
Esto significa que en el arranque, estos registros tienen X
valor.
Por lo tanto, las salidas de u_mult1
, u_mult2
y u_mult3
tienen X
valor.
Por lo tanto, la salida de u_adder1
, u_adder2
y u_adder3
obtiene X
valor.
Por lo tanto, en el siguiente borde del reloj, sum_out_old
obtiene X
valor. Probablemente al mismo tiempo, las variables K se cargan con sus valores desde las entradas del módulo. Pero es muy tarde. Dado que sum_out
se calcula a partir de sum_out_old
, se convierte en X
, y sum_out_old
queda atrapada en el X
estado.
La manera fácil de resolver esto es tener K0
, K1
y K2
restablecer a 0 cuando rst_n
se afirma (bajo), pero debe considerar si esto es correcto para su situación.
Para la simulación, debe restablecer sus valores a un estado conocido al principio. Puede usar la línea de reinicio para esto, pero esto termina sintetizado como lo menciona The Photon (no suele ser un problema)
Otra forma de hacerlo es establecer el valor cuando codifica el registro, como:
reg [N-1:0]K0 = 8'b00000000;
reg [N-1:0]K1 = 8'b00000000;
reg [N-1:0]K2 = 8'b00000000;
Dependiendo de sus herramientas, esto puede funcionar o no (yo uso las herramientas de Xilinx), y en realidad puede terminar siendo sintetizado (es decir, los registros se configuran durante la carga del flujo de bits en el FPGA), pero pruébelo y háganoslo saber.
el fotón
zdun8
el fotón
reset
? Eso parece que hiciste todo bien --- si puedes, comparte tu código y podemos buscar errores tipográficos u otros tipos de problemas.el fotón
reg reg1 (.CLK(c), .RST(r), .I(x), .O(y))
), no hay forma de que pueda estar seguro de esta parte de su código.