Skip to content

Commit

Permalink
Merge pull request #345 from byuccl/xdcConstraintInterface
Browse files Browse the repository at this point in the history
XDC constraints interface & XDC Constraint Package Pin
  • Loading branch information
trharoldsen authored Mar 24, 2018
2 parents 578c5e2 + 81341b1 commit 9afeeac
Show file tree
Hide file tree
Showing 5 changed files with 203 additions and 73 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -806,6 +806,35 @@ public void addVivadoConstraint(XdcConstraint constraint) {
}
vivadoConstraints.add(constraint);
}

/**
* Creates a map from port cells to the sites the cells are constrained to be placed on according to the
* imported constraints.xdc.
* @return the map from port cells to their sites
*/
public Map<Cell, Site> getPortConstraintMap() {
Map<Cell, Site> portConstraintMap = new HashMap<>();
if (vivadoConstraints == null)
return portConstraintMap;

for (XdcConstraint constraint : vivadoConstraints) {
if (constraint.getPackagePinConstraint() == null)
continue;

// Get the port cell
Cell portCell = this.getCell(constraint.getPackagePinConstraint().getPortName());
assert(portCell.isPort());

// Get the package pin's site
Site site = device.getSite(constraint.getPackagePinConstraint().getPinName());
assert(site != null);

// Add to the port map
portConstraintMap.put(portCell, site);
}

return portConstraintMap;
}

/**
* Creates and returns a deep copy of the current CellDesign.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,7 @@
import java.util.Map;
import java.util.Set;

import edu.byu.ece.rapidSmith.design.subsite.BelRoutethrough;
import edu.byu.ece.rapidSmith.design.subsite.CellDesign;
import edu.byu.ece.rapidSmith.design.subsite.CellLibrary;
import edu.byu.ece.rapidSmith.design.subsite.CellPin;
import edu.byu.ece.rapidSmith.design.subsite.*;
import edu.byu.ece.rapidSmith.device.Bel;
import edu.byu.ece.rapidSmith.device.BelPin;
import edu.byu.ece.rapidSmith.device.Device;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -96,8 +96,10 @@ public static VivadoCheckpoint loadRSCP (String rscp, boolean storeAdditionalInf
design.setImplementationMode(mode);

// parse the constraints into RapidSmith
parseConstraintsXDC(design, rscpPath.resolve("constraints.xdc").toString());

String constraintsFile = rscpPath.resolve("constraints.xdc").toString();
XdcConstraintsInterface constraintsInterface = new XdcConstraintsInterface(design, device);
constraintsInterface.parseConstraintsXDC(constraintsFile);

// re-create the placement and routing information
String placementFile = rscpPath.resolve("placement.rsc").toString();
XdcPlacementInterface placementInterface = new XdcPlacementInterface(design, device);
Expand All @@ -117,42 +119,7 @@ public static VivadoCheckpoint loadRSCP (String rscp, boolean storeAdditionalInf

return vivadoCheckpoint;
}

/**
* Loads Vivado constraints into the specified {@link CellDesign}. For now, these constraints are
* loaded as two strings, a command and a list of arguments. There is no attempt right now to
* intelligently handle these constraints, and they are included so the user has access to them.
* TODO: Update how we handle constraints files to make them easier to move
*
* @param design {@link CellDesign}
* @param constraintPath File location of the constraints file. Typically rscpDirectory/constraints.rsc is the constraints file.
*/
private static void parseConstraintsXDC(CellDesign design, String constraintPath) {

try (BufferedReader br = new BufferedReader(new FileReader(constraintPath))) {

String line = null;
// add the design constraints to the design
while ((line = br.readLine()) != null) {

String trimmed = line.trim();

// Skip commented lines
if (trimmed.startsWith("#") || trimmed.length() < 1)
continue;

// assuming a space after the command TODO: make sure this assumption is correct
int index = trimmed.indexOf(" ");
String command = trimmed.substring(0, index);
String options = trimmed.substring(index + 1);
design.addVivadoConstraint(new XdcConstraint(command, options));
}

} catch (IOException e) {
throw new Exceptions.ParseException(e);
}
}


