Severson-Group / AMDC-Firmware

Embedded system code (C and Verilog) which runs the AMDC Hardware
http://docs.amdc.dev/firmware
BSD 3-Clause "New" or "Revised" License
30 stars 5 forks source link

Add diff_equation folder #315

Open lzhao224 opened 12 months ago

lzhao224 commented 12 months ago

This is an ip core that supports rk4 diff equations.

There are two provided versions of the diff solver -- Floating Point and Integer.

The floating point uses 32 bit IEEE floating point standard to represent the input and output. It is easier to interact because the floating point can represent a large range of values and it is an industry-standard format. Since it is only 32 bits, it has less precision than the 64 bit integer system. ( When adding a very small value with a large value, the small value diminishes because it can not be represented in the larger values' exponent, such as adding 10 with .000000001 would result in a 10) It is also more difficult to meet timing because it instantiates more FP adders and multipliers. (18,000 ns setup time violation)

The integer system uses 64 bit integer with a customized exponent to represent the input and output. It still cannot meet the 200 MHz clock requirement. (7,700 ns setup time violation). It has better precision than the 32 bit floating point system. However, it does not protect the user from overflow. (If the input is already the maximum value, the output cannot be greater than that because the input and output shares the same exponent) It is also more difficult to interact with. Please see the comment in solver_rk4_fp.sv for more detailed explanations.

Both methods do not meet the 200 MHz timing requirement. There are two approaches to solving this problem.

  1. Use a slower clock to operate the solver. This step requires changes to the step size(currently is 10 ns), which could potential make the simulation less in accurate because the value is not monitored and updated frequently enough. On the other hand, this could increase the accuracy of the model because STEP x dy_dt is directly proportional to the STEP size. Therefore, the issue of adding-a-small-value-with-a-large-value issue could be mitigated.
  2. Change the solver to multi-cycle operations, which means that the modules still run at a relatively fast clock but the process is pipelined. Further research is needed to have an accurate result.

Example

Parameters:

parameters

True result from Simulink(1ms simulation):

matlab_true_graph

Floating point

fp_system_wave From the above graph, we see that there is a period where i is constant ( the last wave in the chart). This is because the 32 bit floating point cannot handle some very small values. If the change is small, this algorithm might not be able to represent the change over a long period of time. The predicted i at the end of the wave is 3.1836, which is close to the simulation result 3.1868.

Integer

Integer_system_wave In the above simulation, we give 0x0FFF FFFF FFFF FFFF as the input. If we assume this input is 1 volt, then the output can be interpreted by output/input x input_value(1). If the output is 0x32AE 3D2F BF17 D85C at the end of the simulation, then the final current after 1ms is 0x32AE 3D2F BF17 D85C/ 0x0FFF FFFF FFFF FFFF = 3.16753882075. There seem to be a lose of accuracy in this method as well. However, we see that this method is able to produce a change even if the change is small. (There is no discontinuity in the last wave--i)