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
  • 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
Eye On Intelligence Challenge
  • Challenges & Projects
  • Design Challenges
  • Eye On Intelligence Challenge
  • More
  • Cancel
Eye On Intelligence Challenge
Blog Blog 3 - Custom IP implementation
  • Blog
  • Forum
  • Documents
  • Polls
  • Files
  • Members
  • Mentions
  • Sub-Groups
  • Tags
  • More
  • Cancel
  • New
Join Eye On Intelligence Challenge to participate - click to join for free!
  • Share
  • More
  • Cancel
Group Actions
  • Group RSS
  • More
  • Cancel
Engagement
  • Author Author: pandoramc
  • Date Created: 10 Oct 2024 4:21 AM Date Created
  • Views 331 views
  • Likes 8 likes
  • Comments 1 comment
  • soc
  • fpga
  • custom ip
  • Eye on Intelligence Challenge
  • digilent
  • zynq-7000
Related
Recommended

Blog 3 - Custom IP implementation

pandoramc
pandoramc
10 Oct 2024

The IP catalog is really wide in terms of logical blocks with AXI interface for system integration with the Hard Processor (Zynq7) or Soft Processor (Microblaze V). In the last blog, an AXI GPIO was integrated to share data between the HP and the Programmable Logic (PL), but sometimes the required behavior could not meet the specifications with the available  AXI catalog. With this in mind, it is necessary to design our custom logic with an interface to the processor for configuration and data transfer in the both devices. This brings us to the use of the Create and Package New IP, available in the Tools menu. For our purposes, the Create a new AXI4 peripheral is selected since our project will not be a part of a new IP as a whole, but a new device will be added to the current project. To achieve a device compatibility, the data width must be 32-bit, but a 64-bit interface could be used according to the architecture. On the other hand, the new IP will work according to the configuration registers, consequently, a Lite Slave interface is chosen because the communication between the processor and the soft peripheral is not a high priority.

NewIPConfig

For this process, a PWM generator will be created and only will only have the behavior of a counter until the PERIOD value is met, and a COMPARATOR register generates a high state when the counter starts, and a low state when a comparison occurs. Finally, the processor is able to query the COUNTER value to monitor the process, but the interface does not allow writing to the register. The described behavior is as follows,

Timming

As the image shows, the frequency and duty cycle are configured by the writing to the PERIOD and COMPARATOR registers, but this is not possible directly. In the first step, the logic must be described and connected to the logic communication from an AXI4 interface, which is created from the IP wizard, and the interfaces must be instantiated at the appropriate location. A high level view is shown below, where an instance of our logic block is created and the wiring is made by the available registers in the template. According to our configuration, the DemoIP block is created with 4 memory locations, which is the minimum configurable in the IP wizard, for the data storage and behavior configuration of the behavior. Remember! the addressing is Byte wide, but the data width is 32 bits, consequently, the memory offset is in multiples of four Bytes.

Instance

In this case, the PWM generator has the following description,

module pwm_gen (
	input aclk, 
	input resetn, 
	input [31:0] period, 
	input [31:0] comparator,

	output reg [31:0] counter,
	output pwm
);

	always @(posedge aclk)
		if (!resetn)
			counter <= 0;
		else 
			if (counter < period)
				counter <= counter + 1;
			else 
				counter <= 0;

	assign pwm = (comparator > counter)? 1'b1: 1'b0;

endmodule

Once the IP is packaged, the user can create many instances as the logic resources are available. For the newest platform, the DemoIP will be instantiated three times.

Platform

Since the PWM_n terminals are not available in the default configuration, this terminal must be configured with a XDC file. Here, the pins are configured in two Arduino terminals and one in the LED0 to validate the configuration visually.

set_property -dict { PACKAGE_PIN R14    IOSTANDARD LVCMOS33 } [get_ports { PWM_0 }]; #IO_L6N_T0_VREF_34 Sch=LED0
set_property -dict { PACKAGE_PIN T15   IOSTANDARD LVCMOS33 } [get_ports { PWM_2  }]; #IO_L5N_T0_34            Sch=CK_IO5
set_property -dict { PACKAGE_PIN R16   IOSTANDARD LVCMOS33 } [get_ports { PWM_3  }]; #IO_L19P_T3_34           Sch=CK_IO6

