Skip to content

muwyse/arty-a7-100t

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

12 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Arty A7 Example Design with Memory

This repository contains source and scripts to create an example design for the Arty A7-100T Revision E.0 board that instantiates the on-board 256 MiB DDR3 SDRAM.

This design comprises three main parts under the top level arty module:

  1. a block design that generates the clocks, instantiates the 256 MiB DDR memory, and exposes an AXI 4 Lite interface
  2. a simple AXI 4 Lite traffic generator
  3. basic I/O using switches, LEDs, and buttons

Repository Organization

  • common/ contains board and constraint files from Digilent.
  • src/ contains the source files for the project
  • tcl/ contains scripts to generate the project and compile the design
  • docs/ contains extra docummentation referenced from this README

Requirements

This project was created with Vivado ML Standard 2021.1.1 and tested on Windows 10 Version 21H1. The scripts should work on Linux variants supported by Vivado ML, but have not been tested on these platforms.

References

Quick Start

To generate a project: vivado -mode batch -source tcl/arty-memory.tcl

To run synthesis, implementation, and generate bitsream: vivado -mode batch -source tcl/generate_bitstream.tcl

BlackParrot on Arty (ArtyParrot)

BlackParrot is a 64-bit RISC-V processor initially developed at the University of Washington. This repository contains scripts and the necessary files to instantiate a single BlackParrot processor on the Arty A7, which connects to the on-board DDR3 SDRAM using the design detailed in the rest of this README. The ArtyParrot design also includes a UART module that acts as the gateway between a PC Host and BlackParrot, allowing the user to load programs to memory, configure the processor core, and then receive I/O from the core during execution. More details and instructions for instantiating this design can be found in the ArtyParrot documentation.

Programming the Arty A7 using Quad SPI Flash Memory

The Arty A7 has a 16 MiB Quad-SPI Flash memory that can be used to store the FPGA configuration file (bitstream). This memory can be programmed using the bitstream generated by this project so that when the board is powered on the FPGA is automatically programmed using the stored design configuration.

The general directions for this are available on Digilent's Arty Programming Guide. The project in this repo has already been configured to generate the .bin file required for programming the Quad-SPI memory and sets the Configuration Rate and Mode as described in Step 2 of the Arty Programming Guide.

Programming the Quad-SPI can be accomplished by opening the de# Vivado and then completing Step 4 in the Arty Programming Guide. First, open the Hardware Manager and connect to the Arty A7 board. Then, in Step 4.3 select the memory part with name s25fl128sxxxxxx0-spi-x1_x2_x4 and part s25fl128sxxxxxx0. Warning: this part is specific for Rev E of the Arty A7 board, as specified in the Arty A7 Reference Manual. Follow the remaining steps and wait for programming to complete.

Project Description

As stated above, this project instantiates the 256 MiB DDR3 SDRAM on the Arty A7 board and exposes it to user logic with an AXI4 Lite interface. The project also contains a simple AXI4 Lite traffic generator that writes then reads the entire memory in 64-bit words. The primary goal of this project is to create an easy to understand design with functional DDR3 SDRAM.

The desing has the following I/O on the board:

  • 4 switches that enable the 4 RGB LEDs (off by default).
  • Buttons 0 to 2 increase the intensity of Blue, Green, and Red LED channels, respectively. Pressing a button will increase the intensity of the associated color channel for LEDs that are enabled (corresponding switch is activated).
  • Button 4 starts the AXI4 Lite traffic generator logic. Once started, the traffic generator writes the entire memory 64-bits at a time and then reads back the entire memory 64-bits at a time while verifying that the read value matches the value that was written previously. If the test passes, LED 6 will turn on and stay on. If the test fails, LED 4 or 5 will turn on, indicating there was an error due to a write or read operation, respectively.
  • Red reset button triggers a reset of the entire design, turning off all LEDs and resetting the memory and traffic generator. LED 7 lights up when reset is pressed.

Project Creation Tutorial

