Use two chained PLLs to generate all needed clocks. This makes it possible to switch the USB clock to 72 MHz.
Signed-off-by: Michael Walle <mich...@walle.cc> --- boards/milkymist-one/rtl/system.v | 213 +++++++++++++++++------------ boards/milkymist-one/synthesis/common.ucf | 13 +- boards/milkymist-one/synthesis/xst.ucf | 10 +- 3 files changed, 140 insertions(+), 96 deletions(-) diff --git a/boards/milkymist-one/rtl/system.v b/boards/milkymist-one/rtl/system.v index dfbf72e..5332154 100644 --- a/boards/milkymist-one/rtl/system.v +++ b/boards/milkymist-one/rtl/system.v @@ -19,7 +19,7 @@ `include "lm32_include.v" module system( - input clk50, + input clkin50, // Boot ROM output [23:0] flash_adr, @@ -106,7 +106,7 @@ module system( input phy_irq_n, output phy_mii_clk, inout phy_mii_data, - output reg phy_clk, + output phy_clk, // Video Input input [7:0] videoin_p, @@ -144,58 +144,142 @@ module system( //------------------------------------------------------------------ // Clock and Reset Generation //------------------------------------------------------------------ -wire sys_clk; -wire sys_clk_n; wire hard_reset; wire reset_button = btn1 & btn2 & btn3; `ifndef SIMULATION -wire sys_clk_dcm; -wire sys_clk_n_dcm; - -DCM_SP #( - .CLKDV_DIVIDE(2.0), // 1.5,2.0,2.5,3.0,3.5,4.0,4.5,5.0,5.5,6.0,6.5 - - .CLKFX_DIVIDE(5), // 1 to 32 - .CLKFX_MULTIPLY(8), // 2 to 32 - - .CLKIN_DIVIDE_BY_2("FALSE"), - .CLKIN_PERIOD(20.0), - .CLKOUT_PHASE_SHIFT("NONE"), - .CLK_FEEDBACK("NONE"), - .DESKEW_ADJUST("SYSTEM_SYNCHRONOUS"), - .DUTY_CYCLE_CORRECTION("TRUE"), - .PHASE_SHIFT(0), - .STARTUP_WAIT("TRUE") -) clkgen_sys ( - .CLK0(), - .CLK90(), - .CLK180(), - .CLK270(), - - .CLK2X(), - .CLK2X180(), - - .CLKDV(), - .CLKFX(sys_clk_dcm), - .CLKFX180(sys_clk_n_dcm), +wire clkin50_b; +IBUFG clk50_ibuf( + .I(clkin50), + .O(clkin50_b) +); + +wire clk24_pll; +wire phy_clk_pll; +wire clk50_pll; +wire clkgen600_fb; +PLL_BASE #( + .COMPENSATION("INTERNAL"), + .BANDWIDTH("OPTIMIZED"), + .CLKOUT0_DIVIDE(25), // 24 MHz + .CLKOUT1_DIVIDE(24), // 25 MHz + .CLKOUT2_DIVIDE(12), // 50 MHz + .CLKOUT3_DIVIDE(1), + .CLKOUT4_DIVIDE(1), + .CLKOUT5_DIVIDE(1), + .CLKOUT0_PHASE(0.0), + .CLKOUT1_PHASE(0.0), + .CLKOUT2_PHASE(0.0), + .CLKOUT3_PHASE(0.0), + .CLKOUT4_PHASE(0.0), + .CLKOUT5_PHASE(0.0), + .CLKOUT0_DUTY_CYCLE(0.50), + .CLKOUT1_DUTY_CYCLE(0.50), + .CLKOUT2_DUTY_CYCLE(0.50), + .CLKOUT3_DUTY_CYCLE(0.50), + .CLKOUT4_DUTY_CYCLE(0.50), + .CLKOUT5_DUTY_CYCLE(0.50), + .CLKFBOUT_MULT(12), // 600 MHz + .DIVCLK_DIVIDE(1), + .CLKFBOUT_PHASE(0.0), + .REF_JITTER(0.100), + .CLKIN_PERIOD(0.000) +) clkgen600 ( + .CLKOUT0(clk24_pll), + .CLKOUT1(phy_clk_pll), + .CLKOUT2(clk50_pll), + .CLKOUT3(), + .CLKOUT4(), + .CLKOUT5(), + .CLKFBOUT(clkgen600_fb), + .CLKIN(clkin50_b), + .CLKFBIN(clkgen600_fb), + .LOCKED(), + .RST(1'b0) +); + +wire clk24; +BUFG clk24_buf( + .I(clk24_pll), + .O(clk24) +); + +OBUF phy_clk_obuf( + .I(phy_clk_pll), + .O(phy_clk) +); + +//wire clk50; +//BUFG clk50_buf( +// .I(clk50_pll), +// .O(clk50) +//); + +wire usb_clk_pll; +wire sys_clk_pll; +wire sys_clk_n_pll; +wire clkgen720_fb; +PLL_BASE #( + .COMPENSATION("INTERNAL"), + .BANDWIDTH("OPTIMIZED"), + .CLKOUT0_DIVIDE(15), // 48 MHz + .CLKOUT1_DIVIDE(9), // 80 MHz + .CLKOUT2_DIVIDE(9), // 80 MHz, 180deg phase shift + .CLKOUT3_DIVIDE(1), + .CLKOUT4_DIVIDE(1), + .CLKOUT5_DIVIDE(1), + .CLKOUT0_PHASE(0.0), + .CLKOUT1_PHASE(0.0), + .CLKOUT2_PHASE(180.0), + .CLKOUT3_PHASE(0.0), + .CLKOUT4_PHASE(0.0), + .CLKOUT5_PHASE(0.0), + .CLKOUT0_DUTY_CYCLE(0.50), + .CLKOUT1_DUTY_CYCLE(0.50), + .CLKOUT2_DUTY_CYCLE(0.50), + .CLKOUT3_DUTY_CYCLE(0.50), + .CLKOUT4_DUTY_CYCLE(0.50), + .CLKOUT5_DUTY_CYCLE(0.50), + .CLKFBOUT_MULT(30), // 720 MHz + .DIVCLK_DIVIDE(1), + .CLKFBOUT_PHASE(0.0), + .REF_JITTER(0.100), + .CLKIN_PERIOD(0.000) +) clkgen720 ( + .CLKOUT0(usb_clk_pll), + .CLKOUT1(sys_clk_pll), + .CLKOUT2(sys_clk_n_pll), + .CLKOUT3(), + .CLKOUT4(), + .CLKOUT5(), + .CLKFBOUT(clkgen720_fb), + .CLKIN(clk24), + .CLKFBIN(clkgen720_fb), .LOCKED(), - .CLKFB(), - .CLKIN(clk50), - .RST(1'b0), - .PSEN(1'b0) + .RST(1'b0) ); -BUFG b1( - .I(sys_clk_dcm), + +wire usb_clk; +BUFG clkgen720_b1( + .I(usb_clk_pll), + .O(usb_clk) +); + +wire sys_clk; +BUFG clkgen720_b2( + .I(sys_clk_pll), .O(sys_clk) ); -BUFG b2( - .I(sys_clk_n_dcm), + +wire sys_clk_n; +BUFG clkgen720_b3( + .I(sys_clk_n_pll), .O(sys_clk_n) ); + `else -assign sys_clk = clkin; -assign sys_clk_n = ~clkin; +wire sys_clk = clkin; +wire sys_clk_n = ~clkin; `endif reg trigger_reset; @@ -990,7 +1074,7 @@ vga #( .fml_depth(`SDRAM_DEPTH) ) vga ( .sys_clk(sys_clk), - .clk50(clk50), + .clk50(clkin50_b), .sys_rst(sys_rst), .csr_a(csr_a), @@ -1315,8 +1399,6 @@ assign phy_mii_data = 1'bz; assign phy_rst_n = 1'b0; `endif -always @(posedge clk50) phy_clk <= ~phy_clk; - //--------------------------------------------------------------------------- // FastMemoryLink usage and performance meter //--------------------------------------------------------------------------- @@ -1489,45 +1571,6 @@ assign ir_irq = 1'b0; //--------------------------------------------------------------------------- // USB //--------------------------------------------------------------------------- -wire usb_clk_dcm; -wire usb_clk; -DCM_SP #( - .CLKDV_DIVIDE(2.0), // 1.5,2.0,2.5,3.0,3.5,4.0,4.5,5.0,5.5,6.0,6.5 - - .CLKFX_DIVIDE(25), // 1 to 32 - .CLKFX_MULTIPLY(24), // 2 to 32 - - .CLKIN_DIVIDE_BY_2("FALSE"), - .CLKIN_PERIOD(20.0), - .CLKOUT_PHASE_SHIFT("NONE"), - .CLK_FEEDBACK("NONE"), - .DESKEW_ADJUST("SYSTEM_SYNCHRONOUS"), - .DUTY_CYCLE_CORRECTION("TRUE"), - .PHASE_SHIFT(0), - .STARTUP_WAIT("TRUE") -) clkgen_usb ( - .CLK0(), - .CLK90(), - .CLK180(), - .CLK270(), - - .CLK2X(), - .CLK2X180(), - - .CLKDV(), - .CLKFX(usb_clk_dcm), - .CLKFX180(), - .LOCKED(), - .CLKFB(), - .CLKIN(clk50), - .RST(1'b0), - - .PSEN(1'b0) -); -BUFG usb_b_p( - .I(usb_clk_dcm), - .O(usb_clk) -); `ifdef ENABLE_USB softusb #( .csr_addr(4'hf) diff --git a/boards/milkymist-one/synthesis/common.ucf b/boards/milkymist-one/synthesis/common.ucf index f1ab861..4c2973e 100644 --- a/boards/milkymist-one/synthesis/common.ucf +++ b/boards/milkymist-one/synthesis/common.ucf @@ -1,8 +1,8 @@ # ==== Clock input ==== -NET "clk50" LOC = AB11 | IOSTANDARD = LVCMOS33; +NET "clkin50" LOC = AB11 | IOSTANDARD = LVCMOS33; -NET "clk50" TNM_NET = "GRPclk50"; -TIMESPEC "TSclk50" = PERIOD "GRPclk50" 20 ns HIGH 50%; +NET "clkin50" TNM_NET = "GRPclkin50"; +TIMESPEC "TSclkin50" = PERIOD "GRPclkin50" 20 ns HIGH 50%; # ==== Flash ==== NET "flash_adr(0)" LOC = L22; @@ -350,6 +350,7 @@ NET "usb_clk" TNM_NET = "GRPusb"; TIMESPEC "TSusb_async1" = FROM "GRPsys" TO "GRPusb" TIG; TIMESPEC "TSusb_async2" = FROM "GRPusb" TO "GRPsys" TIG; -NET "clk50_IBUFG" TNM_NET = "GRPinput"; -TIMESPEC "TSusb_async3" = FROM "GRPinput" TO "GRPusb" TIG; -TIMESPEC "TSusb_async4" = FROM "GRPusb" TO "GRPinput" TIG; +#NET "clkin50_ibuf" TNM_NET = "GRPinput"; +#NET "clkin50" TNM_NET = "GRPinput"; +#TIMESPEC "TSusb_async3" = FROM "GRPinput" TO "GRPusb" TIG; +#TIMESPEC "TSusb_async4" = FROM "GRPusb" TO "GRPinput" TIG; diff --git a/boards/milkymist-one/synthesis/xst.ucf b/boards/milkymist-one/synthesis/xst.ucf index 42e2833..e52f5bb 100644 --- a/boards/milkymist-one/synthesis/xst.ucf +++ b/boards/milkymist-one/synthesis/xst.ucf @@ -1,5 +1,5 @@ -INST "b1" LOC = BUFGMUX_X3Y6; -INST "b2" LOC = BUFGMUX_X2Y1; +#INST "b1" LOC = BUFGMUX_X3Y6; +#INST "b2" LOC = BUFGMUX_X2Y1; INST "b_videoin" LOC = BUFGMUX_X3Y15; INST "vga/b" LOC = BUFGMUX_X2Y9; INST "b_phy_rx_clk" LOC = BUFGMUX_X3Y5; @@ -7,8 +7,8 @@ INST "b_phy_tx_clk" LOC = BUFGMUX_X2Y3; INST "bio_ac97" LOC = BUFIO2_X4Y26; INST "b_ac97" LOC = BUFGMUX_X3Y7; -INST "clkgen_sys" LOC = DCM_X0Y0; -INST "clkgen_usb" LOC = DCM_X0Y3; -INST "vga/clkgen_vga" LOC = DCM_X0Y1; +#INST "clkgen_sys" LOC = DCM_X0Y0; +#INST "clkgen_usb" LOC = DCM_X0Y3; +#INST "vga/clkgen_vga" LOC = DCM_X0Y1; CONFIG STEPPING = "ES"; -- 1.7.2.5 _______________________________________________ http://lists.milkymist.org/listinfo.cgi/devel-milkymist.org IRC: #milkymist@Freenode