Synchronize a software waveform generator
It is not clear to me how you are determining your phase error so there may be issues there, and it also looks like  you are adding the phase correction to the accumulator directly. Consider adding the corrections to the frequency control word instead which would be analogous to a traditional analog PLL such as that shown in the graphic below (with the NCO being the equivalent to a VCO); this would allow the NCO to be an additional integrator in the loop which is necessary to implement a desired second order type 2 PI loop with your use of a PI Loop filter.  If you feed the corrections to the phase accumulator directly, you are treating the NCO as a phase control device instead of a frequency control device.



A type 2 implementation will track a frequency offset with zero error, while a type 1 implementation (which is what would result if the control was fed to the phase accumulator directly) would have an offset that is proportional to the inverse of the loop gain.

For the phase detector implementation, consider using a simple multiplier followed by a low pass filter to remove the double frequency output. (This multiplier can be analog or digital-- in your case since you are dealing with an analog signal an analog multiplier may be simplest. If you can be ensured the duty cycle is 50%, an XOR gate is perfect for this purpose. Otherwise a passive mixer is often a good choice).   The average value will be proportional the phase error with a quadrature offset (so the Loop would therefore lock in quadrature to the input signal).  Care should be taken that the low pass filter simply removes the double frequency component and is not too tight in bandwidth so as to compete with the loop bandwidth (it is preferred to set the loop bandwidth with the loop filter alone). Depending on implementation (see diagrams below) a "Phase/Frequency Detector" may be a preferred choice for the phase detector given that it won't lock to alias frequency offsets. If a multiplier type phase detector is used, the VCO/NCO output must be constrained to a narrow frequency range to avoid such false locks.

Three variants of a PLL approach are shown below. Depending on your need for digital and analog signal types in the rest of your system and programmability of loop dynamics one may be preferred over the other. 







For the last implementation shown (which I think would be simplest) there are plenty of integrated chip solutions out there to make this even simpler. For example this chip: https://www.analog.com/en/products/hmc984.html#product-overview incorporates a phase/frequency detector together with a high range divider. The divider is 14 bits but 18 bits are required to get to 240,000, so the approach in this case would be to "pre-scale" the 12 MHz VCXO output with a divide by 16 to create a 750KHz clock, which would then be divided by 15,000 with this chip. There are many other integrated solutions to consider if you went down this path.