=====Simulating a Custom IP core using a Zynq processor=====
{{ :zybo:zybo_revb-box-1000.png?nolink&400 |}}
----
====Prerequisites====
* Completed the Zybo [[zybo:gsg|Getting Started Guide]]
* Completed the Zybo [[zybo:custom_ip_cores|Creating Custom IP Cores Guide]]
----
Created in Vivado 2015.1 and SDK 2015.1
This demo is great for the ZYBO but is also applicable for any microblaze design. This tutorial simulates the custom IP core with a microblaze project to avoid the additional licenses associated with the ZYNQ BFM core and AXI BFM core. Unfortunately, this results in a significantly more complex setup for the simulation but provides a solution for simulation with built-in licenses for series-7 boards in Vivado.
We will be using the PWM core written in the Zybo [[zybo:custom_ip_cores|Creating Custom IP Cores Guide]]
----
===1. Open vivado and create a new project with Nexys4 DDR board===
>1.1) Create a new project with name: "ip_core_simulation".
>
>{{:zybo:zybo:sim1.png?nolink&600|}}
>1.2) Click **Next**.
>
>{{:zybo:zybo:sim2.png?nolink&600|}}
>1.3) Select the **Nexys4 DDR**.
>
>{{:zybo:zybo:sim3.png?nolink&600|}}
>1.4) Click **Finish**.
>
>{{:zybo:zybo:sim4.png?nolink&600|}}
===2. Create Microblaze Block Design===
>2.1) Select **Create block design**.
>
>{{:zybo:zybo:sim8.png?nolink&300|}}
>2.2) Click **OK**.
>
>{{:zybo:zybo:sim9.png?nolink&400|}}
>2.3) Add microblaze IP block.
>
>{{:zybo:zybo:sim10.png?nolink&300|}}
>2.4) Add My_PWM_Core.
>
>{{:zybo:zybo:sim14.png?nolink&300|}}
>2.5) Run block automation and run connection automation.
>2.6) Make PMW0, PWM1, PWM2 and PWM3 all external connections.
>
>{{:zybo:zybo:sim18.png?nolink&600|}}
>2.7) Change the source of the input clock to single ended clock.
>
>{{:zybo:zybo:sim44.png?nolink&800|}}
>2.8) Double-click the clocking wizard block and change the reset type to **active low**.
>
>{{:zybo:zybo:sim20.png?nolink&800|}}
>2.9) Create the HDL wrapper
>
>{{:zybo:zybo:sim19.png?nolink&400|}}
===3. Run Synthesis, Implementation and Export hardware design===
>3.1) Click **Run Implementation**.
>
>{{:zybo:zybo:sim23.png?nolink&200|}}
>3.2) Click **File->Export->Export Hardware**.
>
>{{:zybo:zybo:sim24.png?nolink&400|}}
>3.3) Click **OK**.
>
>{{:zybo:zybo:sim25.png?nolink&400|}}
>3.4) Launch the SDK.
===4. Create program to test your IP core===
>4.1) Create new application.
>
>{{:zybo:zybo:sim29.png?nolink&600|}}
>4.2) Enter Project name "custom_ip_simulation" and click **Next**.
>
>{{:zybo:zybo:sim31.png?nolink&600|}}
>4.3) Select **Empty Application** and click **Finish**.
>
>{{:zybo:zybo:sim32.png?nolink&600|}}
>4.4) Add main.c
>4.5) We are going to start with the program from the Creating a custom IP core tutorial and modifying it for simulation. The original code looks like this:
>
#include "xparameters.h"
#include "xil_io.h"
#define MY_PWM XPAR_MY_PWM_CORE_0_S00_AXI_BASEADDR
int main(){
int num, i;
while(1){
if(num == 100)
num = 0;
else
num++;
Xil_Out32(MY_PWM, num);
Xil_Out32((MY_PWM+4), num);
Xil_Out32((MY_PWM+8), num);
Xil_Out32((MY_PWM+12), num);
for(i=0;i<300000; i++);
}
}
>4.6) A delay loop of 300000 is going to take a while to simulate so choosing a smaller number like 30 will speed up simulation. Change the delay loop to 30. Save the project and exit SDK.
===5. Associate ELF created in SDK with microblaze design===
>5.1) Right Click **Simulation Sources**. Click **Add Sources**.
>
>{{:zybo:zybo:sim33.png?nolink&400|}}
>5.2) Select **Add or create simulation sources**. Click **Next**.
>
>{{:zybo:zybo:sim34.png?nolink&600|}}
>5.3) Click the green plus symbol. Select **Add Files...**
>
>{{:zybo:zybo:sim35.png?nolink&600|}}
>5.4) Navigate to **"your work folder"/ip_core_simulation.sdk/custom_ip_core/Debug/**. Add **custom_ip_simulation.elf**.
>
>{{:zybo:zybo:sim36.png?nolink&600|}}
>5.5) Click **Finish**.
>
>{{:zybo:zybo:sim37.png?nolink&600|}}
>5.6) Right click **custom_ip_core.elf**. Click **Associate ELF File...** //NOTE: if Vivado asks to generate output products then click generate output products and repeat this step.//
>
>{{:zybo:zybo:sim38.png?nolink&600|}}
>5.7) Click the **...** button
>
>{{:zybo:zybo:sim42.png?nolink&600|}}
>5.8) Select **custom_ip_simulation.elf**. Click **OK**.
>
>{{:zybo:zybo:sim43.png?nolink&600|}}
===6. Create Test Fixture===
>6.1) Add a new simulation file named "test.v".
>6.2) Copy the following code into "test.v":
>
`timescale 1ns / 1ps
module test();
wire PWM0_tb;
wire PWM1_tb;
wire PWM2_tb;
wire PWM3_tb;
reg clk = 0;
design_1_wrapper uut(
.PWM0(PWM0_tb),
.PWM1(PWM1_tb),
.PWM2(PWM2_tb),
.PWM3(PWM3_tb),
.clk_in1(clk),
.reset(1)
);
always
#5 clk <= ~clk;
endmodule
===7. Run Simulation===
>Click **Run behavioral simulation**.
>
>{{:zybo:zybo:sim64.png?nolink&500|}}
===8. Celebrate===
>It works! We can now simulate IP cores
>
>{{:zybo:sim_works.png?nolink&800|}}
{{tag>learn programmable-logic tutorial zybo}}