/**
* Export the RapidSmith2 design into an existing TINCR checkpoint file.
*
Expand Down Expand Up @@ -185,36 +152,12 @@ public static void writeTCP(String tcpDirectory, CellDesign design, Device devic
EdifInterface.writeEdif(edifOut, design);

// write constraints.xdc
writeConstraintsXdc(design, Paths.get(tcpDirectory, "constraints.xdc").toString());

String constraintsOut = Paths.get(tcpDirectory, "constraints.xdc").toString();
XdcConstraintsInterface constraintsInterface = new XdcConstraintsInterface(design, device);
constraintsInterface.writeConstraintsXdc(constraintsOut);

// write design.info
String partInfoOut = Paths.get(tcpDirectory, "design.info").toString();
DesignInfoInterface.writeInfoFile(partInfoOut, design.getPartName());
}

/**
* Reads the Vivado constraints from the specified {@link CellDesign} and creates a
* constraints.xdc file representing the constraints. The file is written to the newly
* created TINCR checkpoint.
*
* @param design {@link CellDesign}
* @param xdcOut Constraints.xdc file path
* @throws IOException
*/
private static void writeConstraintsXdc(CellDesign design, String xdcOut) throws IOException {

try (BufferedWriter fileout = new BufferedWriter (new FileWriter(xdcOut))) {

LocalDateTime time = LocalDateTime.now();

fileout.write(String.format("##############################################################\n"
+ "# Generated by RapidSmith v.2.0 on %02d/%02d/%02d at %02d:%02d:%02d\n"
+ "##############################################################\n\n",
time.getMonthValue(), time.getDayOfMonth(), time.getYear(), time.getHour(), time.getMinute(), time.getSecond()));

for (XdcConstraint constraint : design.getVivadoConstraints()) {
fileout.write(constraint + "\n");
}
}
}
} // END CLASS
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@