The original project was created using the Vivado GUI. This tutorial will walk you through re-creating the project distributed in this repository using the GUI. This has only been tested with Vivado ML Standard Version 2021.1.1 on Windows 10, however the steps should be similar in other versions of Vivado and on other platforms.

Note that steps or settings may have been missed in this writeup. Please report any issues using the GitHub Issue feature on this repository.

Setup Vivado and Add Board Files

Follow the instructions from Digilent to setup Vivado and add the board files for the Arty A7 100T, which are found here.

Create the Project

Launch Vivado then choose Create Project from the Quick Start (or File - Project - New...). Choose where to save your project and give it a name, say "arty-memory". Choose RTL Project and check "Do not specify sources at this time" then click Next to the part selection page. On the part selection page, select the Boards tab and then double click on the Arty A7-100 board. Click Finish to create the project.

Create the Block Design

With the project created, click on "Create Block Design" to open a new block design. Leave the design settings as their defaults. With the design open select the Board window, which should appear as a new tab alongside the Sources tab. This window lists IP that can be easily instantiated on the Arty A7.

DDR3 SDRAM

Drag-and-drop the DDR3 SDRAM item from the Board Window to the block design. Then, double-click on the IP block to reconfigure with the settings below. Most settings were left unchanged, but some were tweaked slightly. Bold settings indicate changes from default (as best as remembered).

  • First Page
    • Create Design
    • Multi-Controller: select 1 for Number of controllers
    • AXI4 Interface box will be checked
  • Pin Compatible FPGAs
    • none selected
  • Memory Selection
    • DDR3 SDRAM
  • Controller Options
    • Clock Period = 3,000 ns (333.33 MHz)
    • PHY to Controller Clock Ratio = 4:1
    • Memory Type = Components
    • Memory Part = MT41K128M16XX-15E
    • Memory Voltage = 1.35V
    • Data Width = 16
    • ECC = disabled
    • Data Mask = checked
    • Number of Bank Machines = 4
    • ORDERING = Normal
  • AXI Parameter
    • Data Width = 64
    • Arbitration Scheme = RD_PRI_REG
    • Narrow Burst Support = 0
    • Address Width = 28
    • ID Width = 4
  • Memory Options
    • Input Clock Period = 6,000 ns (166.667 MHz)
    • Additional Clocks (checked to add additional clocks)
      • Clock 0: 9009 ps (111 MHz)
      • Clock 1: 13513 ps (74 MHz)
      • Clock 2: 27027 ps (37 MHz)
      • Clock 3: 55555 ps (18 MHz)
    • Read Burst Type and Length = Sequential
    • Output Driver Impedance Control = RZQ/6
    • RTT = RZQ/6
    • Controller Chip Select Pin = Enable
    • Memory Address Mapping Selection = Bank, Row, Column
  • FPGA Options
    • System Clock: No Buffer
    • Reference Clock: No Buffer
    • System Reset Polarity: Active Low
    • Internal Vref: checked
    • IO Power Reduction: On
    • XADC Instantiation: Enabled
  • Extended FPGA Options
    • Internal Termination Impedence: 50 Ohms
  • IO Planning Options
    • Pin/Bank Selection Mode: Fixed Pin Out
      • This works because the vivado project was created for the Arty A7 board using the Digilent board files
  • Pin Selection
    • click Validate, current pin assignment should be valid, then Next to proceed
  • System Signals Selection
    • for sys_rst, init_calib_complete, and tg_compare_error
    • Bank Number = Select Bank
    • Pin Number = No Connect
  • Simulation Options
    • Accept then Next
  • PCB Information
    • click Next
  • Design Notes
    • click Generate

After reconfiguring the DDR3 SDRAM IP it will be ready to connect to clocks, resets, and an AXI interface. The DDR3 SDRAM IP requires two input clocks: clk_ref_i at 200 MHz and sys_clk_i at 166.667 MHz. These clocks will be generated and connected in the next step. Before moving on, click on and then delete both clk_ref_i and sys_clk_i input ports.

