I like the way artificial intelligence works, but I like the way it works. I like the way it works, and I like the way it works. I like the way it works, and I like the way it works
1. Purpose of the experiment
Create a custom IP core mounted on AXI bus with HDL +Vivado
2. Experimental procedures
2.1. Create a new project
2.2. Invoke the Create and Package IP Wizard to Create a new AXI-Lite slave IP
chooseTools
->Create and Package IP
Edit the created IP address
- Led_controller_v1_0.v – instantiates all aXI-Lite interfaces, in which case only one interface exists
- Led_controller_v1_0_s00_axi. v – contains axi4-Lite interface functionality for handling PL peripherals and PS side software
Open theled_controller_v1_0_S00_AXI.v
File, findUsers to add ports here
, and then add the desired port after:
And then at the end of the file, findAdd user logic here
And then add the logic function code after it:
Save the file and open itled_controller_v1_0.v
File, findUsers to add ports here
, add port:
Instantiate the port we just added in the top-level file and save the file:
Update the IP core
Packaging IP core
Then close the project and the IP core is created successfully.
2.3. Add IP core to Block Design for Design
Create Block Design:
Click Add IP, search for led, Addled_controller
IP:
Because LEDs_out is connected to the onboard LED, click on the pin and press downctrl+t
Export pin:
Add Zynq PS core, automatic connection:
Press theF6
Verification design:
Create Block Design HDL file:
Add LED pin constraint file:
##LEDs
set_property -dict { PACKAGE_PIN R14 IOSTANDARD LVCMOS33 } [get_ports { LEDs_out_0[0]}]; #IO_L6N_T0_VREF_34 Sch=LEDs_out_0[0]
set_property -dict { PACKAGE_PIN P14 IOSTANDARD LVCMOS33 } [get_ports { LEDs_out_0[1]}]; #IO_L6P_T0_34 Sch=LEDs_out_0[1]
set_property -dict { PACKAGE_PIN N16 IOSTANDARD LVCMOS33 } [get_ports { LEDs_out_0[2]}]; #IO_L21N_T3_DQS_AD14N_35 Sch=LEDs_out_0[2]
set_property -dict { PACKAGE_PIN M14 IOSTANDARD LVCMOS33 } [get_ports { LEDs_out_0[3]}]; #IO_L23P_T3_35 Sch=LEDs_out_0[3]
Copy the code
2.4. Generate Bitstream, open implementation design, export hardware file, and run SDK
2.5. Create an empty application project
File->New->Application Project, select create an empty Project:
2.6. Adding a driver library
Select led_test_bsp before the following operation!!
chooseXilinx
->Repositories
:
Add the directory where the IP core resides. After adding, the SDK will automatically scan the added directory and recompile the project to add a new driver file:
Check that the library is dispatched to the LED_Controller peripheral, open itsystem.mss
Led_controller_0 exists in the peripheral driver:
Click on the topmodify this BSP's Setting
Check driver Settings:
At this point, led_ControlerIP core hardware design completed, BSP driver added completed, you can start to write application test procedures.
2.7. Write application code
In the firstsrc
Create a C file under this folder:
/** * @file led_test.c * @brief led_controler ip test * @author mculover666 * @date 2018/11/10 * */
#include "xparameters.h"
#include "xil_io.h" //led_controller.h uses Xil_Out32
#include "led_controller.h"
#include "xil_printf.h"
#define LED_BASE_ADDR XPAR_LED_CONTROLLER_0_S00_AXI_BASEADDR
#define LED_REG0 0
#define DELAY 50000000
int main(a)
{
int temp = 0;
int led_value = 0;
int i = 0;
xil_printf("led_controller ip test\r\n");
xil_printf("----------------------\r\n");
while(1)
{
/* write reg0 */
LED_CONTROLLER_mWriteReg(LED_BASE_ADDR,LED_REG0,led_value);
/* read reg0 */
temp = LED_CONTROLLER_mReadReg (LED_BASE_ADDR,LED_REG0);
/* show value */
xil_printf("led = %d",led_value);
xil_printf("\ttemp = %d\r\n",temp);
if(led_value < 15)
led_value++;
else
led_value = 0;
for(i=0; i<DELAY; i++); }}Copy the code
2.9. Run the configuration and observe the result
3. Experiment summary
I did this experiment for a long time, and finally I looked at the lamp and thought for a long time:
- From an experimental point of view: HDL is used to create an IP core mounted on AXI bus to control LED, and then under memory mapping, the four registers of this IP core will have their own address, CPU access to the register by this address, for simple operation, there is generally a base address, the other registers are offset relative to this base address. So the control code only needs to read and write registers;
- From the point of view of embedded principle, in fact, the design is based on the register, the hardware depends on the data of the register to work, the register is mounted on the bus, so the register will have an address (register mapping), we can access the data of the address in the memory space through the pointer;
- From the perspective of embedded development, usually register address mapping are made by the manufacturer when the factory map is good, we only need to check the chip reference manual programming, now the whole hardware can be their own design, just register address mapping in a fixed interval period (AXI machine addresses from 1 g), have become more flexible, It also shows that the design of the whole digital system is changing from on-board design to on-board design. The task that can be done by a board only needs a chip now