Finally, the Base Address for Custom IP, by default, starts in the address 0x43C00000. On the other hand, the AXI GPIO holds the provided base address from the last project. Below, the memory map is shown.

Memory Map

Before the programming of a new application, the platform must be updated in the Vitis Unified IDE. To do it, the first step is change of the XSA platform definition. When the hardware is exported in Vivado, all the definitions and the newest .bit file is grouped for the platform definition, but Vitis has a bug and the XSA swithching is not sufficient enough to redefine the architecture. The second step is remove the current bit file from the Sources>hw Vitis component, and import the last synthesis of the architecture available in the PROJECT.runs folder from the Vivado project. When the last step is made, clean and compile the Platform component. This will create the new export folder where the .bit file is available in the last version. Finally, the Application component launch.json must be updated to use that bit file, now we know the file location in the platform and the Bitstream File field must be updated.

{gallery}Update Process

image

Switch XSA: Update the platform definition

image

Bitstream replacement: Delete the current Bitstream and import the newest

image

Bitstream File location: Update the Bitstream location in the Application component

differ command

Bitstream verification: If the Bitstream replacement is success, then the files must not differ

In the software perpective, we can create a pair of files PWMGen.c and PWMGen.h for the configuration management. Here, there are two perspectives for configuration, Time and Duty Cicle. For the frequency configuration, we only need the relationship between the AXI frequency and the desired Frequency, consequently, the PERIOD register must be configured as,

image

and the COMPARATOR register has two methods: the duty, using a percentage of the PERIOD register, and time, the relationship between the desired time and the AXI clock. All methods and test can be viewed in the codes below

#ifndef __PWMGEN_H__
#define __PWMGEN_H__

#include <xil_types.h>

void DemoFrequency(UINTPTR Addr, u32 Frequency);
void DemoDuty(UINTPTR Addr, float percent);
void DemoTime(UINTPTR Addr, float time);

#endif

#include "PWMGen.h"
#include "xparameters.h"
#include <xil_types.h>

#ifndef FCPU
#define FCPU 100000000UL
#endif

void DemoFrequency(UINTPTR Addr, u32 Frequency){
    u32 Period = FCPU/Frequency;
    *((volatile u32 *)Addr) = Period;
}

void DemoDuty(UINTPTR Addr, float percent){
    u32 Comparator = percent*(*((volatile u32 *)Addr));
    *((volatile u32 *)(Addr + 4)) = Comparator;
}

void DemoTime(UINTPTR Addr, float time){
    u32 Comparator = time*FCPU;
    *((volatile u32 *)(Addr + 4)) = Comparator;
}

#include <xil_io.h>
#include <xil_types.h>
#include "xparameters.h"
#include "PWMGen.h"

int main(void){
    uint32_t btnIn;
    uint32_t ledState;

    DemoFrequency(XPAR_DEMOIP_0_BASEADDR, 1);
    DemoDuty(XPAR_DEMOIP_0_BASEADDR, .5);

    DemoFrequency(XPAR_DEMOIP_1_BASEADDR, 50);
    DemoTime(XPAR_DEMOIP_1_BASEADDR, 1e-3);

    DemoFrequency(XPAR_DEMOIP_2_BASEADDR, 1000);
    DemoDuty(XPAR_DEMOIP_2_BASEADDR, .75);

    while(1){
        ledState = Xil_In32(XPAR_AXI_GPIO_0_BASEADDR);
        btnIn = Xil_In32(XPAR_AXI_GPIO_0_BASEADDR + 8);
        if(btnIn & 0x08){
            ledState &= ~0x07;
            ledState |= (btnIn & 0x07);
        }else{
            ledState &= ~0x38;
            ledState |= (btnIn & 0x07) << 3;
        }
        Xil_Out32(XPAR_AXI_GPIO_0_BASEADDR, ledState);
    }
}

The main code holds the beavior implemented in the last blog and the methods generates the waveforms below, proving the implemented code reflects the mathematical and logic reasoning to bring a Hardware Abstraction Layer (HAL) for our Custom IP

Waveform generation

  • Sign in to reply
  • DAB
    DAB 9 months ago

    Very cool.

    • Cancel
    • Vote Up 0 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