From 9feb96888b29f46353253db86eb1725c34dc2bb7 Mon Sep 17 00:00:00 2001 From: marqs Date: Wed, 9 Oct 2019 23:58:55 +0300 Subject: [PATCH] fix PLL reference clock switchover logic --- ossc.qsf | 2 +- rtl/pll_2x.ppf | 1 + rtl/pll_2x.v | 48 ++--- rtl/pll_config_default_data.mif | 174 +++++++++++++++++++ rtl/scanconverter.v | 13 +- software/sys_controller/ossc/av_controller.c | 6 + 6 files changed, 220 insertions(+), 24 deletions(-) create mode 100644 rtl/pll_config_default_data.mif diff --git a/ossc.qsf b/ossc.qsf index cc59c9f..533bb81 100644 --- a/ossc.qsf +++ b/ossc.qsf @@ -218,7 +218,7 @@ set_global_assignment -name ENABLE_SIGNALTAP OFF set_global_assignment -name USE_SIGNALTAP_FILE output_files/ossc_la.stp set_global_assignment -name FITTER_EFFORT "AUTO FIT" -set_global_assignment -name SEED 2 +set_global_assignment -name SEED 4 diff --git a/rtl/pll_2x.ppf b/rtl/pll_2x.ppf index df82f86..3d83c85 100644 --- a/rtl/pll_2x.ppf +++ b/rtl/pll_2x.ppf @@ -10,6 +10,7 @@ + diff --git a/rtl/pll_2x.v b/rtl/pll_2x.v index 303d5eb..b84a7be 100644 --- a/rtl/pll_2x.v +++ b/rtl/pll_2x.v @@ -45,6 +45,7 @@ module pll_2x ( scanclk, scanclkena, scandata, + activeclock, c0, c1, locked, @@ -59,6 +60,7 @@ module pll_2x ( input scanclk; input scanclkena; input scandata; + output activeclock; output c0; output c1; output locked; @@ -76,34 +78,36 @@ module pll_2x ( // synopsys translate_on `endif - wire [4:0] sub_wire0; - wire sub_wire3; + wire sub_wire0; + wire [4:0] sub_wire1; wire sub_wire4; wire sub_wire5; - wire sub_wire8 = inclk1; - wire [1:1] sub_wire2 = sub_wire0[1:1]; - wire [0:0] sub_wire1 = sub_wire0[0:0]; - wire c0 = sub_wire1; - wire c1 = sub_wire2; - wire locked = sub_wire3; - wire scandataout = sub_wire4; - wire scandone = sub_wire5; - wire sub_wire6 = inclk0; - wire [1:0] sub_wire7 = {sub_wire8, sub_wire6}; + wire sub_wire6; + wire sub_wire9 = inclk1; + wire activeclock = sub_wire0; + wire [1:1] sub_wire3 = sub_wire1[1:1]; + wire [0:0] sub_wire2 = sub_wire1[0:0]; + wire c0 = sub_wire2; + wire c1 = sub_wire3; + wire locked = sub_wire4; + wire scandataout = sub_wire5; + wire scandone = sub_wire6; + wire sub_wire7 = inclk0; + wire [1:0] sub_wire8 = {sub_wire9, sub_wire7}; altpll altpll_component ( .areset (areset), .clkswitch (clkswitch), .configupdate (configupdate), - .inclk (sub_wire7), + .inclk (sub_wire8), .scanclk (scanclk), .scanclkena (scanclkena), .scandata (scandata), - .clk (sub_wire0), - .locked (sub_wire3), - .scandataout (sub_wire4), - .scandone (sub_wire5), - .activeclock (), + .activeclock (sub_wire0), + .clk (sub_wire1), + .locked (sub_wire4), + .scandataout (sub_wire5), + .scandone (sub_wire6), .clkbad (), .clkena ({6{1'b1}}), .clkloss (), @@ -147,7 +151,7 @@ module pll_2x ( altpll_component.lpm_type = "altpll", altpll_component.operation_mode = "NORMAL", altpll_component.pll_type = "AUTO", - altpll_component.port_activeclock = "PORT_UNUSED", + altpll_component.port_activeclock = "PORT_USED", altpll_component.port_areset = "PORT_USED", altpll_component.port_clkbad0 = "PORT_UNUSED", altpll_component.port_clkbad1 = "PORT_UNUSED", @@ -205,7 +209,7 @@ endmodule // ============================================================ // CNX file retrieval info // ============================================================ -// Retrieval info: PRIVATE: ACTIVECLK_CHECK STRING "0" +// Retrieval info: PRIVATE: ACTIVECLK_CHECK STRING "1" // Retrieval info: PRIVATE: BANDWIDTH STRING "1.000" // Retrieval info: PRIVATE: BANDWIDTH_FEATURE_ENABLED STRING "1" // Retrieval info: PRIVATE: BANDWIDTH_FREQ_UNIT STRING "MHz" @@ -316,7 +320,7 @@ endmodule // Retrieval info: CONSTANT: LPM_TYPE STRING "altpll" // Retrieval info: CONSTANT: OPERATION_MODE STRING "NORMAL" // Retrieval info: CONSTANT: PLL_TYPE STRING "AUTO" -// Retrieval info: CONSTANT: PORT_ACTIVECLOCK STRING "PORT_UNUSED" +// Retrieval info: CONSTANT: PORT_ACTIVECLOCK STRING "PORT_USED" // Retrieval info: CONSTANT: PORT_ARESET STRING "PORT_USED" // Retrieval info: CONSTANT: PORT_CLKBAD0 STRING "PORT_UNUSED" // Retrieval info: CONSTANT: PORT_CLKBAD1 STRING "PORT_UNUSED" @@ -363,6 +367,7 @@ endmodule // Retrieval info: CONSTANT: WIDTH_CLOCK NUMERIC "5" // Retrieval info: CONSTANT: scan_chain_mif_file STRING "pll_2x.hex" // Retrieval info: USED_PORT: @clk 0 0 5 0 OUTPUT_CLK_EXT VCC "@clk[4..0]" +// Retrieval info: USED_PORT: activeclock 0 0 0 0 OUTPUT GND "activeclock" // Retrieval info: USED_PORT: areset 0 0 0 0 INPUT GND "areset" // Retrieval info: USED_PORT: c0 0 0 0 0 OUTPUT_CLK_EXT VCC "c0" // Retrieval info: USED_PORT: c1 0 0 0 0 OUTPUT_CLK_EXT VCC "c1" @@ -384,6 +389,7 @@ endmodule // Retrieval info: CONNECT: @scanclk 0 0 0 0 scanclk 0 0 0 0 // Retrieval info: CONNECT: @scanclkena 0 0 0 0 scanclkena 0 0 0 0 // Retrieval info: CONNECT: @scandata 0 0 0 0 scandata 0 0 0 0 +// Retrieval info: CONNECT: activeclock 0 0 0 0 @activeclock 0 0 0 0 // Retrieval info: CONNECT: c0 0 0 0 0 @clk 0 0 1 0 // Retrieval info: CONNECT: c1 0 0 0 0 @clk 0 0 1 1 // Retrieval info: CONNECT: locked 0 0 0 0 @locked 0 0 0 0 diff --git a/rtl/pll_config_default_data.mif b/rtl/pll_config_default_data.mif new file mode 100644 index 0000000..9f68d5e --- /dev/null +++ b/rtl/pll_config_default_data.mif @@ -0,0 +1,174 @@ +-- Copyright (C) 2017 Intel Corporation. All rights reserved. +-- Your use of Intel Corporation's design tools, logic functions +-- and other software and tools, and its AMPP partner logic +-- functions, and any output files from any of the foregoing +-- (including device programming or simulation files), and any +-- associated documentation or information are expressly subject +-- to the terms and conditions of the Intel Program License +-- Subscription Agreement, the Intel Quartus Prime License Agreement, +-- the Intel FPGA IP License Agreement, or other applicable license +-- agreement, including, without limitation, that your use is for +-- the sole purpose of programming logic devices manufactured by +-- Intel and sold by Intel or its authorized distributors. Please +-- refer to the applicable agreement for further details. + +-- MIF file representing initial state of PLL Scan Chain +-- Device Family: Cyclone IV E +-- Device Part: - +-- Device Speed Grade: 8 +-- PLL Scan Chain: Fast PLL (144 bits) +-- File Name: /home/markus/Code/ossc/rtl/pll_config_default_data.mif +-- Generated: Wed Oct 9 22:20:06 2019 + +WIDTH=1; +DEPTH=144; + +ADDRESS_RADIX=UNS; +DATA_RADIX=UNS; + +CONTENT BEGIN + 0 : 0; -- Reserved Bits = 0 (1 bit(s)) + 1 : 0; -- Reserved Bits = 0 (1 bit(s)) + 2 : 0; -- Loop Filter Capacitance = 0 (2 bit(s)) (Setting 0) + 3 : 0; + 4 : 1; -- Loop Filter Resistance = 27 (5 bit(s)) (Setting 27) + 5 : 1; + 6 : 0; + 7 : 1; + 8 : 1; + 9 : 0; -- VCO Post Scale = 0 (1 bit(s)) (VCO post-scale divider counter value = 2) + 10 : 0; -- Reserved Bits = 0 (5 bit(s)) + 11 : 0; + 12 : 0; + 13 : 0; + 14 : 0; + 15 : 0; -- Charge Pump Current = 1 (3 bit(s)) (Setting 1) + 16 : 0; + 17 : 1; + 18 : 1; -- N counter: Bypass = 1 (1 bit(s)) + 19 : 0; -- N counter: High Count = 0 (8 bit(s)) + 20 : 0; + 21 : 0; + 22 : 0; + 23 : 0; + 24 : 0; + 25 : 0; + 26 : 0; + 27 : 0; -- N counter: Odd Division = 0 (1 bit(s)) + 28 : 0; -- N counter: Low Count = 0 (8 bit(s)) + 29 : 0; + 30 : 0; + 31 : 0; + 32 : 0; + 33 : 0; + 34 : 0; + 35 : 0; + 36 : 0; -- M counter: Bypass = 0 (1 bit(s)) + 37 : 0; -- M counter: High Count = 8 (8 bit(s)) + 38 : 0; + 39 : 0; + 40 : 0; + 41 : 1; + 42 : 0; + 43 : 0; + 44 : 0; + 45 : 0; -- M counter: Odd Division = 0 (1 bit(s)) + 46 : 0; -- M counter: Low Count = 8 (8 bit(s)) + 47 : 0; + 48 : 0; + 49 : 0; + 50 : 1; + 51 : 0; + 52 : 0; + 53 : 0; + 54 : 0; -- clk0 counter: Bypass = 0 (1 bit(s)) + 55 : 0; -- clk0 counter: High Count = 8 (8 bit(s)) + 56 : 0; + 57 : 0; + 58 : 0; + 59 : 1; + 60 : 0; + 61 : 0; + 62 : 0; + 63 : 0; -- clk0 counter: Odd Division = 0 (1 bit(s)) + 64 : 0; -- clk0 counter: Low Count = 8 (8 bit(s)) + 65 : 0; + 66 : 0; + 67 : 0; + 68 : 1; + 69 : 0; + 70 : 0; + 71 : 0; + 72 : 0; -- clk1 counter: Bypass = 0 (1 bit(s)) + 73 : 0; -- clk1 counter: High Count = 8 (8 bit(s)) + 74 : 0; + 75 : 0; + 76 : 0; + 77 : 1; + 78 : 0; + 79 : 0; + 80 : 0; + 81 : 0; -- clk1 counter: Odd Division = 0 (1 bit(s)) + 82 : 0; -- clk1 counter: Low Count = 8 (8 bit(s)) + 83 : 0; + 84 : 0; + 85 : 0; + 86 : 1; + 87 : 0; + 88 : 0; + 89 : 0; + 90 : 1; -- clk2 counter: Bypass = 1 (1 bit(s)) + 91 : 0; -- clk2 counter: High Count = 0 (8 bit(s)) + 92 : 0; + 93 : 0; + 94 : 0; + 95 : 0; + 96 : 0; + 97 : 0; + 98 : 0; + 99 : 0; -- clk2 counter: Odd Division = 0 (1 bit(s)) + 100 : 0; -- clk2 counter: Low Count = 0 (8 bit(s)) + 101 : 0; + 102 : 0; + 103 : 0; + 104 : 0; + 105 : 0; + 106 : 0; + 107 : 0; + 108 : 1; -- clk3 counter: Bypass = 1 (1 bit(s)) + 109 : 0; -- clk3 counter: High Count = 0 (8 bit(s)) + 110 : 0; + 111 : 0; + 112 : 0; + 113 : 0; + 114 : 0; + 115 : 0; + 116 : 0; + 117 : 0; -- clk3 counter: Odd Division = 0 (1 bit(s)) + 118 : 0; -- clk3 counter: Low Count = 0 (8 bit(s)) + 119 : 0; + 120 : 0; + 121 : 0; + 122 : 0; + 123 : 0; + 124 : 0; + 125 : 0; + 126 : 1; -- clk4 counter: Bypass = 1 (1 bit(s)) + 127 : 0; -- clk4 counter: High Count = 0 (8 bit(s)) + 128 : 0; + 129 : 0; + 130 : 0; + 131 : 0; + 132 : 0; + 133 : 0; + 134 : 0; + 135 : 0; -- clk4 counter: Odd Division = 0 (1 bit(s)) + 136 : 0; -- clk4 counter: Low Count = 0 (8 bit(s)) + 137 : 0; + 138 : 0; + 139 : 0; + 140 : 0; + 141 : 0; + 142 : 0; + 143 : 0; +END; diff --git a/rtl/scanconverter.v b/rtl/scanconverter.v index 4891f1b..21bf069 100644 --- a/rtl/scanconverter.v +++ b/rtl/scanconverter.v @@ -121,11 +121,13 @@ module scanconverter ( output pll_scandone ); -//clock-related signals +//clock-related signals and registers wire pclk_act; wire pclk_1x, pclk_2x, pclk_3x, pclk_4x, pclk_5x; wire [1:0] pclk_mux_sel; wire pll_lock; +wire pll_activeclock; +reg pll_clkswitch; //RGB signals®isters: 8 bits per component -> 16.7M colors wire [7:0] R_act, G_act, B_act; @@ -492,13 +494,14 @@ endcase pll_2x pll_pclk ( .areset(pll_areset), - .clkswitch(enable_sc), + .clkswitch(pll_clkswitch), .configupdate(pll_configupdate), .inclk0(clk27), // set videogen clock to primary (power-on default) since both reference clocks must be running during switchover .inclk1(PCLK_in), // is the secondary input clock fully compensated? .scanclk(pll_scanclk), .scanclkena(pll_scanclkena), .scandata(pll_scandata), + .activeclock(pll_activeclock), .c0(pclk_2x), // pclk_3x in secondary config .c1(pclk_5x), // pclk_4x in secondary config .locked(pll_lock), @@ -807,6 +810,12 @@ begin end end +// Control PLL reference clock switchover +always @(posedge clk27) +begin + pll_clkswitch <= (pll_activeclock != enable_sc); +end + //Forward status flag to CPU assign vsync_flag = ~VSYNC_in_cc_LL; diff --git a/software/sys_controller/ossc/av_controller.c b/software/sys_controller/ossc/av_controller.c index 8b76800..dc33154 100644 --- a/software/sys_controller/ossc/av_controller.c +++ b/software/sys_controller/ossc/av_controller.c @@ -97,6 +97,7 @@ alt_u32 read_it2(alt_u32 regaddr); // 8. Compare your MIF/HEX to the captured scan chain and update it accordingly // 9. Dump the updated scan chain data to an array like below (last 16 bits are 0) // 10. PLL can be then reconfigured with custom pll_reconfig as shown in program_mode() +const alt_u32 pll_config_default_data[] = {0x0d806000, 0x00402010, 0x08040220, 0x00004022, 0x00000000}; const alt_u32 pll_config_2x_5x_data[] = {0x0dc06000, 0x00783c11, 0x070180e0, 0x0000180e, 0x00000000}; const alt_u32 pll_config_3x_4x_data[] = {0x0d806000, 0x00301804, 0x02014060, 0x00001406, 0x00000000}; @@ -745,6 +746,11 @@ int init_hw() sys_ctrl = AV_RESET_N|LCD_BL|SD_SPI_SS_N|LCD_CS_N|REMOTE_EVENT; IOWR_ALTERA_AVALON_PIO_DATA(PIO_0_BASE, sys_ctrl); + // Reload initial PLL config (needed after jtagm_reset_req if config has changed). + // Note that test pattern gets restored only if pclk was active before jtagm_reset_req assertion. + memcpy((void*)pll_reconfig->pll_config_data.data, pll_config_default_data, sizeof(pll_config_default_data)); + pll_reconfig->pll_config_status.update = 1; + //wait >500ms for SD card interface to be stable //over 200ms and LCD may be buggy? usleep(200000);