// Fractional-N Frequency Synthesizer // MASH Simulation // www.holmea.demon.co.uk #include #include #include const double PI = 3.14159265358979323846; #define MODULO (1<<16) // Modulus of overflowing accumulators #define SEQLEN (4*MODULO) // Length of sequence (2* for F even; 4* for F odd) // Time represented as multiples of the carrier (VCO) period double tREF[SEQLEN]; // Position of REF edge int tVCO[SEQLEN]; // Position of divided VCO edge (always an integer) // Sigma-delta sequence char Delta[SEQLEN]; // Parameters const int N=17, F=1; class MASH { int q[4]; // Latch outputs int c[4][4]; // Carry flip flops public: MASH() // Constructor { // Initial values memset(c, 0, sizeof c); q[0] = 1; q[1] = 0; q[2] = 0; q[3] = 0; // Fill flip-flops for (int i=0; i<4; i++) Clock(); } int Clock() { int d[4]; // Adder output / latch data input // Carry flip-flops c[3][3] = c[3][2]; c[3][2] = c[3][1]; c[3][1] = c[3][0]; c[2][2] = c[2][1]; c[2][1] = c[2][0]; c[1][1] = c[1][0]; // Adders d[0] = (q[0]+ F) % MODULO; d[1] = (q[1]+d[0]) % MODULO; d[2] = (q[2]+d[1]) % MODULO; d[3] = (q[3]+d[2]) % MODULO; // Carries c[0][0] = (q[0]+ F) / MODULO; c[1][0] = (q[1]+d[0]) / MODULO; c[2][0] = (q[2]+d[1]) / MODULO; c[3][0] = (q[3]+d[2]) / MODULO; // Latch for (int i=0; i<4; i++) q[i] = d[i]; return c[0][0] + c[1][0] - c[1][1] + c[2][0] - 2*c[2][1] + c[2][2] + c[3][0] - 3*c[3][1] + 3*c[3][2] - c[3][3] ; } bool operator != (MASH& m) // Debug { return memcmp(this, &m, sizeof(MASH)) != 0; } }; void main() { MASH m; for (int i=0; i