我正在尝试编程FPGA来解决一个简单的质量弹簧系统,给定用户定义的初始条件和最终时间值。不幸的是,我只有大约2周的SystemVerilog经验,我的大多数故障排除都是通过将我的代码与在线示例进行比较来完成的,所以如果这里有明显的错误我会道歉。我尝试合成时得到的错误是:超出了循环迭代限制。
我意识到这是因为while
循环具有非静态边界,所以我尝试通过在最后时间添加最大值2来约束它,然后仅检查用户定义的最终时间循环内。不幸的是,这并没有解决问题。我对原因的下一个猜测是我需要将循环连接到时钟边缘。但是,我需要使用阻止分配,因为数学必须按顺序完成,我被告知它们应该在always_comb
中使用。
包含模块的代码,该代码逐个接收用户输入,直到收到所有4个值(m
,k
,x_i
,t_f
) ,然后计算最终位置。
//----------------------------------------------------------------
// math_unit
//
// module to receive button inputs and calculate final position
// Inputs: num_i
// state
// clk
// Outputs: out
//----------------------------------------------------------------
module math_unit (
input logic [5:0] num_i, // input from button board
input logic [2:0] state, // input from state machine 1
input logic clk, // slow clock
output logic [5:0] out // output to 7-seg modules
);
logic [5:0] num; // use num to compensate for active-low button board
assign num = ~num_i;
logic [5:0] m, k, x_i, t_f; // m = mass
// k = spring constant
// x_i = initial position
// t_f = final time
integer x, x_n, v, v_n, t, dt; // x = position
// x_n = next position
// v = velocity
// v_n = next velocity
// t = current time
// dt = time step
always_comb
begin
case (state) // assigns user input to variables depending on state
0: m = num;
1: k = num;
2: x_i = num;
3: t_f = num;
endcase
if (state != 4) out = num; // before all variables are assigned, just display user input
else begin
t = 0; // setting up initial conditions
v = 0;
x = x_i;
// iteration loop for Euler method
while (t <= 2) begin // sets maximum time boundary
if (t <= t_f) begin // checks actual time boundary
v_n = v - (k/m)*x*dt; // next velocity is equal to current velocity plus dv/dt*dt
x_n = x + v*dt; // next position is equal to current position plus dx/dt*dt
x = x_n; // updates variables
v = v_n;
t += 0.1;
end
end
out = x_n;
end
end
endmodule