In general the differences in output between Simulink and generated code could be explained by differences in numerical precision or a range of other factors such as:
- Different compiler optimizations
- Statement ordering
- Run-time libraries
To read more about this please refer to the following article:
However, as you mention in this case, the difference appears more significant than can be explained by those sources. The issue may be due to major and minor time steps in simulating the model. You may be sampling the output during the minor time step of the Simulation loop instead of sampling the output right after the major time step. Please refer to the following image from a visualization of the 'Simulation Loop' I am describing. Please note the difference between the minor and major time steps as can be seen on the vertical line of the loop.
To get the correct output you would want to sample the output after the 'mdlOutputs' step but before the 'mdlUpdate' step in the 'Simulation loop'.
For more details about how the Simulink Engine functions please refer to the following article:
As you noted there is a slight difference in behavior between the ODE1 and ODE4 solvers. This is due to the differences in the usage of minor time steps between the two solvers.
When using the ODE1 solver Simulink uses Euler's method so there is no need for minor time steps. When using the ODE4 solver Simulink uses Runge-Kutta's method thus minor time steps are needed in order to compute the slope at different points in the interval. Since the ODE1 solver does not use minor time steps you do not need to worry about accidently sampling the output during a minor timestep. With the ODE4 solver you need to ensure you are sampling at the right location, between the 'mdlOutputs' and 'mdlUpdate' steps.