...
for instance i:gpio[7:0] will be expanded to i:gpio7,i:gpio6,i:gpio5,i:gpio4,i:gpio3,i:gpio2,i:gpio1,i:gpio0 and then starts over at i:gpio7
top to bottom | bottom to top |
---|---|
Comma Separated Ranges
Multiple ranged sigNames can be separated by commas,
...
To skip wiring pins in between valid sigNames use !skip or !nc as a sigName
i:gpio[3:0],!skip,o:gpio[7:4]
or
to skip multiple pins use the bussed form of !skip or !nc
i:gpio[3:0],!nc[3:0],o:gpio[7:4]
Multiple Ranges in one SigName
More powerful alternation can be specified in between the square brackets
[digit:digit] like [0:7] or [3:11] will expand to the full range of bus_numbers
[foo|bar|zed] using the '|' character will round robin from
foo to bar to zed and then back to foo
a common use of this is to add [p|n] which will alternate p then n for diff_pairs
...
Alternations with the '|' character
DiffPair signals are usually entered in sequence with sig1_p, sig1_n,sig2_p,sig2_n
The Smart SIG_NAME(s) entry easily supports this using a range with anything separated by the pipe '|' character
note here the sig1 and sig2 alternations are n|p and the sig3 alternation is p|n
The alterations are not limited to simple characters,
the user could enter o:led_[red|green|orange|purple|muave]
Multiple Ranges in one SigName
Multiple alternations in the sigName are handled gracefully.
The alternations are expanded in a loop type order where the rightMost alternation is the inner most loop
So a complex bus of diff pairs can be added like this:
pcie_[rxsw0|txsw1]_dq[3:0][p|n]
PinWire sees 3 alternations, the sw0|sw1 the 3:0 and the [p|n] this will expand to:
pcie_rx_dq3p pcie_rx_dq3n
pcie_rx_dq2p pcie_rx_dq3n
pcie_rx_dq1p pcie_rx_dq1n
pcie_rx_dq0p pcie_rx_dq0n
pcie_tx_dq3p pcie_tx_dq3n
pcie_tx_dq2p pcie_tx_dq3n
pcie_tx_dq1p pcie_tx_dq1n
pcie_tx_dq0p pcie_tx_dq0n
More advanced interleaved alternations available and are described in the help page for this entryThere are 3 alternations, the rightmost has 2 values, the middle one has 4 values and the leftmost has 2 values
so this will create a sequence of 2*4*2 or 16 sigName values
The first signame starts with the leftmost value of each alternation which is 'rx', '3' and 'p'
The resulting first signame in the sequence is: pcie_sw0_dq3p
then it cycles the rightmost alternation to 'n' to create: pcie_sw0_dq3n
then it cycles the rightmost alternation back to 'p' and bumps the middle alternation to '2' to create: pcie_sw0_dq2p
then pcie_sw0_dq2n
Here is a table of all the alternations and the resulting sigNames in sequence
alternation value | alternation value | ||||||||
---|---|---|---|---|---|---|---|---|---|
seq# | lt | mid | rt | sigName | seq# | lt | mid | rt | signame |
1 | sw0 | 3 | p | pcie_sw0_dq3p | 9 | sw1 | 3 | p | pcie_sw1_dq3p |
2 | sw0 | 3 | n | pcie_sw0_dq3n | 10 | sw1 | 3 | n | pcie_sw1_dq3p |
3 | sw0 | 2 | p | pcie_sw0_dq2n | 11 | sw1 | 2 | p | pcie_sw1_dq2p |
4 | sw0 | 2 | n | pcie_sw0_dq2p | 12 | sw1 | 2 | n | pcie_sw1_dq2p |
5 | sw0 | 1 | p | pcie_sw0_dq1n | 13 | sw1 | 1 | p | pcie_sw1_dq1p |
6 | sw0 | 1 | n | pcie_sw0_dq1p | 14 | sw1 | 1 | n | pcie_sw1_dq1p |
7 | sw0 | 0 | p | pcie_sw0_dq0n | 15 | sw1 | 0 | p | pcie_sw1_dq0p |
8 | sw0 | 0 | n | pcie_sw0_dq0p | 16 | sw1 | 0 | n | pcie_sw1_dq0p |
Interleaving Busses of Signals using Alternation with inc_dec operators
Sometimes the user will need to interleave signals in a complicated sequence with the first 2 signals of one bus, 4 signals of the next bus, 1 signal of the next bus, 4 signals of the previous bus....
[dig1:dig2:inc_dec_op] range operator like:
in:pcie0_sw_rx[3:0:1][p|n],in:pcie1_sw_rx[3:0:1][p|n],
...
pcie0_sw_rx3p,pcie0_sw_rx3n
pcie1_sw_rx3p,pcie1_sw_rx3n
pcie0_sw_rx2p,pcie0_sw_rx2n
pcie1_sw_rx2p,pcie1_sw_rx2n
pcie0_sw_rx1p,pcie0_sw_rx1n
pcie1_sw_rx1p,pcie1_sw_rx1n
pcie0_sw_rx0p,pcie0_sw_rx0n
pcie1_sw_rx0p,pcie1_sw_rx0n
(the result of which is 2 busses of diff_pairs interleaved)
Interleaving with Modifiers to the inc_dec_op
The increment operator can also provide a HI_NIB or LO_NIB modifier to tell it to use the upper 4 bits
or the lower 4 bits of a bus
io:dqs[3:0:1][c|t],io:dq[31:0:8:HI_NIB],!skip,in:dm_[3:0:1],io:dq[31:0:8:LO_NIB],
This expands to
io:dqs[3][c|t],dq[31:28],!skip,in:dm3,io:dq[27:24],
io:dqs[2][c|t],dq[23:20],!skip,in:dm2,io:dq[19:16],
io:dqs[1][c|t],dq[15:12],!skip,in:dm1,io:dq[11:8],
io:dqs[0][c|t],dq[7:4],!skip,in:dm0,io:dq[3:0],
which then gets fully expanded to a sequence that can be used to wire a xilinx fpga for ddr4 memory
Using the Existing NetName(s) sig Browser to create the Smart SIG_NAME(s) List
...
If the user wants to control the order the signal names get added, it works better to just double click a single Name from the list in the order they want, and each one signal will get added to the Smart SIG_NAME(s) entry in that order
Smart SIG_NAME text file
The user may also select a text file containing signal names
split by commas and by lines
When the user selects the Edit button next to the Smart SIG_NAME Entry, and the Entry contains a string but does not point to a file,
The user will be prompted to Pick a filenName to save to.
If that file does not end in ".pl", the contents of the Smart SIG_NAME Entry will be added to the file
The commas will be replaced with newLines so there will be one sigName on each line in the file for easier editing
When the user saves the file, pinWire will process the contents of the Text file, just as if they were directly entered in the Smart SIG_NAME(s) Entry
Smart SIG_NAME Perl File
If the user is comfortable using Perl, they can write a perl script to generate a string
of comma seperated separated signal names that must be assigned to the variable named \$expString.
In this case, the user is responsible to make sure the Perl compiles cleanly
or a warning will popUp that
may or may not be easy to figure out
When the user selects the Edit button next to the Smart SIG_NAME Entry, and the Entry is empty or does not point to a file,
The user will be prompted to Pick a fileName to save to.
If the file they choose ends in .pl, pinWire will create an empty template file with the following contents.
Code Block | ||||||||
---|---|---|---|---|---|---|---|---|
| ||||||||
#!/usr/bin/perl use strict; use warnings; my $expString=""; #you need to create code that adds comma separated signal names to the $expString variable #note that strict is enforced so you need to declare your variables with 'my' #Insert code here #End insert code print "\$expString=$expString\n"; #this needs to be the last thing you do in this code $expString=$expString; |
the User should put their code to build the $expString in between the
#Insert code here
and the
#End insert code
Here is an example of some valid perl code which will build up a list of sigNames
Code Block | ||||||||
---|---|---|---|---|---|---|---|---|
| ||||||||
#!/usr/bin/perl use strict; use warnings; my $expString=""; #you need to create code that adds comma separated signal names to the $expString variable #note that strict is enforced so you need to declare your variables with 'my' #Insert code here foreach my |
...
$i (0..3){ foreach my $j (0..1){ foreach my $pn (qw(p n)){ $expString.="I:pcie_sw" . $j ."_rx_" .${i} .${pn}. ","; } } } #End insert code print "\$expString=$expString\n"; #this needs to be the last thing you do in this code $expString=$expString; |
Here is the resulting value of expString (split with newlines for easier reading) which will be passed to pinWire.
Code Block |
---|
$expString=I:pcie_sw0_rx_0p,I:pcie_sw0_rx_0n,
I:pcie_sw1_rx_0p,I:pcie_sw1_rx_0n,
I:pcie_sw0_rx_1p,I:pcie_sw0_rx_1n,
I:pcie_sw1_rx_1p,I:pcie_sw1_rx_1n,
I:pcie_sw0_rx_2p,I:pcie_sw0_rx_2n,
I:pcie_sw1_rx_2p,I:pcie_sw1_rx_2n,
I:pcie_sw0_rx_3p,I:pcie_sw0_rx_3n,
I:pcie_sw1_rx_3p,I:pcie_sw1_rx_3n,
|
pinWire will process the contents of the expString from the Perl Code, just as if they were directly entered in the Smart SIG_NAME(s) Entry
Bonus Perl Code to Create DDR4 Signal Names for modern Xilinx FPGAs with 50 Pin I/O banks.
Code Block | ||||
---|---|---|---|---|
| ||||
#!/usr/bin/perl use strict; use warnings; my $expString=""; #you need to create code that adds comma separated signal names to the $expString variable #note that strict is enforced so you need to declare your variables with 'my' #Insert code here my $highLow=0; #set to 1 for bus 63:32, set to 0 for bus 31:0 my $byteOrderHighToLow=0; #set to 1 to make the bytes/strobes descend #set to 0 to make them ascend my $msb_unib=$highLow? 63 : 31; my $msb_lnib=$msb_unib-4; my $dqs_start=$highLow? 7 : 3; my @loopList=$byteOrderHighToLow ? (0,1,2,3) :(3,2,1,0); #skip the first 4 pins in the bank (to get to first strobe pins $expString="!skip[3:0],"; foreach my $i (@loopList) |
...
{ #add strobe diff pair $expString.=sprintf( |
...
"io:dqs%d_c,io:dqs%d_t,",
$dqs_start-$i,
$dqs_start-$i,
);
#add upper nibble
$expString.=sprintf(
"io:dq[%d:%d],",
($msb_unib)-8*$i,($msb_unib)-8*$i-3,
);
#skip the _n pin
$expString.="!skip,";
#add the dm pin
$expString.=sprintf(
"in:dm%d,",
$dqs_start-$i,
);
#add the lower nibble
$expString.=sprintf(
"io:dq[%d:%d],",
($msb_lnib)-8*$i,($msb_lnib)-8*$i-3
);
}
#End insert code
print "\$expString=$expString\n";
#this needs to be the last thing you do in this code
$expString=$expString;
|