RoadTest: USB104 A7: Artix-7 FPGA Development Board
Author: yesha98
Creation date:
Evaluation Type: Development Boards & Tools
Did you receive all parts the manufacturer stated would be included in the package?: True
What other parts do you consider comparable to this product?: The package does not contain the Zmod ADC / DAC, which could've been really useful for people looking to experiment with Analog signals too. One more point to be noted is, the board lacks Ethernet connectivity, which becomes crucial in some cases, thus adding a NIC Pmod to the package would be appreciable.
What were the biggest problems encountered?: The MIG 7 series - Memory Interface Generator IP has a problem in routing as the sys_clk is in a different bank (Vivado 2017.3). Was unable to fix the problem even after many tries.
Detailed Review:
1. Introduction:
The USB 104 A7, as the name suggests, comes in the PC104 form factor, mainly aimed at use in the Stackable computers. The main advantage of using a stackable computer is its scalability. The boards can be added (scaled) to the requirement of the application such that the memory, programmable fabric, LEs, and other things match the requirement. The board features the famous Artix-7 100T FPGA which is widely used in development boards such as the Arty A7 and Basys boards. This brings us to the question of why USB 104 A7? Well, the answer is, this is an industry-grade board that can withstand drastic changes in temperatures.
Update: Course Featuring this board - Summer of FPGAs - Building an Embedded System on FPGA
Needless to mention the board comes with very good packaging and all basic parts to get the board working such as the Power Adapter and the USB cable.
1.1 Key Features:
The board featured the famous ATmega328PB, which is also used in Arduino boards, to implement the SmartVIO requirements of the SYZYGY standard, set the DDR voltage, configure the USB Hub, and provide information about the power supply settings and SYZYGY ports to the FPGA.
DPTI:
The DPTI interface is an 8-bit wide parallel FIFO-style data interface supporting both asynchronous and synchronous modes.
One can use PC applications to communicate with the board using the standard Windows COM port command.
Refer to manual for detailed info: https://reference.digilentinc.com/reference/programmable-logic/usb104a7/reference-manual
2. RoadTest:
2.1 Detecting the USB-Serial Communication when connecting the board to PC for the first time and running the out-of-box demo.
2.2 Testing onboard USB-JTAG Programmer
2.3 Compatibility with Xilinx ISE (Older versions)
2.4 Testing a design with Pmod VGA
2.5 Testing a design with Pmod SD
2.6 Design to boot Linux
2.7 Testing the GPIO with custom Pmod Starter
(Includes an interesting section that explains the purpose of this board)
Note: Watch the videos at a higher resolution for better clarity.
2.1 Detecting the USB-Serial Communication when connecting the board to PC for the first time and running the out-of-box demo:
For the development of block designs and ease, the board files are provided on the Digilent website which can be downloaded and added to the design. Vivado detects the board as soon as it is added to the respective directory - C:\Xilinx\Vivado\<version>\data\boards\board_files
The above images show how Vivado immediately detects the board files for their use in IP and block-based designs.
The board files can be found here: https://github.com/Digilent/vivado-boards/tree/master/new/board_files/usb104-a7/B
2.2 Testing onboard USB-JTAG Programmer:
In this test, a simple HDL code for a half adder will be executed on the FPGA to test the on-board buttons, LEDs and finally program the FPGA using the bitstream generated and programmed into the FPGA
{tabbedtable} Getting Started |
Tab Content |
---|---|
Create Project | ![]() |
Give the project a name without spaces | |
Select the Design Entry type | |
Select the board | ![]() |
Click Finish | ![]() |
A Master XDC file is used as a constraints file for easy coding which can be found in this link: https://github.com/Digilent/digilent-xdc/blob/master/USB104-A7-100T-Master.xdc
Output:
2.3 Compatibility with Xilinx ISE (Older versions):
There are many developers and engineers still working with older versions of design software due to compatibility issues and because their previous designs might now work with newer versions of the software
due to software and IP upgrades or major upgrades. Thus it is essential to test if the board works with older versions and other software.
The below video illustrates the compatibility with the Xilinx ISE - Boundary-scan in iMPACT(I hope people still remember that)
The board is very well compatible with the Xilinx ISE and one can use it for simple designs with HDL code as the board files are not compatible with the ISE format.
2.4 Testing a design with Pmod VGA:
A sample code to test Pmod VGA in VHDL. Resolution: 1920 * 1080 @ 60Hz
top.vhd:
library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.std_logic_unsigned.all; entity top is Port ( CLK_I : in STD_LOGIC; VGA_HS_O : out STD_LOGIC; VGA_VS_O : out STD_LOGIC; VGA_R : out STD_LOGIC_VECTOR (3 downto 0); VGA_B : out STD_LOGIC_VECTOR (3 downto 0); VGA_G : out STD_LOGIC_VECTOR (3 downto 0)); end top; architecture Behavioral of top is component clk_wiz_0 port (-- Clock in ports CLK_IN1 : in std_logic; -- Clock out ports CLK_OUT1 : out std_logic ); end component; --Sync Generation constants ----***640x480@60Hz***-- Requires 25 MHz clock --constant FRAME_WIDTH : natural := 640; --constant FRAME_HEIGHT : natural := 480; --constant H_FP : natural := 16; --H front porch width (pixels) --constant H_PW : natural := 96; --H sync pulse width (pixels) --constant H_MAX : natural := 800; --H total period (pixels) --constant V_FP : natural := 10; --V front porch width (lines) --constant V_PW : natural := 2; --V sync pulse width (lines) --constant V_MAX : natural := 525; --V total period (lines) --constant H_POL : std_logic := '0'; --constant V_POL : std_logic := '0'; ----***800x600@60Hz***-- Requires 40 MHz clock --constant FRAME_WIDTH : natural := 800; --constant FRAME_HEIGHT : natural := 600; -- --constant H_FP : natural := 40; --H front porch width (pixels) --constant H_PW : natural := 128; --H sync pulse width (pixels) --constant H_MAX : natural := 1056; --H total period (pixels) -- --constant V_FP : natural := 1; --V front porch width (lines) --constant V_PW : natural := 4; --V sync pulse width (lines) --constant V_MAX : natural := 628; --V total period (lines) -- --constant H_POL : std_logic := '1'; --constant V_POL : std_logic := '1'; ----***1280x720@60Hz***-- Requires 74.25 MHz clock --constant FRAME_WIDTH : natural := 1280; --constant FRAME_HEIGHT : natural := 720; -- --constant H_FP : natural := 110; --H front porch width (pixels) --constant H_PW : natural := 40; --H sync pulse width (pixels) --constant H_MAX : natural := 1650; --H total period (pixels) -- --constant V_FP : natural := 5; --V front porch width (lines) --constant V_PW : natural := 5; --V sync pulse width (lines) --constant V_MAX : natural := 750; --V total period (lines) -- --constant H_POL : std_logic := '1'; --constant V_POL : std_logic := '1'; ----***1280x1024@60Hz***-- Requires 108 MHz clock --constant FRAME_WIDTH : natural := 1280; --constant FRAME_HEIGHT : natural := 1024; --constant H_FP : natural := 48; --H front porch width (pixels) --constant H_PW : natural := 112; --H sync pulse width (pixels) --constant H_MAX : natural := 1688; --H total period (pixels) --constant V_FP : natural := 1; --V front porch width (lines) --constant V_PW : natural := 3; --V sync pulse width (lines) --constant V_MAX : natural := 1066; --V total period (lines) --constant H_POL : std_logic := '1'; --constant V_POL : std_logic := '1'; --***1920x1080@60Hz***-- Requires 148.5 MHz pxl_clk constant FRAME_WIDTH : natural := 1920; constant FRAME_HEIGHT : natural := 1080; constant H_FP : natural := 88; --H front porch width (pixels) constant H_PW : natural := 44; --H sync pulse width (pixels) constant H_MAX : natural := 2200; --H total period (pixels) constant V_FP : natural := 4; --V front porch width (lines) constant V_PW : natural := 5; --V sync pulse width (lines) constant V_MAX : natural := 1125; --V total period (lines) constant H_POL : std_logic := '1'; constant V_POL : std_logic := '1'; --Moving Box constants constant BOX_WIDTH : natural := 8; constant BOX_CLK_DIV : natural := 1000000; --MAX=(2^25 - 1) constant BOX_X_MAX : natural := (512 - BOX_WIDTH); constant BOX_Y_MAX : natural := (FRAME_HEIGHT - BOX_WIDTH); constant BOX_X_MIN : natural := 0; constant BOX_Y_MIN : natural := 256; constant BOX_X_INIT : std_logic_vector(11 downto 0) := x"000"; constant BOX_Y_INIT : std_logic_vector(11 downto 0) := x"190"; --400 signal pxl_clk : std_logic; signal active : std_logic; signal h_cntr_reg : std_logic_vector(11 downto 0) := (others =>'0'); signal v_cntr_reg : std_logic_vector(11 downto 0) := (others =>'0'); signal h_sync_reg : std_logic := not(H_POL); signal v_sync_reg : std_logic := not(V_POL); signal h_sync_dly_reg : std_logic := not(H_POL); signal v_sync_dly_reg : std_logic := not(V_POL); signal vga_red_reg : std_logic_vector(3 downto 0) := (others =>'0'); signal vga_green_reg : std_logic_vector(3 downto 0) := (others =>'0'); signal vga_blue_reg : std_logic_vector(3 downto 0) := (others =>'0'); signal vga_red : std_logic_vector(3 downto 0); signal vga_green : std_logic_vector(3 downto 0); signal vga_blue : std_logic_vector(3 downto 0); signal box_x_reg : std_logic_vector(11 downto 0) := BOX_X_INIT; signal box_x_dir : std_logic := '1'; signal box_y_reg : std_logic_vector(11 downto 0) := BOX_Y_INIT; signal box_y_dir : std_logic := '1'; signal box_cntr_reg : std_logic_vector(24 downto 0) := (others =>'0'); signal update_box : std_logic; signal pixel_in_box : std_logic; begin clk_div_inst : clk_wiz_0 port map (-- Clock in ports CLK_IN1 => CLK_I, -- Clock out ports CLK_OUT1 => pxl_clk); ---------------------------------------------------- ------- TEST PATTERN LOGIC ------- ---------------------------------------------------- vga_red <= h_cntr_reg(5 downto 2) when (active = '1' and ((h_cntr_reg < 512 and v_cntr_reg < 256) and h_cntr_reg(8) = '1')) else (others=>'1') when (active = '1' and ((h_cntr_reg < 512 and not(v_cntr_reg < 256)) and not(pixel_in_box = '1'))) else (others=>'1') when (active = '1' and ((not(h_cntr_reg < 512) and (v_cntr_reg(8) = '1' and h_cntr_reg(3) = '1')) or (not(h_cntr_reg < 512) and (v_cntr_reg(8) = '0' and v_cntr_reg(3) = '1')))) else (others=>'0'); vga_blue <= h_cntr_reg(5 downto 2) when (active = '1' and ((h_cntr_reg < 512 and v_cntr_reg < 256) and h_cntr_reg(6) = '1')) else (others=>'1') when (active = '1' and ((h_cntr_reg < 512 and not(v_cntr_reg < 256)) and not(pixel_in_box = '1'))) else (others=>'1') when (active = '1' and ((not(h_cntr_reg < 512) and (v_cntr_reg(8) = '1' and h_cntr_reg(3) = '1')) or (not(h_cntr_reg < 512) and (v_cntr_reg(8) = '0' and v_cntr_reg(3) = '1')))) else (others=>'0'); vga_green <= h_cntr_reg(5 downto 2) when (active = '1' and ((h_cntr_reg < 512 and v_cntr_reg < 256) and h_cntr_reg(7) = '1')) else (others=>'1') when (active = '1' and ((h_cntr_reg < 512 and not(v_cntr_reg < 256)) and not(pixel_in_box = '1'))) else (others=>'1') when (active = '1' and ((not(h_cntr_reg < 512) and (v_cntr_reg(8) = '1' and h_cntr_reg(3) = '1')) or (not(h_cntr_reg < 512) and (v_cntr_reg(8) = '0' and v_cntr_reg(3) = '1')))) else (others=>'0'); ------------------------------------------------------ ------- MOVING BOX LOGIC ------ ------------------------------------------------------ process (pxl_clk) begin if (rising_edge(pxl_clk)) then if (update_box = '1') then if (box_x_dir = '1') then box_x_reg <= box_x_reg + 1; else box_x_reg <= box_x_reg - 1; end if; if (box_y_dir = '1') then box_y_reg <= box_y_reg + 1; else box_y_reg <= box_y_reg - 1; end if; end if; end if; end process; process (pxl_clk) begin if (rising_edge(pxl_clk)) then if (update_box = '1') then if ((box_x_dir = '1' and (box_x_reg = BOX_X_MAX - 1)) or (box_x_dir = '0' and (box_x_reg = BOX_X_MIN + 1))) then box_x_dir <= not(box_x_dir); end if; if ((box_y_dir = '1' and (box_y_reg = BOX_Y_MAX - 1)) or (box_y_dir = '0' and (box_y_reg = BOX_Y_MIN + 1))) then box_y_dir <= not(box_y_dir); end if; end if; end if; end process; process (pxl_clk) begin if (rising_edge(pxl_clk)) then if (box_cntr_reg = (BOX_CLK_DIV - 1)) then box_cntr_reg <= (others=>'0'); else box_cntr_reg <= box_cntr_reg + 1; end if; end if; end process; update_box <= '1' when box_cntr_reg = (BOX_CLK_DIV - 1) else '0'; pixel_in_box <= '1' when (((h_cntr_reg >= box_x_reg) and (h_cntr_reg < (box_x_reg + BOX_WIDTH))) and ((v_cntr_reg >= box_y_reg) and (v_cntr_reg < (box_y_reg + BOX_WIDTH)))) else '0'; ------------------------------------------------------ ------- SYNC GENERATION ------ ------------------------------------------------------ process (pxl_clk) begin if (rising_edge(pxl_clk)) then if (h_cntr_reg = (H_MAX - 1)) then h_cntr_reg <= (others =>'0'); else h_cntr_reg <= h_cntr_reg + 1; end if; end if; end process; process (pxl_clk) begin if (rising_edge(pxl_clk)) then if ((h_cntr_reg = (H_MAX - 1)) and (v_cntr_reg = (V_MAX - 1))) then v_cntr_reg <= (others =>'0'); elsif (h_cntr_reg = (H_MAX - 1)) then v_cntr_reg <= v_cntr_reg + 1; end if; end if; end process; process (pxl_clk) begin if (rising_edge(pxl_clk)) then if (h_cntr_reg >= (H_FP + FRAME_WIDTH - 1)) and (h_cntr_reg < (H_FP + FRAME_WIDTH + H_PW - 1)) then h_sync_reg <= H_POL; else h_sync_reg <= not(H_POL); end if; end if; end process; process (pxl_clk) begin if (rising_edge(pxl_clk)) then if (v_cntr_reg >= (V_FP + FRAME_HEIGHT - 1)) and (v_cntr_reg < (V_FP + FRAME_HEIGHT + V_PW - 1)) then v_sync_reg <= V_POL; else v_sync_reg <= not(V_POL); end if; end if; end process; active <= '1' when ((h_cntr_reg < FRAME_WIDTH) and (v_cntr_reg < FRAME_HEIGHT))else '0'; process (pxl_clk) begin if (rising_edge(pxl_clk)) then v_sync_dly_reg <= v_sync_reg; h_sync_dly_reg <= h_sync_reg; vga_red_reg <= vga_red; vga_green_reg <= vga_green; vga_blue_reg <= vga_blue; end if; end process; VGA_HS_O <= h_sync_dly_reg; VGA_VS_O <= v_sync_dly_reg; VGA_R <= vga_red_reg; VGA_G <= vga_green_reg; VGA_B <= vga_blue_reg; end Behavioral;
Constraints file:
## 100MHz Clock set_property -dict { PACKAGE_PIN E3 IOSTANDARD LVCMOS33 } [get_ports { CLK_I }]; #IO_L12P_T1_MRCC_35 Sch=gclk[100] create_clock -add -name sys_clk_pin -period 10.00 -waveform {0 5} [get_ports { CLK_I }]; ### Pmod Header JB set_property -dict { PACKAGE_PIN C4 IOSTANDARD LVCMOS33 } [get_ports { VGA_G[0] }]; #IO_L7P_T1_AD6P_35 Sch=jb[1] set_property -dict { PACKAGE_PIN B2 IOSTANDARD LVCMOS33 } [get_ports { VGA_G[1] }]; #IO_L10N_T1_AD15N_35 Sch=jb[2] set_property -dict { PACKAGE_PIN B3 IOSTANDARD LVCMOS33 } [get_ports { VGA_G[2] }]; #IO_L10P_T1_AD15P_35 Sch=jb[3] set_property -dict { PACKAGE_PIN B4 IOSTANDARD LVCMOS33 } [get_ports { VGA_G[3] }]; #IO_L7N_T1_AD6N_35 Sch=jb[4] set_property -dict { PACKAGE_PIN B1 IOSTANDARD LVCMOS33 } [get_ports { VGA_R[0] }]; #IO_L9P_T1_DQS_AD7P_35 Sch=jb[7] set_property -dict { PACKAGE_PIN A1 IOSTANDARD LVCMOS33 } [get_ports { VGA_R[1] }]; #IO_L9N_T1_DQS_AD7N_35 Sch=jb[8] set_property -dict { PACKAGE_PIN A3 IOSTANDARD LVCMOS33 } [get_ports { VGA_R[2] }]; #IO_L8N_T1_AD14N_35 Sch=jb[9] set_property -dict { PACKAGE_PIN A4 IOSTANDARD LVCMOS33 } [get_ports { VGA_R[3] }]; #IO_L8P_T1_AD14P_35 Sch=jb[10] ### Pmod Header JC set_property -dict { PACKAGE_PIN C5 IOSTANDARD LVCMOS33 } [get_ports { VGA_B[0] }]; #IO_L1N_T0_AD4N_35 Sch=jc[1] set_property -dict { PACKAGE_PIN C6 IOSTANDARD LVCMOS33 } [get_ports { VGA_B[1] }]; #IO_L1P_T0_AD4P_35 Sch=jc[2] set_property -dict { PACKAGE_PIN B6 IOSTANDARD LVCMOS33 } [get_ports { VGA_B[2] }]; #IO_L2N_T0_AD12N_35 Sch=jc[3] set_property -dict { PACKAGE_PIN C7 IOSTANDARD LVCMOS33 } [get_ports { VGA_B[3] }]; #IO_L4N_T0_35 Sch=jc[4] set_property -dict { PACKAGE_PIN A5 IOSTANDARD LVCMOS33 } [get_ports { VGA_HS_O }]; #IO_L3N_T0_DQS_AD5N_35 Sch=jc[7] set_property -dict { PACKAGE_PIN A6 IOSTANDARD LVCMOS33 } [get_ports { VGA_VS_O }]; #IO_L3P_T0_DQS_AD5P_35 Sch=jc[8] ## Bitstream Settings set_property BITSTREAM.GENERAL.COMPRESS TRUE [current_design]
This project additionally needs a clock gen IP, xci file can download from this link: https://github.com/Digilent/Arty-Pmod-VGA/tree/master/src/ip/clk_wiz_0
The VGA Pmod is connected to JB and JC as shown below:
Working video:
2.5 Testing a design with Pmod SD:
This phase of the test consists of creating a block design with MicroBlaze and the Pmod SD IP and using the Xilinx SDK to check the read-write capabilities of the SD card.
The SD card will be connected to the JA Pmod connector on the board.
One more thing that should've been included with this board is the system-reset button which should've been an active low button. Almost all IPs such as the MicroBlaze processor system reset and the MIG series comes with default active low reset mode. While this option of having a system reset button is available in the Arty based boards, this board lacks the dedicated system reset button.
The below image shows how I had to use a resistor connected to one of the GPIOs to use it as an external system reset.
After creating the block design, run the synthesis, implementation and finally generate the bitstream.
Launch the Xilinx SDK after exporting the hardware with bitstream included.
The C++ code used to test the SD card is given below: (A demo program)
main.cc File:
/******************************************************************************/ /* */ /* main.cc -- Demo program for the PmodSD IP */ /* */ /******************************************************************************/ /* Author: Thomas Kappenman */ /* Copyright 2016, Digilent Inc. */ /******************************************************************************/ /* * * Copyright (c) 2013-2016, Digilent <www.digilentinc.com> * Contact Digilent for the latest version. * * This program is free software; distributed under the terms of * BSD 3-clause license ("Revised BSD License", "New BSD License", or "Modified BSD License") * * Redistribution and use in source and binary forms, with or without modification, * are permitted provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this * list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * 3. Neither the name(s) of the above-listed copyright holder(s) nor the names * of its contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ /******************************************************************************/ /* File Description: */ /* */ /* This demo creates a file in your SD card and writes to it */ /* */ /******************************************************************************/ /* Revision History: */ /* */ /* 08/10/2016(TommyK): Created */ /* 01/20/2018(atangzwj): Validated for Vivado 2017.4 */ /* */ /******************************************************************************/ #include "PmodSD.h" #include "xil_cache.h" #include "xil_printf.h" void DemoInitialize(); void DemoRun(); int main(void) { Xil_ICacheEnable(); Xil_DCacheEnable(); DemoInitialize(); DemoRun(); return 0; } void DemoInitialize() { } void DemoRun() { DXSPISDVOL disk(XPAR_PMODSD_0_AXI_LITE_SPI_BASEADDR, XPAR_PMODSD_0_AXI_LITE_SDCS_BASEADDR); DFILE file; // The drive to mount the SD volume to. // Options are: "0:", "1:", "2:", "3:", "4:" static const char szDriveNbr[] = "0:"; FRESULT fr; u32 bytesWritten = 0; u32 bytesRead, totalBytesRead; u8 buff[12], *buffptr; xil_printf("PmodSD Demo Launched\r\n"); // Mount the disk DFATFS::fsmount(disk, szDriveNbr, 1); xil_printf("Disk mounted\r\n"); fr = file.fsopen("newfile.txt", FA_WRITE | FA_CREATE_ALWAYS); if (fr == FR_OK) { xil_printf("Opened newfile.txt\r\n"); fr = file.fswrite("It works!!!", 12, &bytesWritten); if (fr == FR_OK) xil_printf("Write successful\r\n"); else xil_printf("Write failed\r\n"); fr = file.fsclose(); if (fr == FR_OK) xil_printf("File close successful\r\n"); else xil_printf("File close failed\r\n"); } else { xil_printf("Failed to open file to write to\r\n"); } fr = file.fsopen("newfile.txt", FA_READ); if (fr == FR_OK) { buffptr = buff; totalBytesRead = 0; do { fr = file.fsread(buffptr, 1, &bytesRead); buffptr++; totalBytesRead += bytesRead; } while (totalBytesRead < 12 && fr == FR_OK); if (fr == FR_OK) { xil_printf("Read successful:"); buff[totalBytesRead] = 0; xil_printf("'%s'\r\n", buff); } else { xil_printf("Read failed\r\n"); } } else { xil_printf("Failed to open file to read from\r\n"); } while (1); }
This demo code along with all header files are available in the Pmod library. Link: https://github.com/Digilent/vivado-library/releases/tag/v2019.1-1
Output video after running the program:
2.6 Design to boot Linux:
A block design was created with various IP blocks available with the board, such as Clock, Microblaze softcore IP, Quad SPI, UART lite, and the MIG 7 series for the DDR3 interface.
An attempt to boot PetaLinux was made with the above block design but was not successful because of an error in the bitstream generation.
Here's a possible solution, but still unable to fix this error due to the clock pin allocation, upgrading to a newer version of Vivado might solve this issue.
A possible solution Link: https://www.xilinx.com/support/answers/60480.html
2.7 Why use this board?
As many might be thinking, why this board? this part of the test shall address it.
Given above are 3 development boards, all of them feature the Artix-7 FPGA. But comparatively cheaper than the USB104-A7 board.
As one might notice user GPIO and the onboard switches and other components such as 7-segment are absent in the USB104 board. This is because of the key features of the USB104-A7 board that the other two boards do not have. I have listed them below:
The images given below explains how the USB hub is used in the USB104-A7 to route various signals.
{tabbedtable} Comparison | Tab Content |
---|---|
In regular boards |
Micro USB directly connected to the FT2232 Chip for both JTAG and USB-UART in Regular boards |
USB104-A7 |
FT2232 Connected to the Hub rather than directly connecting to the USB |
USB104-A7 |
JTAG connected to the USB Hub via the controller
|
USB104-A7 |
FT232 Connected to the USB Hub for DPTI |
The above points explain why one can use this board rather than going for others.
Testing the GPIO with a custom Pmod:
I shall start by saying the quote: “The expert at anything was once a beginner.” – Helen Hayes
People starting to learn hardware description languages might need the slide switches and the LEDs for sure.
As one would've realized by now that the board still lacks much user GPIO because it's all consumed by the DPTI and the Zmod, to address this issue, a custom Pmod is fabricated.
Let's take a look at the schematic for the fabrication.
Design made with NI Multisim:
From the schematics, it can be understood that using a 10k resistor would be used for pull-up and pull-down purposes.
As there is already a 200 Ohm resistor connected in series to the Pmod GPIO to prevent damage to the FPGA if one accidentally drives an input as an output,
only 100 Ohm resistor is used in series with the LEDs. All switches are active high. The circuit diagram is given below:
Started with the above components, some PCB mount slide switches, LEDs, and the Bent Male-Male Dual pin headers.
After soldering all the components and the connections:
Here is the general constraints file for the above-fabricated Pmod:
## Pmod Header JA #set_property -dict { PACKAGE_PIN F4 IOSTANDARD LVCMOS33 } [get_ports { led[0] }]; #IO_L13P_T2_MRCC_35 Sch=ja[1] #set_property -dict { PACKAGE_PIN F3 IOSTANDARD LVCMOS33 } [get_ports { led[1] }]; #IO_L13N_T2_MRCC_35 Sch=ja[2] #set_property -dict { PACKAGE_PIN E2 IOSTANDARD LVCMOS33 } [get_ports { led[2] }]; #IO_L14P_T2_SRCC_35 Sch=ja[3] #set_property -dict { PACKAGE_PIN D2 IOSTANDARD LVCMOS33 } [get_ports { led[3] }]; #IO_L14N_T2_SRCC_35 Sch=ja[4] #set_property -dict { PACKAGE_PIN H2 IOSTANDARD LVCMOS33 } [get_ports { led[4] }]; #IO_L15P_T2_DQS_35 Sch=ja[7] #set_property -dict { PACKAGE_PIN G2 IOSTANDARD LVCMOS33 } [get_ports { led[5] }]; #IO_L15N_T2_DQS_35 Sch=ja[8] #set_property -dict { PACKAGE_PIN C2 IOSTANDARD LVCMOS33 } [get_ports { led[6] }]; #IO_L16P_T2_35 Sch=ja[9] #set_property -dict { PACKAGE_PIN C1 IOSTANDARD LVCMOS33 } [get_ports { led[7] }]; #IO_L16N_T2_35 Sch=ja[10] ### Pmod Header JB #set_property -dict { PACKAGE_PIN C4 IOSTANDARD LVCMOS33 } [get_ports { sw_b[0] }]; #IO_L7P_T1_AD6P_35 Sch=jb[1] #set_property -dict { PACKAGE_PIN B2 IOSTANDARD LVCMOS33 } [get_ports { sw_b[1] }]; #IO_L10N_T1_AD15N_35 Sch=jb[2] #set_property -dict { PACKAGE_PIN B3 IOSTANDARD LVCMOS33 } [get_ports { sw_b[2] }]; #IO_L10P_T1_AD15P_35 Sch=jb[3] #set_property -dict { PACKAGE_PIN B4 IOSTANDARD LVCMOS33 } [get_ports { sw_b[3] }]; #IO_L7N_T1_AD6N_35 Sch=jb[4] #set_property -dict { PACKAGE_PIN B1 IOSTANDARD LVCMOS33 } [get_ports { sw_b[4] }]; #IO_L9P_T1_DQS_AD7P_35 Sch=jb[7] #set_property -dict { PACKAGE_PIN A1 IOSTANDARD LVCMOS33 } [get_ports { sw_b[5] }]; #IO_L9N_T1_DQS_AD7N_35 Sch=jb[8] #set_property -dict { PACKAGE_PIN A3 IOSTANDARD LVCMOS33 } [get_ports { sw_b[6] }]; #IO_L8N_T1_AD14N_35 Sch=jb[9] #set_property -dict { PACKAGE_PIN A4 IOSTANDARD LVCMOS33 } [get_ports { sw_b[7] }]; #IO_L8P_T1_AD14P_35 Sch=jb[10] ### Pmod Header JC #set_property -dict { PACKAGE_PIN C5 IOSTANDARD LVCMOS33 } [get_ports { sw_a[0] }]; #IO_L1N_T0_AD4N_35 Sch=jc[1] #set_property -dict { PACKAGE_PIN C6 IOSTANDARD LVCMOS33 } [get_ports { sw_a[1] }]; #IO_L1P_T0_AD4P_35 Sch=jc[2] #set_property -dict { PACKAGE_PIN B6 IOSTANDARD LVCMOS33 } [get_ports { sw_a[2] }]; #IO_L2N_T0_AD12N_35 Sch=jc[3] #set_property -dict { PACKAGE_PIN C7 IOSTANDARD LVCMOS33 } [get_ports { sw_a[3] }]; #IO_L4N_T0_35 Sch=jc[4] #set_property -dict { PACKAGE_PIN A5 IOSTANDARD LVCMOS33 } [get_ports { sw_a[4] }]; #IO_L3N_T0_DQS_AD5N_35 Sch=jc[7] #set_property -dict { PACKAGE_PIN A6 IOSTANDARD LVCMOS33 } [get_ports { sw_a[5] }]; #IO_L3P_T0_DQS_AD5P_35 Sch=jc[8] #set_property -dict { PACKAGE_PIN B7 IOSTANDARD LVCMOS33 } [get_ports { sw_a[6] }]; #IO_L2P_T0_AD12P_35 Sch=jc[9] #set_property -dict { PACKAGE_PIN D8 IOSTANDARD LVCMOS33 } [get_ports { sw_a[7] }]; #IO_L4P_T0_35 Sch=jc[10]
Running an example design (4-bit ALU):
3. Overall review:
My first impressions on the board were like, as soon as I unboxed it, found the board to be more compact than I expected. Almost all the components on the board are SMDs. The board seems so delicate yet robust.
One thing that I have to mention here is that even though it has a lot of useful features, it's not as popular as the other boards because beginners and developers prefer boards such as the Arty / Basys for getting started.
However, if you want to start with an industry-grade board, then this is the right one to start with, also if your design needs the use of high-resolution Analog to Digital Converters then you might want this board as it is one among the best to feature the dedicated Zmod port. The only place where I faced some problems was with the MIG IP as I am on a lower version of Vivado (2017.3). Upgrading to a higher version would probably solve the problem.
One thing I want to mention here is, the board does not have many tutorials/guides as compared to the famous boards such as the Arty, even the Pmod IPs which I used have been built around the Arty boards such that Vivado keeps warning about the board packaging. But then I hope the road tests would have covered maximum usage of these boards such that anyone who wants to build their design and get it running won't have much trouble searching for tutorials online. I have also solved the problem for beginners not wanting to start with this board by providing a guide to building a custom Pmod, I call it the Pmod Starter Pack.
4. Acknowledgments:
First of all, I thank Randall for giving me this opportunity. Secondly, I thank Daniel sir for arranging the shipment (I received the board just in time!)
Last but not the least, I thank Digilent, a National Instruments Company for sponsoring this road test.
Top Comments
yesha98 Very nice review!
The design and testing of custom PMOD is interesting.
Thanks, navadeepganeshu!
Thanks Yeshvanth