Skip to content

PLL Reconfig

agg23 edited this page Sep 19, 2022 · 1 revision

PLL reconfiguration is commonly used for switching between NTSC and PAL display modes for various hardware. For some reason there is very little documenation available on how this process works, so I will detail it as much as possible here.

NOTE: For the Analogue Pocket, it seems that the source clock of 74.25MHz makes reconfiguration not work quite right due to 2 undocumented variables being changed (demonstrated on the SNES port). I would recommend producing separate PAL binaries rather than using the reconfig

Setup

The initial setup of the PLL reconfiguration component is very simple.

  1. Open the PLL MegaWizard, and under "Settings" turn on "PLL Auto Reset" and "Enable dynamic reconfiguration of PLL". This adds the necessary ports for connection to the config instance
  2. Generate a PLL config instance via the IP tool
  3. Connect the reconfig_to_pll and reconfig_from_pll lines to your PLL
mf_pllcfg pll_cfg (
      .mgmt_clk(clk_74a),
      .mgmt_reset(0),
      .mgmt_waitrequest(cfg_waitrequest),
      .mgmt_read(0),
      .mgmt_readdata(),
      .mgmt_write(cfg_write),
      .mgmt_address(cfg_address),
      .mgmt_writedata(cfg_data),
      .reconfig_to_pll(reconfig_to_pll),
      .reconfig_from_pll(reconfig_from_pll)
  );

Changing clocks

The above instructions were very simple, but it doesn't actually tell you anything about how to change the clock speeds. Intel's documentation gives you some basics, but doesn't actually tell you how to find the numbers you're looking for.

  1. Take a snapshot of your current internal pll.v file, where the altera_pll component is instantiated, after you turned on "Enable dynamic reconfiguration" above
  2. Use the MegaWizard to change your PLL to your PAL or other clock variant
  3. Look at the difference between the original pll.v and your new pll.v
  4. Enter each of the changed set of values into Intel's PLL Reconfiguration Calculator. You want to make sure all of the settings match (bypass, odd divider) in addition to the lo and hi counts for each M, N, or C counter node.
    • If you have a prst or a ph_mux_prst value change, you are unlucky. I cannot find any documentation about these properties whatsoever, and doing the reconfig without them seems to minorly offset the PLL clocks
  5. Each value you generate from the calculator must be sent to the PLL reconfig component via a state machine, one after another. Create your state machine, starting with an address 0x0 write of 0x0 to set the reconfig mode to waitrequest, and ending with writing 0x0 to address 0x2 to indicate the reconfiguration should start
if (!cfg_waitrequest) begin
      if (state) state <= state + 1'd1;
      case (state)
        1: begin
          // Set mode to waitrequest
          cfg_address <= 0;
          cfg_data <= 0;
          cfg_write <= 1;
        end
        3: begin
          // Set fractional division
          cfg_address <= 7;
          // NTSC: 425936216
          //   Mem: 85.90908MHz
          //   Main: 21.47727MHz
          //   Vid: 10.7386MHz
          // PAL:
          //   Mem: 85.12548MHz
          //   Main: 21.28137MHz
          //   Vid: 10.64069MHz
          cfg_data <= PAL ? 737741702 : 425937894;
          cfg_write <= 1;
        end
        5: begin
          // Set counter C0
          cfg_address <= 'h5;
          cfg_data <= PAL ? 32'h000404 : 32'h020403;
          cfg_write <= 1;
        end
        13: begin
          // Set counter M
          cfg_address <= 'h4;
          cfg_data <= PAL ? 32'h20504 : 32'h00404;
          cfg_write <= 1;
        end
        15: begin
          // Begin fractional PLL reconfig
          cfg_address <= 2;
          cfg_data <= 0;
          cfg_write <= 1;
        end
      endcase
    end
  end
Clone this wiki locally