From bd8273558cc65878085806362e189ecd8f821ee0 Mon Sep 17 00:00:00 2001 From: Joris van Rantwijk Date: Fri, 4 Oct 2024 23:01:26 +0200 Subject: [PATCH] Add PLL and reset FPGA via GPIO --- fpga/rtl/puzzlefw_pkg.vhd | 2 +- fpga/rtl/puzzlefw_top.vhd | 89 +++++++++-- .../sources_1/bd/puzzlefw/puzzlefw.bd | 140 ++++++++++++++++-- 3 files changed, 204 insertions(+), 27 deletions(-) diff --git a/fpga/rtl/puzzlefw_pkg.vhd b/fpga/rtl/puzzlefw_pkg.vhd index 3176ea9..c599fec 100644 --- a/fpga/rtl/puzzlefw_pkg.vhd +++ b/fpga/rtl/puzzlefw_pkg.vhd @@ -94,7 +94,7 @@ package puzzlefw_pkg is -- Firmware info word. constant fw_api_version: natural := 1; constant fw_version_major: natural := 0; - constant fw_version_minor: natural := 10; + constant fw_version_minor: natural := 11; constant fw_info_word: std_logic_vector(31 downto 0) := x"4a" & std_logic_vector(to_unsigned(fw_api_version, 8)) diff --git a/fpga/rtl/puzzlefw_top.vhd b/fpga/rtl/puzzlefw_top.vhd index 393aef6..9ce4abc 100644 --- a/fpga/rtl/puzzlefw_top.vhd +++ b/fpga/rtl/puzzlefw_top.vhd @@ -71,16 +71,27 @@ architecture arch of puzzlefw_top is -- Auxiliary clock from FCLK0. signal clk_fclk: std_logic; - -- Main reset signal, derived from FCLK_RESET0, active high, synchronous to clk_adc. - signal s_reset: std_logic; + -- Reset signals. + signal s_gpio_reset_n: std_logic; -- reset signal from GPIO, active low + signal s_pll_reset: std_logic; -- reset signal for PLL + signal s_pll_locked: std_logic; -- PLL locked status + signal s_ext_reset_n: std_logic; -- reset signal for processing system + signal s_reset: std_logic; -- main reset, synchronized to clk_adc - -- Internal clock signal. + -- Internal clock signals. signal s_adc_clk_ibuf: std_logic; + signal s_pll_clkfbout: std_logic; + signal s_pll_clkfbin: std_logic; + signal s_pll_clkout: std_logic; -- Blinking LED. signal r_adcclk_cnt: unsigned(25 downto 0); signal r_adcclk_led: std_logic; + -- Internal GPIO bus from PS. + signal s_gpio_in: std_logic_vector(23 downto 0); + signal s_gpio_out: std_logic_vector(23 downto 0); + -- APB bus for register access. signal s_apb_paddr: std_logic_vector(31 downto 0); signal s_apb_penable: std_logic; @@ -168,6 +179,20 @@ architecture arch of puzzlefw_top is begin + -- Global FPGA reset. + -- GPIO(0) = '0' to reset. + s_gpio_reset_n <= s_gpio_out(0); + + -- ADC clock duty cycle stabilizer. + -- GPIO(2) = '1' to enable, '0' to disable. + adc_cdcs_o <= s_gpio_out(2); + + -- GPIO inputs to the PS. + -- GPIO(1) = '0' while in reset, '1' when reset released. + s_gpio_in(1) <= not s_reset; + s_gpio_in(0) <= '0'; + s_gpio_in(23 downto 2) <= (others => '0'); + -- Drive LEDs. led_o(0) <= r_adcclk_led; -- blinking LED, 1 Hz led_o(1) <= s_reg_control.acquisition_en; -- acquisition enabled @@ -175,9 +200,6 @@ begin led_o(3) <= or_reduce(s_reg_control.timetagger_en); -- timetagger enabled led_o(7 downto 4) <= s_reg_control.led_state(7 downto 4); - -- Enable ADC clock duty cycle stabilizer. - adc_cdcs_o <= '1'; - -- ADC clock outputs are not connected on vanilla Red Pitaya 125-14. adc_clk_o <= (others => 'Z'); @@ -201,12 +223,45 @@ begin IB => adc_clk_i(0) ); - -- Clock buffer for ADC clock. - inst_bufg_adc_clk: BUFG + -- PLL for 125 MHz clock. + -- Input clock comes from ADC. + -- Output clock drives most of the FPGA design. + inst_pll: PLLE2_BASE + generic map ( + BANDWIDTH => "OPTIMIZED", + CLKFBOUT_MULT => 7, + CLKFBOUT_PHASE => 0.0, + CLKIN1_PERIOD => 8.0, + CLKOUT0_DIVIDE => 7, + CLKOUT0_DUTY_CYCLE => 0.5, + CLKOUT0_PHASE => 0.0, + DIVCLK_DIVIDE => 1, + STARTUP_WAIT => "FALSE" ) port map ( - I => s_adc_clk_ibuf, - O => clk_adc - ); + CLKOUT0 => s_pll_clkout, + CLKFBOUT => s_pll_clkfbout, + LOCKED => s_pll_locked, + CLKIN1 => s_adc_clk_ibuf, + PWRDWN => '0', + RST => s_pll_reset, + CLKFBIN => s_pll_clkfbin ); + + -- Reset PLL when external reset is applied. + s_pll_reset <= not s_gpio_reset_n; + + -- Reset processing system when PLL is not locked. + s_ext_reset_n <= s_gpio_reset_n and s_pll_locked; + + -- Clock buffers for PLL. + inst_bufg_pll_clkfb: BUFG + port map ( + I => s_pll_clkfbout, + O => s_pll_clkfbin ); + + inst_bufg_pll_clkout: BUFG + port map ( + I => s_pll_clkout, + O => clk_adc ); -- ARM/PS block design. inst_blockdesign: entity work.puzzlefw_wrapper @@ -214,6 +269,7 @@ begin sys_clk => clk_adc, ps_fclk => clk_fclk, peripheral_reset_0(0) => s_reset, + ext_reset_in_0 => s_ext_reset_n, DDR_0_addr => DDR_0_addr, DDR_0_ba => DDR_0_ba, DDR_0_cas_n => DDR_0_cas_n, @@ -235,6 +291,16 @@ begin FIXED_IO_0_ps_clk => FIXED_IO_0_ps_clk, FIXED_IO_0_ps_porb => FIXED_IO_0_ps_porb, FIXED_IO_0_ps_srstb => FIXED_IO_0_ps_srstb, + GPIO_I_0 => s_gpio_in, + GPIO_O_0 => s_gpio_out, + SPI0_MOSI_O_0 => open, + SPI0_MOSI_T_0 => open, + SPI0_SCLK_O_0 => open, + SPI0_SCLK_T_0 => open, + SPI0_SS1_O_0 => open, + SPI0_SS_O_0 => open, + SPI0_SS_T_0 => open, + IRQ_F2P => s_irq_f2p, APB_M_0_paddr => s_apb_paddr, APB_M_0_penable => s_apb_penable, APB_M_0_prdata => s_apb_prdata, @@ -243,7 +309,6 @@ begin APB_M_0_pslverr(0) => s_apb_pslverr, APB_M_0_pwdata => s_apb_pwdata, APB_M_0_pwrite => s_apb_pwrite, - IRQ_F2P => s_irq_f2p, S_AXI_HP0_0_araddr => s_axi_araddr, S_AXI_HP0_0_arburst => s_axi_arburst, S_AXI_HP0_0_arcache => s_axi_arcache, diff --git a/fpga/vivado/redpitaya_puzzlefw.srcs/sources_1/bd/puzzlefw/puzzlefw.bd b/fpga/vivado/redpitaya_puzzlefw.srcs/sources_1/bd/puzzlefw/puzzlefw.bd index 99cce7c..4366e8e 100644 --- a/fpga/vivado/redpitaya_puzzlefw.srcs/sources_1/bd/puzzlefw/puzzlefw.bd +++ b/fpga/vivado/redpitaya_puzzlefw.srcs/sources_1/bd/puzzlefw/puzzlefw.bd @@ -1,7 +1,7 @@ { "design": { "design_info": { - "boundary_crc": "0x3DCD19FE44770B59", + "boundary_crc": "0x9117A810100AEEF7", "device": "xc7z010clg400-1", "gen_directory": "../../../../redpitaya_puzzlefw.gen/sources_1/bd/puzzlefw", "name": "puzzlefw", @@ -18,7 +18,8 @@ "auto_pc": "" } }, - "axi_apb_bridge_0": "" + "axi_apb_bridge_0": "", + "xlconstant_0": "" }, "interface_ports": { "DDR_0": { @@ -284,6 +285,51 @@ "value_src": "default" } } + }, + "ext_reset_in_0": { + "type": "rst", + "direction": "I", + "parameters": { + "INSERT_VIP": { + "value": "0", + "value_src": "default" + }, + "POLARITY": { + "value": "ACTIVE_LOW", + "value_src": "default" + } + } + }, + "GPIO_I_0": { + "direction": "I", + "left": "23", + "right": "0" + }, + "GPIO_O_0": { + "direction": "O", + "left": "23", + "right": "0" + }, + "SPI0_SCLK_O_0": { + "direction": "O" + }, + "SPI0_SCLK_T_0": { + "direction": "O" + }, + "SPI0_SS_T_0": { + "direction": "O" + }, + "SPI0_SS_O_0": { + "direction": "O" + }, + "SPI0_SS1_O_0": { + "direction": "O" + }, + "SPI0_MOSI_O_0": { + "direction": "O" + }, + "SPI0_MOSI_T_0": { + "direction": "O" } }, "components": { @@ -1545,6 +1591,12 @@ ] } } + }, + "xlconstant_0": { + "vlnv": "xilinx.com:ip:xlconstant:1.1", + "xci_name": "puzzlefw_xlconstant_0_0", + "xci_path": "ip/puzzlefw_xlconstant_0_0/puzzlefw_xlconstant_0_0.xci", + "inst_hier_path": "xlconstant_0" } }, "interface_nets": { @@ -1572,26 +1624,20 @@ "processing_system7_0/FIXED_IO" ] }, - "processing_system7_0_M_AXI_GP0": { - "interface_ports": [ - "processing_system7_0/M_AXI_GP0", - "axi_interconnect_0/S00_AXI" - ] - }, "axi_apb_bridge_0_APB_M": { "interface_ports": [ "APB_M_0", "axi_apb_bridge_0/APB_M" ] + }, + "processing_system7_0_M_AXI_GP0": { + "interface_ports": [ + "processing_system7_0/M_AXI_GP0", + "axi_interconnect_0/S00_AXI" + ] } }, "nets": { - "processing_system7_0_FCLK_RESET0_N": { - "ports": [ - "processing_system7_0/FCLK_RESET0_N", - "proc_sys_reset_0/ext_reset_in" - ] - }, "proc_sys_reset_0_peripheral_aresetn": { "ports": [ "proc_sys_reset_0/peripheral_aresetn", @@ -1635,6 +1681,72 @@ "processing_system7_0/FCLK_CLK0", "ps_fclk" ] + }, + "ext_reset_in_0_1": { + "ports": [ + "ext_reset_in_0", + "proc_sys_reset_0/ext_reset_in" + ] + }, + "GPIO_I_0_1": { + "ports": [ + "GPIO_I_0", + "processing_system7_0/GPIO_I" + ] + }, + "processing_system7_0_GPIO_O": { + "ports": [ + "processing_system7_0/GPIO_O", + "GPIO_O_0" + ] + }, + "processing_system7_0_SPI0_SCLK_O": { + "ports": [ + "processing_system7_0/SPI0_SCLK_O", + "SPI0_SCLK_O_0" + ] + }, + "processing_system7_0_SPI0_SCLK_T": { + "ports": [ + "processing_system7_0/SPI0_SCLK_T", + "SPI0_SCLK_T_0" + ] + }, + "processing_system7_0_SPI0_SS_T": { + "ports": [ + "processing_system7_0/SPI0_SS_T", + "SPI0_SS_T_0" + ] + }, + "processing_system7_0_SPI0_SS_O": { + "ports": [ + "processing_system7_0/SPI0_SS_O", + "SPI0_SS_O_0" + ] + }, + "processing_system7_0_SPI0_SS1_O": { + "ports": [ + "processing_system7_0/SPI0_SS1_O", + "SPI0_SS1_O_0" + ] + }, + "processing_system7_0_SPI0_MOSI_O": { + "ports": [ + "processing_system7_0/SPI0_MOSI_O", + "SPI0_MOSI_O_0" + ] + }, + "processing_system7_0_SPI0_MOSI_T": { + "ports": [ + "processing_system7_0/SPI0_MOSI_T", + "SPI0_MOSI_T_0" + ] + }, + "xlconstant_0_dout": { + "ports": [ + "xlconstant_0/dout", + "processing_system7_0/SPI0_SS_I" + ] } }, "addressing": {