📄 fg_ctrl.psm
字号:
JUMP Z, inc_carry
STORE sA, (sB) ;store incremented digit value
JUMP edit_display ;increment task complete
inc_carry: LOAD sA, 00 ;current digit rolls over to zero
STORE sA, (sB) ;store zero digit value
COMPARE sB, BCD_digit8 ;check if working on 100MHz digit
JUMP Z, set_max_value
ADD sB, 01 ;increment pointer to next most significant digit
JUMP inc_digit ;increment next digit up.
;
set_max_value: FETCH sB, edit_digit_pointer ;Must fill digits from insert to MS-Digit with 999...
LOAD sA, 09
fill_max: STORE sA, (sB)
COMPARE sB, BCD_digit8 ;check if filled to 100MHz digit
JUMP Z, edit_display
ADD sB, 01 ;fill next higher digit
JUMP fill_max
;
end_edit_mode: CALL wait_switch_release ;wait for end of switch press
JUMP move_mode ;then go to move cursor mode
;
;
; Routine to poll the press switch with de-bounce delay and wait for it to be
; released. Any rotation inputs detected by the interrupt
; service routine are cleared before returning.
;
wait_switch_release: CALL delay_20ms ;delay to aid switch de-bounce
INPUT s0, rotary_port ;read rotary encoder
TEST s0, rotary_press ;test if button is still being pressed
JUMP NZ, wait_switch_release
LOAD s0, 00 ;clear flag indicating any rotary events
STORE s0, rotary_status
RETURN
;
;**************************************************************************************
; Compute DDS control words from currently display frequency value
;**************************************************************************************
;
; This routine reads the current BCD value and converts it into a 32-bit binary
; integer. It then multiplies it by a 48-bit scaling factor (see notes in the
; constants section above) to form a full precision 80-bit product.
;
; From this product the 32-bit DDS control word must be extracted. For frequencies of
; 50MHz or above the DDS control word is formed by shifting the product left by 2 places
; (multiply by 4) and then keeping only the most significant 32-bits (4 bytes).
;
; Also for frequencies of 50MHz and above, there is no additional division performed
; after the DCM which multiplies frequency and reduces the jitter. Therefore the DDS_scaling
; word will be set to zero and the output of the DCM will divide by 2.
;
; Freq DDS control word DDS Scaling Synthesized Frequency
; of Phase Accumulator
;
; 50MHz 08000000 00 6.25MHz
; 100MHz 10000000 00 12.50MHz
;
; You will notice that for frequencies of 50MHz and above, the upper byte of the
; DDS control word is 08 hex or greater. In other words, bit3 and/or bit4 of that byte
; are High (bits 27 and/or 28 of the full 32-bit word). This is the indication that
; the control words are complete.
;
; For frequencies below 50MHz an additional process is required. The reason for this
; becomes clear if we think about the lowest frequency of 1Hz. In that case the 80-bit
; product is the same as the 48-bit scaling constant 00000000ABCC77118462. Once this
; has been multiplied by 4 (shifted left 2 places) it becomes 00000002AF31DC461188 and the
; most significant 32-bits are only 00000002 hex. If we put this back into the basic
; equations for the phase accumulator we find that the output frequency of the phase
; accumulator would be
;
; Fout = M x clk x N / (2^p)
;
; = 8 x 200MHz x 2 / (2^32) = 0.745 Hz
;
; There are two important observations we can make. Firstly we have lost accuracy because
; the resolution of the DDS control word has become too granular at low amplitudes.
; Secondly this would never even work because the frequency synthesized by the phase
; accumulator would be 0.745/8 = 0.0931 Hz which is seriously slow and a way below the
; frequency at which the DCM can even work.
;
; The solution to both of these issues is to ensure that the DDS control word is always
; formed to be in the range that would result in an output of 50MHz or above. In other
; words to keep the phase accumulator output in the range 6.25MHz to 12.5MHz such that
; the DCM is able to work and only has to deal with one octave of input variation. This
; can be achieved by shifting the 80-bit product left more times until bits 27 and 28
; of the most significant 32-bits are not zero.
;
; For each shift left the synthesized frequency is being doubled and therefore the final
; output from the DCM must be divided by a further factor of 2. This is achieved using
; a multiplexer which is guided to select the appropriate output from a simple binary
; counter.
;
; Returning to the example of 1Hz, the 80-bit product will be shifted left by the default
; 2 places (multiplied by 4), but will then need to be shifted left by a further 26 places
; which is like multiplying by 67108864 (04000000 hex).
;
; 00000000ABCC77118462
; x 4
; --------------------
; 00000002AF31DC461188
;
;
; x 04000000
; --------------------
; 0ABCC771184620000000
;
; So now the DDS control word is 0ABCC771 (180143985 decimal)and the frequency synthesized
; by the phase accumulator will be....
;
; Fpa = clk x N / (2^p) = 200MHz x 180143985 / (2^32) = 8388608Hz
;
; The DCM will multiply this by a factor of 16 to give 134217728Hz and this will then
; be divided by the counter of which the 26th bit selected (26 decimal = 1A hex).
;
; Fout = Fpa x 16 / (2^(D+1)) = 8388608Hz x 16 / (2^(26+1)) = 0.99999999947 Hz
;
; 'D' is the DDS Scaling factor
; Note that bit0 of a counter is a clock division by 2 and hence the 'D+1'
;
; Clearly this implementation style has provided much greater accuracy and enables
; the DCM to work for all desired frequencies.
;
;
; Freq DDS control word DDS Scaling Synthesized Frequency
; of Phase Accumulator
;
; 100 MHz 10000000 00 12.50MHz
; 50 MHz 08000000 00 6.25MHz
; 25 MHz 08000000 01 6.25MHz
; 12.5 MHz 08000000 02 6.25MHz
;
; 1Hz 0ABCC771 1A 8.388608 MHz
;
;
;
; In order to ensure the DCM is always provided with a frequency in an acceptable
; range, the value of absolute zero is never implemented and instead just a very low
; frequency is produced.
; 6.25MHz x 16 / (2^31+1) = 0.0233 Hz
; which is 1 cycle every 43 seconds and that is pretty slow :-)
;
;
;
;
compute_DDS_words: CALL BCD_to_integer ;convert BCD display value to 32-bit value
CALL scale_frequency ;80-bit product of 32-bit frequency x 48-bit scaling value
FETCH sA, product9 ;read the upper part of the 80-bit product into [sA,s9,s8,s7,s6,s5,s4]
FETCH s9, product8 ; The least significant 24-bits of the 80-bit product will never
FETCH s8, product7 ; be used for frequencies above 1Hz.
FETCH s7, product6 ;The final 32-bit DDS control word will be formed in
FETCH s6, product5 ; [sA,s9,s8,s7]
FETCH s5, product4
FETCH s4, product3
CALL shift80_left ;multiply DDS control word by 4 to achieve default value
CALL shift80_left
LOAD sB, 00 ;default scaling factor is 2 (select counter bit0)
normalise_loop: TEST sA, 18 ;Test bits 27 and 28 of 32-bit DDS control word
JUMP NZ, store_DDS_words ;DDS control word is normalised to above 50MHz output
CALL shift80_left ;multiply DDS control word by 2
ADD sB, 01 ;Divide final value by 2 to compensate
COMPARE sB, 1F ;Test for maximum division factor
JUMP NZ, normalise_loop
LOAD sA, 08 ;Set for minimum frequency
LOAD s9, 00 ; with phase accumulator set to generate 6.25MHz
LOAD s8, 00
LOAD s7, 00
store_DDS_words: STORE s7, DDS_control0 ;store local copy of control word
STORE s8, DDS_control1 ;store local copy of control word
STORE s9, DDS_control2 ;store local copy of control word
STORE sA, DDS_control3 ;store local copy of control word
STORE sB, DDS_scaling
CALL drive_DDS_words ;output control words to DDS circuit
RETURN
;
shift80_left: SL0 s4 ;shift (most of the) 80-bit value in
SLA s5 ; [sA,s9,s8,s7,s6,s5,s4] left 1 place
SLA s6
SLA s7
SLA s8
SLA s9
SLA sA
RETURN
;
;**************************************************************************************
; Set DDS control words
;**************************************************************************************
;
; Because multiple ports are used, the idea is to update all of them in
; rapid succession to avoid too much disturbance in the frequency synthesis.
;
; dds_control_word should be supplied in register set [sA,s9,s8,s7]
; dds_scaling_word should be supplied in register s6.
;
drive_DDS_words: FETCH s7, DDS_control0
FETCH s8, DDS_control1
FETCH s9, DDS_control2
FETCH sA, DDS_control3
FETCH s6, DDS_scaling
OUTPUT s7, DDS_control0_port
OUTPUT s8, DDS_control1_port
OUTPUT s9, DDS_control2_port
OUTPUT sA, DDS_control3_port
OUTPUT s6, DDS_scaling_port
RETURN
;
;
;**************************************************************************************
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -