element14 Community
element14 Community
    Register Log In
  • Site
  • Search
  • Log In Register
  • Community Hub
    Community Hub
    • What's New on element14
    • Feedback and Support
    • Benefits of Membership
    • Personal Blogs
    • Members Area
    • Achievement Levels
  • Learn
    Learn
    • Ask an Expert
    • eBooks
    • element14 presents
    • Learning Center
    • Tech Spotlight
    • STEM Academy
    • Webinars, Training and Events
    • Learning Groups
  • Technologies
    Technologies
    • 3D Printing
    • FPGA
    • Industrial Automation
    • Internet of Things
    • Power & Energy
    • Sensors
    • Technology Groups
  • Challenges & Projects
    Challenges & Projects
    • Design Challenges
    • element14 presents Projects
    • Project14
    • Arduino Projects
    • Raspberry Pi Projects
    • Project Groups
  • Products
    Products
    • Arduino
    • Avnet Boards Community
    • Dev Tools
    • Manufacturers
    • Multicomp Pro
    • Product Groups
    • Raspberry Pi
    • RoadTests & Reviews
  • About Us
  • Store
    Store
    • Visit Your Store
    • Choose another store...
      • Europe
      •  Austria (German)
      •  Belgium (Dutch, French)
      •  Bulgaria (Bulgarian)
      •  Czech Republic (Czech)
      •  Denmark (Danish)
      •  Estonia (Estonian)
      •  Finland (Finnish)
      •  France (French)
      •  Germany (German)
      •  Hungary (Hungarian)
      •  Ireland
      •  Israel
      •  Italy (Italian)
      •  Latvia (Latvian)
      •  
      •  Lithuania (Lithuanian)
      •  Netherlands (Dutch)
      •  Norway (Norwegian)
      •  Poland (Polish)
      •  Portugal (Portuguese)
      •  Romania (Romanian)
      •  Russia (Russian)
      •  Slovakia (Slovak)
      •  Slovenia (Slovenian)
      •  Spain (Spanish)
      •  Sweden (Swedish)
      •  Switzerland(German, French)
      •  Turkey (Turkish)
      •  United Kingdom
      • Asia Pacific
      •  Australia
      •  China
      •  Hong Kong
      •  India
      •  Korea (Korean)
      •  Malaysia
      •  New Zealand
      •  Philippines
      •  Singapore
      •  Taiwan
      •  Thailand (Thai)
      • Americas
      •  Brazil (Portuguese)
      •  Canada
      •  Mexico (Spanish)
      •  United States
      Can't find the country/region you're looking for? Visit our export site or find a local distributor.
  • Translate
  • Profile
  • Settings
FPGA
  • Technologies
  • More
FPGA
Blog Learning AMD Zynq: a project to generate a set of PWM signals. 2 - add overall control block, delay and pulse signal
  • Blog
  • Forum
  • Documents
  • Quiz
  • Events
  • Polls
  • Files
  • Members
  • Mentions
  • Sub-Groups
  • Tags
  • More
  • Cancel
  • New
Join FPGA to participate - click to join for free!
  • Share
  • More
  • Cancel
Group Actions
  • Group RSS
  • More
  • Cancel
Engagement
  • Author Author: Jan Cumps
  • Date Created: 4 May 2023 8:15 PM Date Created
  • Views 4929 views
  • Likes 8 likes
  • Comments 49 comments
  • pynq-z2
  • amdzynqultrasoundpulse
  • zynq
  • fpga
  • vivado
  • vhdl
  • pynq
  • spartan
Related
Recommended

Learning AMD Zynq: a project to generate a set of PWM signals. 2 - add overall control block, delay and pulse signal

Jan Cumps
Jan Cumps
4 May 2023
Learning AMD Zynq: a project to generate a set of PWM signals. 2 - add overall control block, delay and pulse signal

Continuation of  Learning AMD Zynq: a project to generate a set of PWM signals. 1 - problem statement and possible approach .

 yepe has a goal to create a set of signals for an ultrasone pulse generator.

