UPGRADE YOUR BROWSER

We have detected your current browser version is not the latest one. Xilinx.com uses the latest web technologies to bring you the best online experience possible. Please upgrade to a Xilinx.com supported browser:Chrome, Firefox, Internet Explorer 11, Safari. Thank you!

Reply

Inconsistencies/errors in GPIO output between similar block designs

Highlighted
Observer
Posts: 18
Registered: ‎11-25-2016

Inconsistencies/errors in GPIO output between similar block designs

While working with getting familiar with the Vivado design flow using IP blocks, i've stumbled into an error which i have not been able to resolve on my own.

 

In a simple design, i've instantiated a Microblaze block, coupled with AXI GPIO blocks interfacing with the onboard switches and LEDs. With design 1 (please refer to images Design1 and Code1), attached code works as intended, with LEDs lighting according to the switched switches.

 

In another design, i've included an AXI IIC block, and another AXI GPIO block, to interface with the onboard pushbuttons. The code has been modified according to the new block design (Two GPIO instances have been instantiated, since the switches and LED outputs are on different AXI GPIO blocks). When programming the board with this design, and running the code (Code2), i am unable to both read the switches, or write to the LEDs. Ive tried alot of different code-snippets trying to read and write to the registers, doing manual setup of the GPIO etc., but with no success. If the same things are done in design 1, the changes works as intended.

 

As for a solution, i've tried regenerating the BSP sources multiple times, resynthesizing and -implementing the entire project, but with no success. I am not suspecting that the processor is running out of memory, since project 2 has a .elf size of 86kb (The Microblaze is inferred with 128kb BRAM). I've verified that the "xparameters.h" file gets updated when regenerating sources and has the correct device-ID's for the two AXI GPIO's in project 2.

 

I have verified that the pin-assigment of both implemented designs are as they should be - both projects have similar package pin placements (with the addition of the two i2c pins in design 2). 

 

I could be suspecting that there might be an error in my workflow, since i've previously had quite some trouble with design 1 aswell, but all of a sudden, it "just worked" - without me (unfortunately) being able to identify why it suddenly worked.

 

I am happy to provide any further information describing the problem. 

 

I am working with a Basys3 board. 

 

Code 1:

#include "xparameters.h"
#include "xil_types.h"
#include "xgpio.h"
#include "xstatus.h"

XGpio GPIO_inout;

int main (void) {

	  u32 status;
	  u32 DataRead = 0;
	  u32 OldData = 0;

	  // Clear the screens
	  xil_printf("%c[2J",27);
	  xil_printf("Running\n");

	  // Initialize the GPIO driver so that it's ready to use,
	  status = XGpio_Initialize(&GPIO_inout,
			  XPAR_AXI_GPIO_0_DEVICE_ID);

	  if (status != XST_SUCCESS)
	    return XST_FAILURE;

	  // Set the direction for channel 1 to be outputs
	  XGpio_SetDataDirection(&GPIO_inout, 1, 0x0);

	  // Set the direction for channel 2 to be inputs
	  XGpio_SetDataDirection(&GPIO_inout, 2, 0xFFFFFFFF);

	  while(1){
		  // Read switches
		  DataRead = XGpio_DiscreteRead(&GPIO_inout, 2);
		  if(OldData != DataRead){
		   xil_printf("Switches changed\n");
		   XGpio_DiscreteWrite(&GPIO_inout, 1, DataRead);
		   OldData = DataRead;
		  }
	  }
	  return 0;
}

 

Code 2:

 

#include "xparameters.h"
#include "xil_types.h"
#include "xgpio.h"
#include "xstatus.h"

XGpio GPIO_input;
XGpio GPIO_led;

int main (void) {

	  u32 status;
	  u32 DataRead = 0;
	  u32 OldData = 0;

	  // Clear the screens
	  xil_printf("%c[2J",27);
	  xil_printf("Running\n");

	  // Initialize GPIO's
	  status = XGpio_Initialize(&GPIO_input,
			  XPAR_AXI_GPIO_0_DEVICE_ID);

	  if (status != XST_SUCCESS)
	  	    return XST_FAILURE;

	  status = XGpio_Initialize(&GPIO_led,
	  			  XPAR_AXI_GPIO_1_DEVICE_ID);

	  if (status != XST_SUCCESS)
	    return XST_FAILURE;

	  // Everything in GPIO_0 is input
	  XGpio_SetDataDirection(&GPIO_input, 1, 0xFFFFFFFF);
	  XGpio_SetDataDirection(&GPIO_input, 2, 0xFFFFFFFF);

	  // Everything in GPIO_1 is output
	  XGpio_SetDataDirection(&GPIO_led, 1, 0x0);

	  while(1){
		  // Read switches
		  DataRead = XGpio_DiscreteRead(&GPIO_input, 1);
		  if(OldData != DataRead){
		   xil_printf("Switches changed\n");
		   XGpio_DiscreteWrite(&GPIO_led, 2, DataRead);
		   OldData = DataRead;
		  }
	  }
	  return 0;
}

 

design1.PNG
Design2.PNG
Mentor
Posts: 1,364
Registered: ‎11-14-2011

