From e1bfb751880aaf52c63bc5f6f1192f37fe6756e3 Mon Sep 17 00:00:00 2001 From: Henry Styles Date: Tue, 31 Oct 2017 16:03:24 -0700 Subject: [PATCH] VC707 Shell : Make DDR and PCIe optional, mixed into Shell with traits. Also add MMCM to provide 65Mhz (and multiples) clock --- src/main/scala/ip/xilinx/Xilinx.scala | 57 +++++++- src/main/scala/shell/xilinx/VC707Shell.scala | 136 ++++++++++++------- xilinx/vc707/constraints/vc707-master.xdc | 36 ++++- 3 files changed, 165 insertions(+), 64 deletions(-) diff --git a/src/main/scala/ip/xilinx/Xilinx.scala b/src/main/scala/ip/xilinx/Xilinx.scala index 38fac92..e1b6d82 100644 --- a/src/main/scala/ip/xilinx/Xilinx.scala +++ b/src/main/scala/ip/xilinx/Xilinx.scala @@ -188,11 +188,11 @@ object PowerOnResetFPGAOnly { } //------------------------------------------------------------------------- -// vc707clk_wiz_sync +// vc707_sys_clock_mmcm //------------------------------------------------------------------------- //IP : xilinx mmcm with "NO_BUFFER" input clock -class vc707clk_wiz_sync extends BlackBox { +class vc707_sys_clock_mmcm0 extends BlackBox { val io = new Bundle { val clk_in1 = Bool(INPUT) val clk_out1 = Clock(OUTPUT) @@ -207,8 +207,8 @@ class vc707clk_wiz_sync extends BlackBox { } ElaborationArtefacts.add( - "vc707clk_wiz_sync.vivado.tcl", - """create_ip -name clk_wiz -vendor xilinx.com -library ip -version 5.3 -module_name vc707clk_wiz_sync -dir $ipdir -force + "vc707_sys_clock_mmcm0.vivado.tcl", + """create_ip -name clk_wiz -vendor xilinx.com -library ip -module_name vc707_sys_clock_mmcm0 -dir $ipdir -force set_property -dict [list \ CONFIG.CLK_IN1_BOARD_INTERFACE {Custom} \ CONFIG.PRIM_SOURCE {No_buffer} \ @@ -252,7 +252,54 @@ class vc707clk_wiz_sync extends BlackBox { CONFIG.CLKOUT6_JITTER {102.207} \ CONFIG.CLKOUT6_PHASE_ERROR {91.235} \ CONFIG.CLKOUT7_JITTER {117.249} \ - CONFIG.CLKOUT7_PHASE_ERROR {91.235}] [get_ips vc707clk_wiz_sync] """ + CONFIG.CLKOUT7_PHASE_ERROR {91.235}] [get_ips vc707_sys_clock_mmcm0] """ + ) +} + +class vc707_sys_clock_mmcm1 extends BlackBox { + val io = new Bundle { + val clk_in1 = Bool(INPUT) + val clk_out1 = Clock(OUTPUT) + val clk_out2 = Clock(OUTPUT) + val reset = Bool(INPUT) + val locked = Bool(OUTPUT) + } + + ElaborationArtefacts.add( + "vc707_sys_clock_mmcm1.vivado.tcl", + """create_ip -name clk_wiz -vendor xilinx.com -library ip -module_name vc707_sys_clock_mmcm1 -dir $ipdir -force + set_property -dict [list \ + CONFIG.CLK_IN1_BOARD_INTERFACE {Custom} \ + CONFIG.PRIM_SOURCE {No_buffer} \ + CONFIG.CLKOUT2_USED {true} \ + CONFIG.CLKOUT3_USED {false} \ + CONFIG.CLKOUT4_USED {false} \ + CONFIG.CLKOUT5_USED {false} \ + CONFIG.CLKOUT6_USED {false} \ + CONFIG.CLKOUT7_USED {false} \ + CONFIG.CLKOUT1_REQUESTED_OUT_FREQ {32.5} \ + CONFIG.CLKOUT2_REQUESTED_OUT_FREQ {65} \ + CONFIG.CLK_IN1_BOARD_INTERFACE {Custom} \ + CONFIG.PRIM_IN_FREQ {200.000} \ + CONFIG.CLKIN1_JITTER_PS {50.0} \ + CONFIG.MMCM_DIVCLK_DIVIDE {1} \ + CONFIG.MMCM_CLKFBOUT_MULT_F {4.875} \ + CONFIG.MMCM_CLKIN1_PERIOD {5.0} \ + CONFIG.MMCM_CLKOUT0_DIVIDE_F {30.000} \ + CONFIG.MMCM_CLKOUT1_DIVIDE {15} \ + CONFIG.MMCM_CLKOUT2_DIVIDE {1} \ + CONFIG.MMCM_CLKOUT3_DIVIDE {1} \ + CONFIG.MMCM_CLKOUT4_DIVIDE {1} \ + CONFIG.MMCM_CLKOUT5_DIVIDE {1} \ + CONFIG.MMCM_CLKOUT6_DIVIDE {1} \ + CONFIG.NUM_OUT_CLKS {2} \ + CONFIG.CLKOUT1_JITTER {135.973} \ + CONFIG.CLKOUT1_PHASE_ERROR {87.159} \ + CONFIG.CLKOUT2_JITTER {117.878} \ + CONFIG.CLKOUT2_PHASE_ERROR {87.159} \ + CONFIG.CLKOUT3_JITTER {131.973} \ + CONFIG.CLKOUT3_PHASE_ERROR {87.159}] \ + [get_ips vc707_sys_clock_mmcm1] """ ) } diff --git a/src/main/scala/shell/xilinx/VC707Shell.scala b/src/main/scala/shell/xilinx/VC707Shell.scala index 619f4a4..fa6a4c4 100644 --- a/src/main/scala/shell/xilinx/VC707Shell.scala +++ b/src/main/scala/shell/xilinx/VC707Shell.scala @@ -15,18 +15,52 @@ import sifive.blocks.devices.uart._ import sifive.fpgashells.devices.xilinx.xilinxvc707mig._ import sifive.fpgashells.devices.xilinx.xilinxvc707pciex1._ -import sifive.fpgashells.ip.xilinx.{IBUFDS, PowerOnResetFPGAOnly, sdio_spi_bridge, vc707clk_wiz_sync, vc707reset} +import sifive.fpgashells.ip.xilinx.{IBUFDS, PowerOnResetFPGAOnly, sdio_spi_bridge, vc707_sys_clock_mmcm0, + vc707_sys_clock_mmcm1, vc707reset} //------------------------------------------------------------------------- // VC707Shell //------------------------------------------------------------------------- +trait HasDDR3 { this: VC707Shell => + + require(!p.lift(MemoryXilinxDDRKey).isEmpty) + val ddr = IO(new XilinxVC707MIGPads(p(MemoryXilinxDDRKey))) + + def connectMIG(dut: HasMemoryXilinxVC707MIGModuleImp): Unit = { + // Clock & Reset + dut.xilinxvc707mig.sys_clk_i := sys_clock.asUInt + mig_clock := dut.xilinxvc707mig.ui_clk + mig_sys_reset := dut.xilinxvc707mig.ui_clk_sync_rst + mig_mmcm_locked := dut.xilinxvc707mig.mmcm_locked + dut.xilinxvc707mig.aresetn := mig_resetn + dut.xilinxvc707mig.sys_rst := sys_reset + + ddr <> dut.xilinxvc707mig + } +} + +trait HasPCIe { this: VC707Shell => + val pcie = IO(new XilinxVC707PCIeX1Pads) + + def connectPCIe(dut: HasSystemXilinxVC707PCIeX1ModuleImp): Unit = { + // Clock & Reset + dut.xilinxvc707pcie.axi_aresetn := pcie_dat_resetn + pcie_dat_clock := dut.xilinxvc707pcie.axi_aclk_out + pcie_cfg_clock := dut.xilinxvc707pcie.axi_ctl_aclk_out + mmcm_lock_pcie := dut.xilinxvc707pcie.mmcm_lock + dut.xilinxvc707pcie.axi_ctl_aresetn := pcie_dat_resetn + + pcie <> dut.xilinxvc707pcie + } +} + abstract class VC707Shell(implicit val p: Parameters) extends RawModule { //----------------------------------------------------------------------- // Interface //----------------------------------------------------------------------- - + // 200Mhz differential sysclk val sys_diff_clock_clk_n = IO(Input(Bool())) val sys_diff_clock_clk_p = IO(Input(Bool())) @@ -34,9 +68,6 @@ abstract class VC707Shell(implicit val p: Parameters) extends RawModule { // active high reset val reset = IO(Input(Bool())) - // DDR SDRAM - val ddr = IO(new XilinxVC707MIGPads(p(MemoryXilinxDDRKey))) - // LED val led = IO(Vec(8, Output(Bool()))) @@ -57,8 +88,22 @@ abstract class VC707Shell(implicit val p: Parameters) extends RawModule { val jtag_TDI = IO(Input(Bool())) val jtag_TDO = IO(Output(Bool())) - // PCIe - val pcie = IO(new XilinxVC707PCIeX1Pads) + //Buttons + val btn_0 = IO(Analog(1.W)) + val btn_1 = IO(Analog(1.W)) + val btn_2 = IO(Analog(1.W)) + val btn_3 = IO(Analog(1.W)) + + //Sliding switches + val sw_0 = IO(Analog(1.W)) + val sw_1 = IO(Analog(1.W)) + val sw_2 = IO(Analog(1.W)) + val sw_3 = IO(Analog(1.W)) + val sw_4 = IO(Analog(1.W)) + val sw_5 = IO(Analog(1.W)) + val sw_6 = IO(Analog(1.W)) + val sw_7 = IO(Analog(1.W)) + //----------------------------------------------------------------------- // Wire declrations @@ -117,18 +162,26 @@ abstract class VC707Shell(implicit val p: Parameters) extends RawModule { // Clock Generator //----------------------------------------------------------------------- - val coreplex_mmcm = Module(new vc707clk_wiz_sync) - coreplex_mmcm.io.clk_in1 := sys_clock.asUInt - coreplex_mmcm.io.reset := mig_sys_reset + //25MHz and multiples + val vc707_sys_clock_mmcm0 = Module(new vc707_sys_clock_mmcm0) + vc707_sys_clock_mmcm0.io.clk_in1 := sys_clock.asUInt + vc707_sys_clock_mmcm0.io.reset := reset + val clk12_5 = vc707_sys_clock_mmcm0.io.clk_out1 + val clk25 = vc707_sys_clock_mmcm0.io.clk_out2 + val clk37_5 = vc707_sys_clock_mmcm0.io.clk_out3 + val clk50 = vc707_sys_clock_mmcm0.io.clk_out4 + val clk100 = vc707_sys_clock_mmcm0.io.clk_out5 + val clk150 = vc707_sys_clock_mmcm0.io.clk_out6 + val clk75 = vc707_sys_clock_mmcm0.io.clk_out7 + val vc707_sys_clock_mmcm0_locked = vc707_sys_clock_mmcm0.io.locked - val clk12_5 = coreplex_mmcm.io.clk_out1 - val clk25 = coreplex_mmcm.io.clk_out2 - val clk37_5 = coreplex_mmcm.io.clk_out3 - val clk50 = coreplex_mmcm.io.clk_out4 - val clk100 = coreplex_mmcm.io.clk_out5 - val clk150 = coreplex_mmcm.io.clk_out6 - val clk75 = coreplex_mmcm.io.clk_out7 - val coreplex_mmcm_locked = coreplex_mmcm.io.locked + //65MHz and multiples + val vc707_sys_clock_mmcm1 = Module(new vc707_sys_clock_mmcm1) + vc707_sys_clock_mmcm1.io.clk_in1 := sys_clock.asUInt + vc707_sys_clock_mmcm1.io.reset := reset + val clk32_5 = vc707_sys_clock_mmcm1.io.clk_out1 + val clk65 = vc707_sys_clock_mmcm1.io.clk_out2 + val vc707_sys_clock_mmcm1_locked = vc707_sys_clock_mmcm1.io.locked // DUT clock dut_clock := clk37_5 @@ -137,12 +190,14 @@ abstract class VC707Shell(implicit val p: Parameters) extends RawModule { // System reset //----------------------------------------------------------------------- - do_reset := !mig_mmcm_locked || !mmcm_lock_pcie || mig_sys_reset || !coreplex_mmcm_locked + do_reset := !mig_mmcm_locked || !mmcm_lock_pcie || mig_sys_reset || !vc707_sys_clock_mmcm0_locked || + !vc707_sys_clock_mmcm1_locked mig_resetn := !mig_reset dut_resetn := !dut_reset pcie_dat_resetn := !pcie_dat_reset pcie_cfg_resetn := !pcie_cfg_reset + val safe_reset = Module(new vc707reset) safe_reset.io.areset := do_reset @@ -155,11 +210,19 @@ abstract class VC707Shell(implicit val p: Parameters) extends RawModule { safe_reset.io.clock4 := dut_clock dut_reset := safe_reset.io.reset4 + //overrided in connectMIG and connect PCIe + //provide defaults to allow above reset sequencing logic to work without both + mig_clock := dut_clock + pcie_dat_clock := dut_clock + pcie_cfg_clock := dut_clock + mig_mmcm_locked := UInt("b1") + mmcm_lock_pcie := UInt("b1") + //--------------------------------------------------------------------- // Debug JTAG //--------------------------------------------------------------------- - def connectDebugJTAG(dut: HasPeripheryDebugModuleImp): Unit = { + def connectDebugJTAG(dut: HasPeripheryDebugModuleImp): SystemJTAGIO = { val djtag = dut.debug.systemjtag.get djtag.jtag.TCK := jtag_TCK @@ -171,6 +234,7 @@ abstract class VC707Shell(implicit val p: Parameters) extends RawModule { djtag.reset := PowerOnResetFPGAOnly(dut_clock) dut_ndreset := dut.debug.ndreset + djtag } //----------------------------------------------------------------------- @@ -224,36 +288,4 @@ abstract class VC707Shell(implicit val p: Parameters) extends RawModule { ip_sdio_spi.io.spi_dq_o := sd_spi_dq_o.asUInt } - //--------------------------------------------------------------------- - // MIG - //--------------------------------------------------------------------- - - def connectMIG(dut: HasMemoryXilinxVC707MIGModuleImp): Unit = { - - // Clock & Reset - dut.xilinxvc707mig.sys_clk_i := sys_clock.asUInt - mig_clock := dut.xilinxvc707mig.ui_clk - mig_sys_reset := dut.xilinxvc707mig.ui_clk_sync_rst - mig_mmcm_locked := dut.xilinxvc707mig.mmcm_locked - dut.xilinxvc707mig.aresetn := mig_resetn - dut.xilinxvc707mig.sys_rst := sys_reset - - ddr <> dut.xilinxvc707mig - } - - //--------------------------------------------------------------------- - // PCIE - //--------------------------------------------------------------------- - - def connectPCIe(dut: HasSystemXilinxVC707PCIeX1ModuleImp): Unit = { - // Clock & Reset - dut.xilinxvc707pcie.axi_aresetn := pcie_dat_resetn - pcie_dat_clock := dut.xilinxvc707pcie.axi_aclk_out - pcie_cfg_clock := dut.xilinxvc707pcie.axi_ctl_aclk_out - mmcm_lock_pcie := dut.xilinxvc707pcie.mmcm_lock - dut.xilinxvc707pcie.axi_ctl_aresetn := pcie_dat_resetn - - pcie <> dut.xilinxvc707pcie - } - } diff --git a/xilinx/vc707/constraints/vc707-master.xdc b/xilinx/vc707/constraints/vc707-master.xdc index cf410e6..7ee91c4 100644 --- a/xilinx/vc707/constraints/vc707-master.xdc +++ b/xilinx/vc707/constraints/vc707-master.xdc @@ -1,5 +1,8 @@ #---------------Physical Constraints----------------- +#get_port_part_pins +#clk_n clk_p dip_switches_tri_i_0 dip_switches_tri_i_1 dip_switches_tri_i_2 dip_switches_tri_i_3 dip_switches_tri_i_4 dip_switches_tri_i_5 dip_switches_tri_i_6 dip_switches_tri_i_7 iic_main_scl_i iic_main_sda_i lcd_7bits_tri_o_0 lcd_7bits_tri_o_1 lcd_7bits_tri_o_2 lcd_7bits_tri_o_3 lcd_7bits_tri_o_4 lcd_7bits_tri_o_5 lcd_7bits_tri_o_6 leds_8bits_tri_o_0 leds_8bits_tri_o_1 leds_8bits_tri_o_2 leds_8bits_tri_o_3 leds_8bits_tri_o_4 leds_8bits_tri_o_5 leds_8bits_tri_o_6 leds_8bits_tri_o_7 linear_flash_addr_1 linear_flash_addr_10 linear_flash_addr_11 linear_flash_addr_12 linear_flash_addr_13 linear_flash_addr_14 linear_flash_addr_15 linear_flash_addr_16 linear_flash_addr_17 linear_flash_addr_18 linear_flash_addr_19 linear_flash_addr_2 linear_flash_addr_20 linear_flash_addr_21 linear_flash_addr_22 linear_flash_addr_23 linear_flash_addr_24 linear_flash_addr_25 linear_flash_addr_26 linear_flash_addr_3 linear_flash_addr_4 linear_flash_addr_5 linear_flash_addr_6 linear_flash_addr_7 linear_flash_addr_8 linear_flash_addr_9 linear_flash_adv_ldn linear_flash_ce_n linear_flash_dq_i_0 linear_flash_dq_i_1 linear_flash_dq_i_10 linear_flash_dq_i_11 linear_flash_dq_i_12 linear_flash_dq_i_13 linear_flash_dq_i_14 linear_flash_dq_i_15 linear_flash_dq_i_2 linear_flash_dq_i_3 linear_flash_dq_i_4 linear_flash_dq_i_5 linear_flash_dq_i_6 linear_flash_dq_i_7 linear_flash_dq_i_8 linear_flash_dq_i_9 linear_flash_oen linear_flash_wen mdc mdio_i phy_rst_out push_buttons_5bits_tri_i_0 push_buttons_5bits_tri_i_1 push_buttons_5bits_tri_i_2 push_buttons_5bits_tri_i_3 push_buttons_5bits_tri_i_4 reset rotary_inca_push_incb_tri_i_0 rotary_inca_push_incb_tri_i_1 rotary_inca_push_incb_tri_i_2 rs232_uart_rxd rs232_uart_txd sfp_rxn sfp_rxp sfp_sgmii_txn sfp_sgmii_txp sgmii_mgt_clkn sgmii_mgt_clkp sgmii_rxn sgmii_rxp sgmii_txn sgmii_txp sma_lvds_rxn sma_lvds_rxp sma_lvds_txn sma_lvds_txp sma_mgt_clkn sma_mgt_clkp sma_sfp_rxn sma_sfp_rxp sma_sfp_txn sma_sfp_txp + set_property BOARD_PIN {clk_p} [get_ports sys_diff_clock_clk_p] set_property BOARD_PIN {clk_n} [get_ports sys_diff_clock_clk_n] set_property BOARD_PIN {reset} [get_ports reset] @@ -16,6 +19,21 @@ set_property BOARD_PIN {leds_8bits_tri_o_5} [get_ports led_5] set_property BOARD_PIN {leds_8bits_tri_o_6} [get_ports led_6] set_property BOARD_PIN {leds_8bits_tri_o_7} [get_ports led_7] +set_property BOARD_PIN {push_buttons_5bits_tri_i_0} [get_ports btn_0] +set_property BOARD_PIN {push_buttons_5bits_tri_i_1} [get_ports btn_1] +set_property BOARD_PIN {push_buttons_5bits_tri_i_2} [get_ports btn_2] +set_property BOARD_PIN {push_buttons_5bits_tri_i_3} [get_ports btn_3] +set_property BOARD_PIN {push_buttons_5bits_tri_i_4} [get_ports btn_5] + +set_property BOARD_PIN {dip_switches_tri_i_0} [get_ports sw_0] +set_property BOARD_PIN {dip_switches_tri_i_1} [get_ports sw_1] +set_property BOARD_PIN {dip_switches_tri_i_2} [get_ports sw_2] +set_property BOARD_PIN {dip_switches_tri_i_3} [get_ports sw_3] +set_property BOARD_PIN {dip_switches_tri_i_4} [get_ports sw_4] +set_property BOARD_PIN {dip_switches_tri_i_5} [get_ports sw_5] +set_property BOARD_PIN {dip_switches_tri_i_6} [get_ports sw_6] +set_property BOARD_PIN {dip_switches_tri_i_7} [get_ports sw_7] + set_property PACKAGE_PIN AU33 [get_ports uart_rx] set_property IOSTANDARD LVCMOS18 [get_ports uart_rx] set_property IOB TRUE [get_ports uart_rx] @@ -64,11 +82,15 @@ set_property -dict { PACKAGE_PIN AT30 IOSTANDARD LVCMOS18 IOB TRUE PULLUP TRU set_clock_groups -asynchronous \ -group { clk_pll_i } \ -group { \ - clk_out1_vc707clk_wiz_sync \ - clk_out2_vc707clk_wiz_sync \ - clk_out3_vc707clk_wiz_sync \ - clk_out4_vc707clk_wiz_sync \ - clk_out5_vc707clk_wiz_sync \ - clk_out6_vc707clk_wiz_sync \ - clk_out7_vc707clk_wiz_sync } \ + clk_out1_vc707_sys_clock_mmcm0 \ + clk_out2_vc707_sys_clock_mmcm0 \ + clk_out3_vc707_sys_clock_mmcm0 \ + clk_out4_vc707_sys_clock_mmcm0 \ + clk_out5_vc707_sys_clock_mmcm0 \ + clk_out6_vc707_sys_clock_mmcm0 \ + clk_out7_vc707_sys_clock_mmcm0 } \ + -group { \ + clk_out1_vc707_sys_clock_mmcm1 \ + clk_out2_vc707_sys_clock_mmcm1 } \ -group [list [get_clocks -include_generated_clocks -of_objects [get_pins -hier -filter {name =~ *pcie*TXOUTCLK}]]] +