CMPE691 : Reconfigurable System Design

Discussion 7

Dr Ryan Robucci and Saad Rahman

October 11,2018; Oct 10,2018

Objective

Reference

Material From

  1. Intel custom component creation manual ftp://ftp.intel.com/Pub/fpgaup/pub/Intel_Material/18.1/Tutorials/Making_Qsys_Components.pdf
  2. ftp://ftp.intel.com/pub/fpgaup/pub/Intel_Material/18.1/Tutorials/Linux_On_DE_Series_Boards.pdf

Tools :

  1. Quartus Prime (Lite).
  2. Platform designer
  3. Putty or Mobaxterm (For serial communication) or minicom for Linux

Custom IP creation in Platform Designer

Steps :

  1. Download the system CD of De1-SoC board from here. Another link from Terasic De1-SoC resources page (Choose ref.F variant from the page).

  2. Extract the zip and open the base project from this directory DE1-SoC_v.5.0.1_HWrevF_SystemCD\Demonstrations\SOC_FPGA\my_first_hps-fpga\fpga-rtl\soc_system.qpf

  3. After opening the project you’ll see an prompt to upgrade the IP. Click on Launch IP Upgrade Tool and it will open a new window pop up. Then hit Perform Automatic Upgrade. It’s recommended,not a required step.

Figure 1
  1. Add two verilog files with the following codes. This is the code which models our custom IP. It’s a 32 bit register which stores the data and then returns the data after incrementing once.

reg32.v

module reg32 (clock, resetn, D, byteenable, Q);
input clock, resetn;
input [3:0] byteenable;
input [31:0] D;
output reg [31:0] Q;
wire [31:0] D_plus;
// Adding one here
assign D_plus = D + 1;
always@(posedge clock)
if (!resetn)
Q <= 32'b0;
else
begin
// Enable writing to each byte separately
    if (byteenable[0]) Q[7:0] <= D_plus[7:0];
    if (byteenable[1]) Q[15:8] <= D_plus[15:8];
    if (byteenable[2]) Q[23:16] <= D_plus[23:16];
    if (byteenable[3]) Q[31:24] <= D_plus[31:24];
end
endmodule

reg32_avalon_interface.v

module reg32_avalon_interface (clock, resetn, writedata, readdata, write, read,
byteenable, chipselect, Q_export);
// signals for connecting to the Avalon fabric
input clock, resetn, read, write, chipselect;
input [3:0] byteenable;
input [31:0] writedata;
output [31:0] readdata;
// signal for exporting register contents outside of the embedded system
output [31:0] Q_export;
wire [3:0] local_byteenable;
wire [31:0] to_reg, from_reg;
assign to_reg = writedata;
assign local_byteenable = (chipselect & write) ? byteenable : 4'd0;
reg32 U1 ( .clock(clock), .resetn(resetn), .D(to_reg), .byteenable(local_byteenable),
.Q(from_reg) );
assign readdata = from_reg;
assign Q_export = from_reg;
endmodule

The description of these signals are as follows.

Figure 2
  1. Then go to Tools -> Platform Designer and open soc_system.qsys file when prompted.

  2. Then click new to add a new custom component from the Platform Designer. It’s in the upper right portion and below the IP Catalog box. A new window like Figure 3 will pop up. Fill up the Name,Display name and Group boxes.

Figure 3
  1. Next, we add the files that describe the component. Go to the Files tab, depicted in Figure 4, and then click on the Add File... button under Synthesis Files to browse and select the top-level file reg32_avalon_interface.v. Run the analysis of the top-level file by clicking on the Analyze Synthesis Files button. Platform Designer analyzes this file to determine the types of interfaces that are used by the component. Optionally, you can also add the file reg32.v to the list of Synthesis Files. Then click the Copy from Synthesis Files button under Verilog Simulation Files to add the files for simulation. If the Component Editor finds any errors when analyzing the top-level file, then they will need to be fixed and the code re-analyzed. Once no syntax errors are present, then the next step is to specify the types of interfaces that are used by the component.

Figure 4
  1. Then click on the 1Signals & Interfaces1 tab to specify the meaning of each interface port in the top-level entity. This leads to the window in Figure 5.

Figure 5
  1. To define correctly the meaning of each signal, it is necessary to specify the correct types of interface, put the signals in the correct interface, and specify the signal type for each signal. For the clock [1] signal, select <<add interface>> and select Clock Input as in Figure 6. Now drag and drop the signal clock [1] into Clock Input interface and change its Signal Type to clk, as shown in Figure 7.

Figure 6

Figure 7
  1. For the resetn signal, drag and drop it into the Reset Input interface and Click Signal Type to reset_n, as indicated in Figures 8.

Figure 8
  1. Finally, the Q_export signal must be visible outside the generated system,so it requires a new interface which is not a part of the Avalon Memory-Mapped Interface. Click on the <<add interface>>, name it conduit_end, and specify its type as Conduit, as shown in Figure 9. Drag and drop Q_export into the newly created conduit interface.The Signal Type for a conduit signal does not matter, so Q_export does not need to be edited. The rest of the signals shown in the Component Editor already have correct interface types as their names are recognizable as specific Avalon signals. The Component Editor window should now appear as shown in Figure 10.