Re: Inconsistencies/errors in GPIO output between similar block designs

I haven't studied your code too greatly but what sort of STDIO output do you get when running code2? When you say you can't read the switches or write to the LEDs, what actually happens when you do try, i.e. what is it that you observe is wrong?

 

Can you put more debug output for each stage (perhaps with expected vs actual data)?

 

Can you chipscope the hardware to verify that bits are being correctly set at that lower level?

----------
"That which we must learn to do, we learn by doing." - Aristotle
Xilinx Employee
Posts: 268
Registered: ‎10-06-2016

Re: Inconsistencies/errors in GPIO output between similar block designs

Hi @s152999,

 

Which version of the tools are you using?

 

Regards,

Ibai

-------------------------------------------------------------------------
Don’t forget to reply, kudo, and accept as solution.
-------------------------------------------------------------------------
Observer
Posts: 18
Registered: ‎11-25-2016

Re: Inconsistencies/errors in GPIO output between similar block designs

I've tried migrating the project to Vivado 2017.2 (such that both Vivado and SDK are of the same version, 2017.2) and upgraded all IP cores which had an available upgrade . This did not resolve the error.
Observer
Posts: 18
Registered: ‎11-25-2016

Re: Inconsistencies/errors in GPIO output between similar block designs

I get the correct "Running" output, but after this, stuff seems to fail. By not being able to read the switches, i mean that i see no change in the DataRead variable when changing the switches and running XGpio_DiscreteRead(..), By not being able to write to the LEDs i mean that there is no change in the state of the LEDs when running XGpio_DiscreteWrite(..).

 

Ive recreated the project in vivado 2017.2, which now has the same errors, and simplified the project to contain only one AXI GPIO IP - image of the code is attached.

 

When running the debugger on this code, i get the correct "Running" output on the console, but stepping through the program;

  • The debugger enters the while(1) loop
  • DataRead is set to 0 when running DiscreteRead()
  • the if statement is terminated (it shouldn't be, though, as both dataRead and OldData are 0
  • the while(1) loop is exited
  • "EOP" is not printed to the console, this is for some reason skipped
  • the program ends up stepping between lines 41 and 42, forever, which are non-existent lines. Stepping here, i enter the           XGpio_DiscreteRead assembly file at line 41, and i step through an instance of the function call, entering line 42, doing seemingly nothing, and returning to line 41, continuously. 

 

Design3.PNG
Mentor
Posts: 1,364
Registered: ‎11-14-2011

Re: Inconsistencies/errors in GPIO output between similar block designs

OK. A bit weird that you fall out of the while loop.

 

Basic questions but:

 

1. Is your GPIO hardware correctly configured for 2 channels?

2. Is the DeviceID you are using for the GPIO actually correct? 

3. Can you insert the GetDataDirection functions after you have SetDataDirection and output the value to the STDIO (and also verify that the directions are correct)?

----------
"That which we must learn to do, we learn by doing." - Aristotle
Observer
Posts: 18
Registered: ‎11-25-2016

Re: Inconsistencies/errors in GPIO output between similar block designs

  1. Yes, i've enabled Dual Channel in the IP Configuration dialog of the AXI GPIO. After running XGpio_Initialize(&GPIO_0, XPAR_AXI_GPIO_0_DEVICE_ID);, the debug view shows that the GPIO_0 variable is dual (isDual = 1), and that the correct base address is set (0x40000000).
  2. in the generated "xparameters.h", only one instance of GPIO driver defines are present, for GPIO_0.When running XGpio_Initialize, i see that the GPIO_0 variable gets all of the defines in xparameters.h transferred correctly. 
  3. Adding GetDataDirection functions and printing to the STDIO, both channels return a data direction of 0 (which is incorrect).

I do not really have any experience with debugging on the assembly level nor using the chipscope, so i will take a look at this and see if i can figure out why the registers aren't being written to properly.

The error with the while loop just being skipped leads me to believe that there might be a compilation error as well?

Mentor
Posts: 1,364
Registered: ‎11-14-2011

Re: Inconsistencies/errors in GPIO output between similar block designs

How's it going with this? I'd recommend using chipscope to see exactly what and where data is being written when you try to access the GPIO components.

 

As I have little experience with the GPIO components, I'd also recommend writing your own HDL to act as the switch/LED interface with the correct bus interface (PLB or AXI or whatever). This should be a simple exercise and you won't need a software driver to access the interface - you can use the low level 32 bit read/write instructions. This may help narrow down exactly where the problems are coming from.

----------
"That which we must learn to do, we learn by doing." - Aristotle
Observer
Posts: 18
Registered: ‎11-25-2016

Re: Inconsistencies/errors in GPIO output between similar block designs

It ended up being solved in the worst possible way - after (another) complete remake of the project, it just seemed to work, and the error hasn't returned. So i was unable to locate the error.

Thank you for the tip on using the low-level r/w instructions. While i didn't get to use it on this problem, it will surely come in hand later on. I do plan on converting one of my RTL-components to an AXI-IP where using AXI R/W will come in hand.

 

Thank you for your continued help.