package edu.byu.ece.rapidSmith.interfaces.vivado;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
* This class holds design constraints found in the constraints.xdc file.
* TODO: Make these constraints easier to work with
Expand All @@ -30,10 +33,21 @@ public final class XdcConstraint {

private final String command;
private final String options;

public XdcConstraint(String command, String options){
private final String comment;
private XdcConstraintPackagePin constraintPackagePin;
private static final Pattern patternPackagePin = Pattern.compile("\\s*set_property\\s+.*PACKAGE_PIN\\s+(\\w+)\\s+.*\\[\\s*get_ports*\\s+\\{?\\s*([^{}\\s]+)\\s*}?\\s*].*$");

public XdcConstraint(String command, String options, String comment){
this.command = command;
this.options = options;
this.comment = comment;

// Set the package pin if this constraint includes one.
String constraint = command + " " + options;
Matcher matcher = patternPackagePin.matcher(constraint);
if (matcher.find()) {
constraintPackagePin = new XdcConstraintPackagePin(matcher.group(1), matcher.group(2));
}
}

/**
Expand All @@ -49,12 +63,49 @@ public String getCommandName() {
public String getOptions() {
return options;
}

/**
* @return the comment of the XDC constraint. null if there is no comment.
*/
public String getComment() { return comment; }

/**
* Formats the XDC constraint and returns it as a string.
*/
@Override
public String toString(){
return command + " " + options;
return (comment != null) ? command + " " + options + " " + comment : command + " " + options;
}

/**
* @return The XDC pin package constraint instance
*/
public XdcConstraintPackagePin getPackagePinConstraint() {
return constraintPackagePin;
}

public class XdcConstraintPackagePin {

private String pinName;
private String portName;

XdcConstraintPackagePin(String pinName, String portName) {
this.pinName = pinName;
this.portName = portName;
}

/**
* @return The name of the pin that the net is constrained to (eg. D7)
*/
public String getPinName() {
return pinName;
}

/**
* @return The name of the port that is constrained to a pin.
*/
public String getPortName() {
return portName;
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
/*
* Copyright (c) 2018 Brigham Young University
*
* This file is part of the BYU RapidSmith Tools.
*
* BYU RapidSmith Tools is free software: you may redistribute it
* and/or modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation, either version 3 of
* the License, or (at your option) any later version.
*
* BYU RapidSmith Tools is distributed in the hope that it will be
* useful, but WITHOUT ANY WARRANTY; without even the implied warranty
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* A copy of the GNU General Public License is included with the BYU
* RapidSmith Tools. It can be found at doc/LICENSE.GPL3.TXT. You may
* also get a copy of the license at <http://www.gnu.org/licenses/>.
*/

package edu.byu.ece.rapidSmith.interfaces.vivado;

import edu.byu.ece.rapidSmith.design.subsite.*;
import edu.byu.ece.rapidSmith.device.*;

import java.io.*;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;

/**
* This class is used for parsing XDC constraint files and adding them into a RS2 design.
*
* @author Dallon Glick, Dr. Jeffrey Goeders, Thomas Townsend
*
*/
public class XdcConstraintsInterface {
private final CellDesign design;
private final Device device;

public XdcConstraintsInterface(CellDesign design, Device device) {
this.design = design;
this.device = device;
}

/**
* Parses a single line from constraints.xdc, makes an XdcConstraint, and adds it to the design.
* @param line the constraint line to parse
*/
private void parseConstraintsLine(String line) {
int optIdx = line.indexOf(" ");
int cmntIdx = line.indexOf("#");
String command = line.substring(0, optIdx);
String options = (cmntIdx != -1) ? line.substring(optIdx + 1, cmntIdx).trim() : line.substring(optIdx + 1).trim();
String comment = (cmntIdx != -1) ? line.substring(cmntIdx) : null;
design.addVivadoConstraint(new XdcConstraint(command, options, comment));
}

/**
* Loads Vivado constraints into the specified {@link CellDesign}. For now, these constraints are
* loaded as two strings, a command and a list of arguments. For package pin constraints, the pin and corresponding
* port is saved. Otherwise, there is no attempt right now to intelligently handle these constraints, and they are
* included so the user has access to them.
* TODO: Update how we handle constraints files to make them easier to move
* @param xdcFile constraints.xdc file
* @throws IOException
*/
public void parseConstraintsXDC(String xdcFile) throws IOException {
LineNumberReader br = new LineNumberReader(new BufferedReader(new FileReader(xdcFile)));
String line;

while ((line = br.readLine()) != null) {
String trimmed = line.trim();

// Skip empty and comment lines
if (trimmed.length() < 1 || trimmed.startsWith("#"))
continue;

parseConstraintsLine(trimmed);
}

br.close();
}

/**
* Reads the Vivado constraints from the {@link CellDesign} and creates a
* constraints.xdc file representing the constraints. The file is written to the newly
* created TINCR checkpoint.
*
* @param xdcOut Constraints.xdc file path
* @throws IOException
*/
public void writeConstraintsXdc(String xdcOut) throws IOException {
try (BufferedWriter fileout = new BufferedWriter (new FileWriter(xdcOut))) {
LocalDateTime time = LocalDateTime.now();

fileout.write(String.format("##############################################################\n"
+ "# Generated by RapidSmith v.2.0 on %02d/%02d/%02d at %02d:%02d:%02d\n"
+ "##############################################################\n\n",
time.getMonthValue(), time.getDayOfMonth(), time.getYear(), time.getHour(), time.getMinute(), time.getSecond()));

if (design.getVivadoConstraints() != null) {
for (XdcConstraint constraint : design.getVivadoConstraints()) {
fileout.write(constraint + "\n");
}
}
}
}
}

0 comments on commit 9afeeac

Please sign in to comment.