Figure 9

Figure 10
  1. Note that there are still some error messages. The first error message states that the avalon_slave_0 interface must have an Associated Clock and an Associated Reset. Click on Avalon_slave_0 then select clock_sink as this clock and clock_reset as the reset, as indicated in Figure 11. Also note in Figure 11 that under the Timing heading we have changed the parameter called Read wait for the avalon_slave_0 interface from its default value, which was 1, to the value 0. This parameter represents the number of Avalon clock signals that the component requires in order to respond to a read request. Our register can respond immediately, so we do not need to use the default of 1 wait cycle.

Figure 11
  1. The remaining error messages state that the clock_reset interface must have an associated clock. Click on clock_reset,set this clock to clock_sink, as depicted in Figure 12. Then click on conduit_end and set Associated Clock and Associated reset as clock_sink and clock_reset respectively as per Figure 13.Now, there should be no error messages left. Click Finish to complete the creation of the custom component, and save the component when prompted to do so.

Figure 12

Figure 13

Integration of custom IP

  1. After saving the custom IP. Add the custom IP from My Own IP Cores group and hit Finish when the new parameter window appears. Then add another PIO (Parallel IO) from Processors and Peripherals -> Peripherals -> PIO (Parallel I/O) Intel FPGA IP and in the new parameter window set the width as 32 bits and direction as Input

Figure 14
  1. Set up the connections like Figure 15. The hps instantiation can’t be seen here but the s1 port of both PIO and custom IP is connected with h2f_lw_axi_master bus of the hps. Then on the export tab double click beside the conduit end of both aforementioned IPs as per the Figure 15. This will be visible as the output and input pin of the custom IP and PIO respectively in the generated HDL.If there is some base address overlapping. Go to System -> Assign Base Addresses to resolve the error and take a note of the base addresses of the custom IP and the PIO depicted in Figure 15 . We will need that for the later part.

Figure 15
  1. Save the qsys file and click on Generate HDL. We integrated our custom IP with the hps system. Then hit Finish to close the Platform Designer window

  2. In the Quartus Prime window, double click on ghrd_top.v(Golden reference) in the Files tab and add these two line in the soc_system instantiation like Figure 16. Add a 32 bit wire variable connection to connect these two. Hit Start Compilation and after the completion program the board. If you having trouble about the program procedure please refer to Demo_2.pdf for help.

Figure 16

Using U-Boot to write and read from memory

U-Boot stands for Universal Boot Loader. It’s a primary boot loader used in embedded devices to package the instructions to boot the device’s operating system kernel. It’s ubiquitous to various computer architectures including 68k, ARM, Blackfin, MicroBlaze, MIPS, Nios, SuperH, PPC, RISC-V and x86.

Steps :

  1. Connect the board with your host PC via the Uart cable. Assuming your SD card has a Linux OS image, use Putty or Mobaxterm to establish connection via a terminal. If you have trouble establishing the connection, please refer to Demo_6.pdf for the steps.
  2. Press the HPS RST button on the board. It’s at the bottom right corner of the board.

Figure 17
  1. The Linux OS will boot up and you’ll see a message like Hit any key to stop autoboot and a countdown for 5 seconds. Hit any key before the countdown finishes and you’ll enter in U-Boot mode like Figure 18.

Figure 18
  1. U-Boot terminal offers some basic operations from the terminal. Type in help to see those. In this discussion we will use only md(Not Maryland!,Memory Display) and mw(Memory Write)
  2. After the HDL generation of the HPS, a html report will be generated in the <your project directory>/soc_system/soc_system.html. Open the file and look for the base addresses of the custom IP and the PIO we added. From the file we find that the base address of the custom IP and the PIO is 0xff200020 and 0xff200010 respectively.

Figure 19
  1. Then, from U-Boot terminal type in md ff200020 and it will display the values stored in the entire block. The values are 0 and 3ff because we just initialized the memory and didn’t written anything new in it.

Figure 20
  1. Then, type in mw ff200020 7 to write 7 in the base address of the custom IP. After that, type in md ff200020 to display the values stored, you can see that the value is 8. Which means that our custom IP is working correctly and storing the value incremented by 1.

Figure 21
  1. To see the value written in the base address of the PIO, type in md ff200010 and you’ll see a similar output as Figure 22. It’ll also show the value 8 because we linked the output and input of the custom IP and PIO with a wire.

Figure 22

Reference

  1. Intel custom component creation manual ftp://ftp.intel.com/Pub/fpgaup/pub/Intel_Material/18.1/Tutorials/Making_Qsys_Components.pdf
  2. ftp://ftp.intel.com/pub/fpgaup/pub/Intel_Material/18.1/Tutorials/Linux_On_DE_Series_Boards.pdf