image

Status after Post 1

In Post 1, we got the PWM and PWMN signals, and a first stab at the PULSE signal. Let's start at that stable point here, and try to add

  • the initial delay between PRF falling edge and the start of the pulse train
  • a PULSE signal that starts and ends exactly when the pulse train starts and ends.

Here's the design from the 1st blog:

image

The clocking wizard generates a 320 MHz clock. High enough to give the PWM signal a decent granularity for the dead times (2.5 ns steps).
The PWM generator generates 2 complementary signals, PWM and PWMN, with configurable deadband.
The PWM generator has an enable pin. When that pin is low, it will set PWM low and PWMN high, else it outputs the train of pulses

image image

Goal of this post:

  • Build a control block that will tell the PWM when to generate pulses (control its enable)
  • let that block also control the PULSE signal
  • establish the configurable? delay at the start
  • maybe handle PRF?

What this session will not do: handle GATE

Same as in post 1, the action will be in the comments. It's a collaborative exercise.

Update 4/5/2023:

Possible signal controller design (partly - not all states and signals implemented)

image

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;

package PulsePckg is

    component signal_controller is
        generic (
            start_delay_resolution : integer := 6;  -- bit width of the counter used delaying pulse train start
            train_length           : integer := 7;  -- bit width of the PWM burst train counter
            gate_delay_resolution  : integer := 6;  -- bit width of the counter used delaying the gate signal start 
            counter_resolution     : integer := 7   -- big enought o hold the largest of above
        );
        port (
            n_reset_i     : in   std_logic;                                                -- async reset
            clk_i         : in   std_logic;                                                -- Input clock.
            start_delay_i : in   std_logic_vector (start_delay_resolution - 1 downto 0);   -- Duty-cycle input.
            train_length_i: in   std_logic_vector (train_length - 1 downto 0);             -- how many PWMs in a burst train.
            prime_i       : in   std_logic;                                                -- allow cycle start
            fire_i        : in   std_logic;                                                -- start a cycle
            prf_o         : out  std_logic;                                                -- PRF
            enable_o      : out  std_logic;                                                -- enable pwm
            pulse_o       : out  std_logic;                                                -- PULSE
            gate_o        : out  std_logic;                                                -- GATE
            leds_o        : out std_logic_vector (3 downto 0)
        );
    end component;

end package;
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use ieee.numeric_std.all;


entity signal_controller is
    generic (
        train_length           : integer := 7;  -- bit width of the PWM burst train counter
        start_delay_resolution : integer := 6;  -- bit width of the counter used delaying pulse train start
        gate_delay_resolution  : integer := 6;  -- bit width of the counter used delaying the gate signal start 
        counter_resolution     : integer := 7   -- big enought o hold the largest of above
    );
    port (
        n_reset_i     : in   std_logic;                                                -- async reset
        clk_i         : in   std_logic;                                                -- Input clock.
        start_delay_i : in   std_logic_vector (start_delay_resolution - 1 downto 0);   -- Duty-cycle input.
        train_length_i: in   std_logic_vector (train_length - 1 downto 0);             -- how many PWMs in a burst train.
        prime_i       : in   std_logic;                                                -- allow cycle start
        fire_i        : in   std_logic;                                                -- start a cycle
        prf_o         : out  std_logic;                                                -- PRF
        enable_o      : out  std_logic;                                                -- enable pwm
        pulse_o       : out  std_logic;                                                -- PULSE
        gate_o        : out  std_logic;                                                -- GATE
        leds_o        : out std_logic_vector (3 downto 0)
    );
end signal_controller;

architecture arch of signal_controller is
    type states is (ready, delay, pulse, gate_delay, gate, done );
    signal counter : integer range 0 to 2**counter_resolution-1;
    signal state  : states;

begin


    clocked: process(clk_i)

    begin

        if rising_edge(clk_i) then
            -- sync reset
            if n_reset_i = '0' then
                counter <= 0;
                state <= ready;
                -- reset output states
                prf_o <= '1';
                enable_o <= '0';
                pulse_o <= '0';
                gate_o <= '0';
                leds_o <= (others => '0');
            else
                counter <= counter + 1;
                -- default output states
                prf_o <= '1';
                enable_o <= '0';
                pulse_o <= '0';
                gate_o <= '0';
                leds_o <= (others => '0');

                case State is

                    when ready =>  -- start a pulse group as soon as the fire bit is set
                        leds_o <= (0 => '1', others => '0');
                        -- check if the caller has reset the prime bit
                        if prime_i = '0' then
                            -- if yes, start if the fire bit is set.
                            if fire_i = '1' then
                                counter <= 0;
                                state <= delay;
                            end if;
                        end if;

                    when delay =>
                        leds_o <= (0 => '0', 1 => '1', others => '0');
                        prf_o <= '0';
                        if counter >= to_integer(unsigned(start_delay_i)) - 1 then
                            counter <= 0;
                            enable_o <= '1';
                            state <= pulse;
                        end if;

                    when pulse =>
                        leds_o <= (0 => '1', 1 => '1', others => '0');
                        enable_o <= '1';
                        prf_o <= '0';
                        if counter < to_integer(unsigned(train_length_i)) - 1 then  -- let the pulse change sync with last edge of PWM
                            pulse_o <= '1';
                        elsif counter = to_integer(unsigned(train_length_i)) - 1 then
                            pulse_o <= '1';
                            counter <= 0;
                            state <= gate_delay;
                        end if;

                    when gate_delay =>
                        leds_o <= (0 => '0', 1 => '0', 2 => '1', others => '0');
                        state <= gate;  -- todo implement

                    when gate =>
                        leds_o <= (0 => '1', 1 => '0', 2 => '1', others => '0');
                        state <= done;  -- todo implement

                    when done =>
                        leds_o <= (0 => '1', 1 => '1', 2 => '1', others => '0');
                        -- check if the caller has reset the fire bit
                        if fire_i = '0' then
                            -- if yes, prime if the prime_bit is set.
                            if prime_i = '1' then
                                counter <= 0;
                                state <= ready;
                            end if;
                        end if;

                end case;

            end if; -- sync reset
        end if; -- rising_edge

    end process clocked;

end architecture;

warning: the train length should always result in full PWM cycles. If you disable the PWM module before it had the chance to generate a full cycle, both PWM and PWMN will switch at the same time and not respect the deadband.

Block diagram:

image

Capture:

image

Jupyter:

image

Jupyter source:

{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# PWM with generic dead band and duty cycle resolution\n",
    "\n",
    "https://community.element14.com/technologies/fpga-group/b/blog/posts/learning-xilinx-zynq-a-school-project-to-generate-a-set-of-pwm-signals-1---problem-statement-and-possible-approach\n",
    "\n",
    "pwm_ultrasound_pulser.xpr"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 70,
   "metadata": {},
   "outputs": [],
   "source": [
    "from pynq import Overlay\n",
    "ol=Overlay(\"pwm_ultrasound_pulser.bit\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 71,
   "metadata": {},
   "outputs": [],
   "source": [
    "from pynq import MMIO\n",
    "RANGE = 8 # Number of bytes; 8/4 = 2x 32-bit locations which is all we need for this example"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 72,
   "metadata": {},
   "outputs": [],
   "source": [
    "duty_address = ol.ip_dict['axi_gpio_duty']['phys_addr']\n",
    "duty_register = MMIO(duty_address, RANGE) \n",
    "# Write 0x00 to the tri-state register at offset 0x4 to configure the IO as outputs.\n",
    "duty_register.write(0x4, 0x0) # Write 0x0 to location 0x4; Set tri-state to output"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 73,
   "metadata": {},
   "outputs": [],
   "source": [
    "band_address = ol.ip_dict['axi_gpio_band']['phys_addr']\n",
    "band_register = MMIO(band_address, RANGE) \n",
    "# Write 0x00 to the tri-state register at offset 0x4 to configure the IO as outputs.\n",
    "band_register.write(0x4, 0x0) # Write 0x0 to location 0x4; Set tri-state to output"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 74,
   "metadata": {},
   "outputs": [],
   "source": [
    "flags_address = ol.ip_dict['axi_gpio_flags']['phys_addr']\n",
    "flags_register = MMIO(flags_address, RANGE) \n",
    "# Write 0x00 to the tri-state register at offset 0x4 to configure the IO as outputs.\n",
    "flags_register.write(0x4, 0x0) # Write 0x0 to location 0x4; Set tri-state to output"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 75,
   "metadata": {},
   "outputs": [],
   "source": [
    "start_delay_address = ol.ip_dict['axi_gpio_start_delay']['phys_addr']\n",
    "start_delay_register = MMIO(start_delay_address, RANGE) \n",
    "# Write 0x00 to the tri-state register at offset 0x4 to configure the IO as outputs.\n",
    "start_delay_register.write(0x4, 0x0) # Write 0x0 to location 0x4; Set tri-state to output"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 76,
   "metadata": {},
   "outputs": [],
   "source": [
    "train_length_address = ol.ip_dict['axi_gpio_train_length']['phys_addr']\n",
    "train_length_register = MMIO(train_length_address, RANGE) \n",
    "# Write 0x00 to the tri-state register at offset 0x4 to configure the IO as outputs.\n",
    "train_length_register.write(0x4, 0x0) # Write 0x0 to location 0x4; Set tri-state to output"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 77,
   "metadata": {},
   "outputs": [],
   "source": [
    "def duty(duty):\n",
    "    duty_register.write(0x00, duty)\n",
    "    \n",
    "def band(band):\n",
    "    band_register.write(0x00, band)\n",
    "    \n",
    "def dutypct(duty):\n",
    "    duty_register.write(0x00, round((0x1F*2)/(100/duty)))\n",
    "    \n",
    "def fire():\n",
    "    flags_register.write(0x00, 1) # bit 0\n",
    "    flags_register.write(0x00, 0)\n",
    "\n",
    "def prime():\n",
    "    flags_register.write(0x00, 2) # bit 1\n",
    "    flags_register.write(0x00, 0)\n",
    "    \n",
    "def startdelay(startdelay):\n",
    "    start_delay_register.write(0x0, startdelay);\n",
    "\n",
    "def trainlength(trainlength):\n",
    "    train_length_register.write(0x0, trainlength);\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [],
   "source": [
    "duty(0x1F)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [],
   "source": [
    "dutypct(50)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 110,
   "metadata": {},
   "outputs": [],
   "source": [
    "band(2)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [],
   "source": [
    "startdelay(20)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 87,
   "metadata": {},
   "outputs": [],
   "source": [
    "trainlength(125)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 90,
   "metadata": {},
   "outputs": [],
   "source": [
    "prime()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 91,
   "metadata": {},
   "outputs": [],
   "source": [
    "fire()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 115,
   "metadata": {},
   "outputs": [],
   "source": [
    "trainlength(125)\n",
    "prime()\n",
    "fire()"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.10.4"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}

Scope capture (PWM, PWMN, PULSE, PRF)

0 dead time:
image

2 dead time:
image

Compare to requirement:

image

Example with longer initial delay and a longer pulse train, 5 pulses of dead band. The FPGA design is the same. This is done by writing different values to the registers:
image

Study of the edges. You see the PWM and PULSE signal, 0 dead band.
image

A few example settings that generate complete pulses. The first two generate 2 pulses, with a short start delay. The second 2 have a longer start delay and generate 5 pulses. The last one is retriggered in a software loop. I've also played with the deadbands.
image

Vivado project and Jupyter notebook are attached. They are for version 2022.1 and PYNQ-Z2 board
pwm_ultrasound_pulser_and_jupyter_20230506.zip

link to all posts.

  • Sign in to reply

Top Comments

  • Jan Cumps
    Jan Cumps over 2 years ago +1
    test of using a control block, that generates a PULSE signal and controls the pulse train:
  • Jan Cumps
    Jan Cumps over 2 years ago in reply to yepe +1
    The Pulse, Gate and PMW(n) can all be specified as number of CLK pulses. Pulse and PWM(n) have to be active atthe same time' for the same time. Gate hasto be active for the same time, but after a delay…
  • Jan Cumps
    Jan Cumps over 2 years ago in reply to yepe +1
    After running Synthesis, open the synthesis design. Then, you should have access to a IO window (not at my pc at the moment, but I think it's under the Windows menu. There you have to define to what…
Parents
  • yepe
    yepe over 2 years ago

    I am following along trying to implement the design on my end. I created the following block diagram with the Pwm.vhd file from your last post

    image

    Synthesis and implementation completes, but generating the bitstream fails. Maybe I did something wrong in the block diagram or in the customization of the blocks? Or maybe I am lacking a constraint file? The internal mechanisms of the AXI interconnects are a bit of a mystery for me Smiley

    Command: write_bitstream -force Pwm.bit
    Attempting to get a license for feature 'Implementation' and/or device 'xc7z020'
    INFO: [Common 17-349] Got license for feature 'Implementation' and/or device 'xc7z020'
    Running DRC as a precondition to command write_bitstream
    INFO: [IP_Flow 19-234] Refreshing IP repositories
    INFO: [IP_Flow 19-1704] No user IP repositories specified
    INFO: [IP_Flow 19-2313] Loaded Vivado IP repository 'C:/Xilinx/Vivado/2022.2/data/ip'.
    INFO: [DRC 23-27] Running DRC with 2 threads
    ERROR: [DRC NSTD-1] Unspecified I/O Standard: 15 out of 15 logical ports use I/O standard (IOSTANDARD) value 'DEFAULT', instead of a user assigned specific value. This may cause I/O contention or incompatibility with the board power or connectivity affecting performance, signal integrity or in extreme cases cause damage to the device or the components to which it is connected. To correct this violation, specify all I/O standards. This design will fail to generate a bitstream unless all logical ports have a user specified I/O standard value defined. To allow bitstream creation with unspecified I/O standard values (not recommended), use this command: set_property SEVERITY {Warning} [get_drc_checks NSTD-1].  NOTE: When using the Vivado Runs infrastructure (e.g. launch_runs Tcl command), add this command to a .tcl file and add that file as a pre-hook for write_bitstream step for the implementation run. Problem ports: band_i[3:0], duty_i[5:0], clk_i, enable_i, n_reset_i, pwmA_o, and pwmB_o.
    ERROR: [DRC UCIO-1] Unconstrained Logical Port: 15 out of 15 logical ports have no user assigned specific location constraint (LOC). This may cause I/O contention or incompatibility with the board power or connectivity affecting performance, signal integrity or in extreme cases cause damage to the device or the components to which it is connected. To correct this violation, specify all pin locations. This design will fail to generate a bitstream unless all logical ports have a user specified site LOC constraint defined.  To allow bitstream creation with unspecified pin locations (not recommended), use this command: set_property SEVERITY {Warning} [get_drc_checks UCIO-1].  NOTE: When using the Vivado Runs infrastructure (e.g. launch_runs Tcl command), add this command to a .tcl file and add that file as a pre-hook for write_bitstream step for the implementation run.  Problem ports: band_i[3:0], duty_i[5:0], clk_i, enable_i, n_reset_i, pwmA_o, and pwmB_o.
    WARNING: [DRC ZPS7-1] PS7 block required: The PS7 cell must be used in this Zynq design in order to enable correct default configuration.
    INFO: [Vivado 12-3199] DRC finished with 2 Errors, 1 Warnings
    INFO: [Vivado 12-3200] Please refer to the DRC report (report_drc) for more information.
    ERROR: [Vivado 12-1345] Error(s) found during DRC. Bitgen not run.
    INFO: [Common 17-83] Releasing license: Implementation
    15 Infos, 1 Warnings, 0 Critical Warnings and 3 Errors encountered.
    write_bitstream failed
    ERROR: [Common 17-39] 'write_bitstream' failed due to earlier errors.

    Looking at the log, it seems to be related to IO

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • More
    • Cancel
Comment
  • yepe
    yepe over 2 years ago

    I am following along trying to implement the design on my end. I created the following block diagram with the Pwm.vhd file from your last post

    image

    Synthesis and implementation completes, but generating the bitstream fails. Maybe I did something wrong in the block diagram or in the customization of the blocks? Or maybe I am lacking a constraint file? The internal mechanisms of the AXI interconnects are a bit of a mystery for me Smiley

    Command: write_bitstream -force Pwm.bit
    Attempting to get a license for feature 'Implementation' and/or device 'xc7z020'
    INFO: [Common 17-349] Got license for feature 'Implementation' and/or device 'xc7z020'
    Running DRC as a precondition to command write_bitstream
    INFO: [IP_Flow 19-234] Refreshing IP repositories
    INFO: [IP_Flow 19-1704] No user IP repositories specified
    INFO: [IP_Flow 19-2313] Loaded Vivado IP repository 'C:/Xilinx/Vivado/2022.2/data/ip'.
    INFO: [DRC 23-27] Running DRC with 2 threads
    ERROR: [DRC NSTD-1] Unspecified I/O Standard: 15 out of 15 logical ports use I/O standard (IOSTANDARD) value 'DEFAULT', instead of a user assigned specific value. This may cause I/O contention or incompatibility with the board power or connectivity affecting performance, signal integrity or in extreme cases cause damage to the device or the components to which it is connected. To correct this violation, specify all I/O standards. This design will fail to generate a bitstream unless all logical ports have a user specified I/O standard value defined. To allow bitstream creation with unspecified I/O standard values (not recommended), use this command: set_property SEVERITY {Warning} [get_drc_checks NSTD-1].  NOTE: When using the Vivado Runs infrastructure (e.g. launch_runs Tcl command), add this command to a .tcl file and add that file as a pre-hook for write_bitstream step for the implementation run. Problem ports: band_i[3:0], duty_i[5:0], clk_i, enable_i, n_reset_i, pwmA_o, and pwmB_o.
    ERROR: [DRC UCIO-1] Unconstrained Logical Port: 15 out of 15 logical ports have no user assigned specific location constraint (LOC). This may cause I/O contention or incompatibility with the board power or connectivity affecting performance, signal integrity or in extreme cases cause damage to the device or the components to which it is connected. To correct this violation, specify all pin locations. This design will fail to generate a bitstream unless all logical ports have a user specified site LOC constraint defined.  To allow bitstream creation with unspecified pin locations (not recommended), use this command: set_property SEVERITY {Warning} [get_drc_checks UCIO-1].  NOTE: When using the Vivado Runs infrastructure (e.g. launch_runs Tcl command), add this command to a .tcl file and add that file as a pre-hook for write_bitstream step for the implementation run.  Problem ports: band_i[3:0], duty_i[5:0], clk_i, enable_i, n_reset_i, pwmA_o, and pwmB_o.
    WARNING: [DRC ZPS7-1] PS7 block required: The PS7 cell must be used in this Zynq design in order to enable correct default configuration.
    INFO: [Vivado 12-3199] DRC finished with 2 Errors, 1 Warnings
    INFO: [Vivado 12-3200] Please refer to the DRC report (report_drc) for more information.
    ERROR: [Vivado 12-1345] Error(s) found during DRC. Bitgen not run.
    INFO: [Common 17-83] Releasing license: Implementation
    15 Infos, 1 Warnings, 0 Critical Warnings and 3 Errors encountered.
    write_bitstream failed
    ERROR: [Common 17-39] 'write_bitstream' failed due to earlier errors.

    Looking at the log, it seems to be related to IO

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • More
    • Cancel
Children
  • Jan Cumps
    Jan Cumps over 2 years ago in reply to yepe

    After running Synthesis, open the synthesis design.

    Then, you should have access to a IO window (not at my pc at the moment, but I think it's under the Windows menu.

    There you have to define to what FPGA ball each external signalhas to connect.

    Double-checkif you generated a wrapper for the board design, and that yo've set that wrapper as the Top of the design. I tend to forget that Slight smile, and then get implementation errors....

    • Cancel
    • Vote Up +1 Vote Down
    • Sign in to reply
    • More
    • Cancel
  • yepe
    yepe over 2 years ago in reply to Jan Cumps

    You are right. I forgot to generate the design wrapper and then after fiddling with the constraint wizard and changing the package pins to Y18&Y19 it now generates the bitstream! (although some critical errors remain)

    image

    I transferred the generated bit and hwh file, then ran the instructions through JupyterLab and it shows the following error
    image

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • More
    • Cancel
  • Jan Cumps
    Jan Cumps over 2 years ago in reply to yepe

    If you are sure that you have the right HWH and BIT file transferred, and you get these errors,
    reboot the board.

    The registers should exist, with the same name as the AXI_GPIO blocks

    image

    Normally, when the bitfile is loaded in step 1 of the Jupyter notebook, they should be available. But I had instances where this was not picked up and I had to reboot.

    • Cancel
    • Vote Up +1 Vote Down
    • Sign in to reply
    • More
    • Cancel
  • yepe
    yepe over 2 years ago in reply to Jan Cumps

    I cought a typo with the in cell 3 

    duty_address = ol.ip_dict['axis_gpio_duty']['phys_addr']
    - removed the extra s but it still gives error

    ---------------------------------------------------------------------------
    KeyError                                  Traceback (most recent call last)
    Input In [3], in <cell line: 1>()
    ----> 1 duty_address = ol.ip_dict['axi_gpio_duty']['phys_addr']
          2 duty_register = MMIO(duty_address, RANGE)
          3 # Write 0x00 to the tri-state register at offset 0x4 to configure the IO as outputs
    
    File /usr/local/share/pynq-venv/lib/python3.10/site-packages/pynqutils/runtime/repr_dict.py:43, in ReprDict.__getitem__(self, key)
         42 def __getitem__(self, key):
    ---> 43     obj = super().__getitem__(key)
         44     if type(obj) is dict:
         45         return ReprDict(obj, expanded=self._expanded, rootname=key)
    
    KeyError: 'axi_gpio_duty'

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • More
    • Cancel
  • Jan Cumps
    Jan Cumps over 2 years ago in reply to yepe

    I have this little script handy, that looks for the 2 files needed by PYNQ, and copies them in your Vivado project root.

    https://gist.github.com/jancumps/529bbfc116f765626e7b4cb34597a4ae

    Afterr the bitstream is generated,
    Copy all the content,
    paste it in the little edit box of the Tcl Console at the bottom 
    press enter


    And you'll find both files together, in that Vivado "Project Root" (typically the directory one level up from your project files)

    image

    • Cancel
    • Vote Up +1 Vote Down
    • Sign in to reply
    • More
    • Cancel
element14 Community

element14 is the first online community specifically for engineers. Connect with your peers and get expert answers to your questions.

  • Members
  • Learn
  • Technologies
  • Challenges & Projects
  • Products
  • Store
  • About Us
  • Feedback & Support
  • FAQs
  • Terms of Use
  • Privacy Policy
  • Legal and Copyright Notices
  • Sitemap
  • Cookies

An Avnet Company © 2025 Premier Farnell Limited. All Rights Reserved.

Premier Farnell Ltd, registered in England and Wales (no 00876412), registered office: Farnell House, Forge Lane, Leeds LS12 2NE.

ICP 备案号 10220084.

Follow element14

  • X
  • Facebook
  • linkedin
  • YouTube