Lastly, create the clock output ports and the calibration complete output port by right clicking on each of the ui_addn_clk ports and the init_calib_complete port and selecting Make External. Rename clock 0 through 4 to clk_111M_o, clk_74M_o, clk_37_o, clk_18M_o. Rename the init_calib_complete to mig_ddr_init_calib_complete_o.

The DDR3 SDRAM exposes an AXI 4 interface and generates a clock and synchronous reset for the interface, called ui_clk and ui_clk_sync_rst.

The primary changes to the DDR3 configuration are to generate additional clocks to drive user logic and the AXI4 Lite interface and setting a 64-bit AXI data width. The motivation for 64-bit data width is due to the simplistic design of the AXI 4 Lite traffic generator, which accesses memory 64-bits at a time using a 64-bit wide data channel. The additional clocks are generated to demonstrate how to perform the clock crossing and run user logic on a secondary clock.

System Clock

Drag-and-drop the System Clock IP onto the blockd design. This block will consume the on-board clock and reset button and generate the 200 MHz and 166 Mhz clocks required by the DDR3 SDRAM.

Click on the sys_clock input and rename it to external_clock_i. Then double-click on the System Clock IP to configure. On the Board tab, select reset for EXT_RESET_IN. On Output Clocks, check both clk_out_1 and clk_out_2. Name the clocks clk_200M_o and clk_166M_o and set the requested frequency to 200 and 166.66667, respectively. At the bottom of the window, select Active Low for Reset Type. Uncheck the locked checkbox under Optional Outputs.

Connect the newly generated clocks to the DDR3 SDRAM IP block by drawing a line from the System Clock IP clock ports to the DDR3 SDRAM IP clock input ports. clk_200M_o connects to clk_ref_i and clk_166M_o connects to sys_clk_i.

Create an external reset connection by right-clicking on resetn port and selecting Make External. Select the newly created port and rename it to external_reset_n_i. Connect this port to mig_ddr sys_rst.

The block design should look like this.

AXI Clock Converter

From the block design window, click the plus sign (Add IP) and search for AXI Clock Converter. Double-click on the IP entry to add it to the design. Once added, double-click on the IP block to re-customize the IP. Make Address Width, Data Width, ID Width, and Is ACLK Asynchronous "Manual" settings by clicking on the Auto/Manual toggle next to each setting. The settings should be:

  • Address Width = 28
  • Data Width = 64
  • ID Width = 4
  • Is ACLK Asynchronous = Yes

The remaining settings should be properly set with the default values, as shown here.

With the IP block configured, connect its ports as follows:

  • M_AXI connects to mig_ddr S_AXI
  • m_axi_aclk connects to mig_ddr ui_clk
  • s_axi_aclk connects to mig_ddr ui_addn_clk_1 (clk_74M_o)

AXI Protocol Converter

From the block design window, click the plus sign (Add IP) and search for AXI Protocol Converter. Double-click on the IP entry to add it to the design. Once added, double-click on the IP block to re-customize the IP. Manually set the following settings:

  • SI Protocol = AXI4LITE
  • MI Protocol = AXI4
  • Address Width = 28
  • Data Width = 64

The remaining settings should be properly set with the default values, as shown here.

Connect its ports as follows:

  • M_AXI connects to S_AXI on the AXI Clock Converter
  • aclk connects to mig_ddr ui_addn_clk_1 (clk_74M_o)

Lastly, right-click on the S_AXI port and Make External. Click on the newly created port and rename it to s_axi_lite_i in the External Interface Properties. In this window, set the Clock Port dropdown to clk_74M_o. The design should look like this.

System Reset

The current design has two reset modules. One is connected to the 83 MHz clock that drives the AXI 4 interface from the DDR3. The second is connected to the clock driving the AXI 4 Lite interface and the user logic in the design. This second clock can be any of the additional clocks generated by the DDR3 SDRAM (111, 74, 37, or 18 MHz). These instructions use the 74 MHz clock.

AXI Reset

