• 0

Cmod A7 pio[discontinuous range of index!]: what to do?


On Cmod A7, the xdc file lists pio[1] to pio[48], but there are gaps at 15,16 (which are instead analog input pins) and 24,25 (which don't exist).

So when I create a Verilog top module that uses pio, how to I specify these discontinuous ranges? Conceptually I want:

module top ( input sysclk, output [1:14, 17:23, 26:48] )  but obviously that's not valid syntax.

So how DO you use the full set of pio's as written in the xdc file?

The file in question:


Edited by gwideman
Added link to xdc file

Share this post

Link to post
Share on other sites

4 answers to this question

Recommended Posts

  • 0


I split it into pioA, pioB and pioC groups, as follows:


module top(input wire CLK12, 
	   output wire [1:0]  LED, 
	   output wire 	      RGB0_Red, 
	   output wire 	      RGB0_Green, 
	   output wire 	      RGB0_Blue, 
	   input wire [14:1]  pioA, // 14 
	   input wire [23:17] pioB, // 7
	   input wire [48:26] pioC, // 23
	   inout wire [7:0]   ja, // 8
	   input wire [1:0]   BTN, 
	   input wire [1:0]   xa_n, 
	   input wire [1:0]   xa_p);

and the constraints file:

set_property PACKAGE_PIN L1 [get_ports {pioA[13]}]
set_property IOSTANDARD LVCMOS33 [get_ports {pioA[13]}]
set_property PULLDOWN true [get_ports {pioA[13]}]
set_property PACKAGE_PIN L2 [get_ports {pioA[14]}]
set_property IOSTANDARD LVCMOS33 [get_ports {pioA[14]}]
set_property PULLDOWN true [get_ports {pioA[14]}]
set_property PACKAGE_PIN M1 [get_ports {pioB[17]}]
set_property IOSTANDARD LVCMOS33 [get_ports {pioB[17]}]
set_property PULLDOWN true [get_ports {pioB[17]}]
set_property PACKAGE_PIN N3 [get_ports {pioB[18]}]
set_property IOSTANDARD LVCMOS33 [get_ports {pioB[18]}]
set_property PULLDOWN true [get_ports {pioB[18]}]

Not pretty, but at least I don't need to renumber.

Share this post

Link to post
Share on other sites
  • 0

Hi @xc6lx45,

Yeah, I ended up renaming and renumbering as well. I just figured if the xdc was supplied written as a discontinuous array, there must be some way to use it as such.


Share this post

Link to post
Share on other sites
  • 0

One thing I realized in the course of mulling this question: Part of my early resistance to splitting pio[...] into pioA, pioB and pioC was that I wanted to implement a bus that would span those ranges, and had a mental block about how to achieve that.

It's not very difficult, but in case someone else has the same hiccup, I'll post an example solution here:

module top(
    input   sysclck,
    output  [1:0]   led,
    input  [14:1]   pioA,
    input  [23:17]  pioB,
    input  [48:26]  pioC
    wire [8:1] mybus;    
    assign mybus[4:1] = pioA[14:11];
    assign mybus[8:5] = pioB[20:17];
    assign led[0] = &mybus;
    assign led[1] = &pioA[10:1]; 

I should note in passing that the supplied xdc file has another problem.

In the supplied xdc file, pio[1]..pio[9] are written as pio[01]..pio[09], as in:

set_property -dict { PACKAGE_PIN M3    IOSTANDARD LVCMOS33 } [get_ports { pio[01] }]; #IO_L8N_T1_AD14N_35 Sch=pio[01]

The xdc file is a TCL language file, and it may not be evident what the { pio[01] } actually means. It looks like it would be an array pio, with index 01, which one might assume is an integer, and thus equivalent to plain 1.

In fact, the {...} is syntax to enclose a string, which is not to be interpolated (no substitutions made). So the result of { pio[01] } is the string:

" pio[01] "

... including the spaces!  In short, the string " pio[01] " is used verbatim as a string key for some array/hashtable/dictionary. It does not imply that there's an array called "pio", from which this code fetches the item at index 1.

But then how does this match up to a particular port object declared in module top's declaration (where pio[14:1] treats the numbers in the index range as integers).

There is some mechanism in get_ports or somewhere that must match this string index ("key") to top's port declaration. So the {...} string as written in the xdc file has to follow the pattern that the matching algorithm uses, which pio[01] does not, apparently.

Consequently, xdc's pio[01] fails to match top.v's pio[1], etc.  (And Vivado will give some obtuse error message about "Unspecified I/O Standard", and fails to generate bitstream.)

Instead, you have to edit the xdc file for all the cases where pio[xx] has a leading zero, and remove it. So, for example,  { pio[01] } should be edited to { pio[1] }. This does satisfy the matching algorithm.

For further illumination on this syntax, you might like to try the following code:

set result A
append result { pioA[01] }
append result B
puts $result

... at an online TCL interpreter, like: https://www.tutorialspoint.com/execute_tcl_online.php

This prints a result "A pioA[01] B", demonstrating that the action of the {...} syntax used in the xdc file is simply to produce a string, which is used verbatim as an argument to get_ports.

Edited by gwideman
Added TCL sample and link to TCL interpreter. Added more explanation.

Share this post

Link to post
Share on other sites
  • 0


so I'm not the only one who's fighting with the template constraints files. Slightly annoying, sends you searching in the wrong direction... Well, it's a problem I have avoided so far, not solved.

At least the error message can be explained: For un"constrained" ports, Vivado picks a random package pin, effectively suggests a floorplan. Strange feature, but it's there. Now it doesn't assign random IO standards, that would make little sense. The initial "DEFAULT" isn't valid. Therefore the error message

Share this post

Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now