From the block design window, click the plus sign (Add IP) and search for Processor System Reset, then double-click to add. Click on the IP and rename to rst_s_axi in the Block Properties window. Make the interconnect_aresetn port external by right-clicking and selecting Make External. Rename this port to s_axi_reset_n_o. Make the mb_reset port external and rename to proc_reset_o.

Connect the ports as follows:

  • slowest_sync_clk to mig_ddr ui_addn_clk_1 (cl_74M_o)
  • dcm_locked to mig_ddr mmcm_locked
  • ext_reset_i to the external_reset_n_i port
  • interconnect_aresetn to axi_protocol_convert_0 aresetn and axi_clock_converter_0 s_axi_aresetn

DDR Reset

From the block design window, click the plus sign (Add IP) and search for Processor System Reset, then double-click to add. Click on the IP and rename to rst_mig_ddr_83M in the Block Properties window.

Connect the ports as follows:

  • slowest_sync_clk to mig_ddr ui_clk
  • dcm_locked to mig_ddr mmcm_locked
  • ext_reset_i to mig_ddr ui_clk_sync_rst
  • interconnect_aresetn to axi_clock_converter_0 m_axi_resetn
  • peripheral_aresetn to mig_ddr aresetn

Constant Tie-Offs

The reset modules each have two reset inputs that are unused in this design and need to be tied to either a high or low signal. This is accomplished using Constant IP blocks. Click the plus sign (Add IP) and search for Constant, then double-click to add. Do this a second time to add a second constant block. Click on one of the blocks and rename it in the Block Properties window to rst_tie_high. Click on the other block and rename it to rst_tie_low. Then double-click on the rst_tie_low block and set the Const Val setting to 0.

Connect dout from rst_tie_low to the mb_debug_sys_rst port on each of the Processor System Reset IP blocks. Connect dout from rst_tie_high to the aux_reset_in port on each of the Processor System Reset IP blocks.

The block design should look like this.

Address Segment Assignment

Click on Validate Design (checkmark in box icon on the block design window) and then select Yes when prompted to auto-assign the unassigned address segment. Verify that the assigned address segment is set starting with address 0x000_0000 and Range 256M with a High Address of 0xFFF_FFFF, as shown here.

Generate HDL Wrapper

Now that the block design is complete, generate the HDL wrapper so that the design can be instantiated inside the top-level arty module. From the Sources Window, right click on the design_1 source entry and select Create HDL Wrapper... Then, click OK (leave Let Vivado manage wrapper and auto-update checked) to generate the design_1_wrapper.v file.

Changing User Logic Clock

This design is configured to use the 74 MHz clock for user logic and the AXI4 Lite interface that user logic uses to connect to memory (s_axi_lite_i port). To change this clock, disconnect the following ports by right-clicking on them and selecting Disconnect Pin, then connect one of the mig_ddr ui_addn_clk ports to:

  • axi_protocol_convert_0 aclk
  • axi_clock_converter_0 s_axi_alck
  • rst_s_axi slowest_sync_clk

Also, set the associated clock port for the s_axi_lite_i port by clicking on the port and setting the Clock Port setting to the clock used above. Revalidate the block design to confirm that the clock connections are valid.

Alternative Design Options (not documented or supported)

If your user logic is capable of running at 83 MHz and communicating over AXI 4 (not Lite), then the design could be simplified by removing the AXI Protocol Converter, AXI Clock Converter, and one of the Processor System Resets. The S_AXI port of the DDR3 SDRAM MIG IP block would be directly exposed to the user logic. This interface's clock and reset are the ui_clk and ui_clk_sync_rst ports coming out of the DDR3 SDRAM MIG IP. Further changes and tweaks to the design are likely needed, and are not covered by the documentation in this repository.

If your design is capable of running at 83 MHz but communicates over AXI 4 Lite, then the AXI Clock Converter and one of the Processor System Resets could be removed. The AXI interface and user design would run on the ui_clk from the DDR3 SDRAM MIG IP.

About

Arty A7 design with DDR3

Resources

License

Stars

Watchers

Forks

Packages

No packages published