Remote Build Server

By default, Rapid HDL performs logic synthesis on the local machine. It is possible to set up a remote build server on a powerful computer in your lab or in the "cloud." The build might run faster than it would on your local computer, and your local computer is freed to do other tasks while the build processes.

Remote Building Steps

  • Rapid HDL generates Verilog files and puts them in the output folder (typically c:\rhdl_out\)
  • Rapid HDL generates build scripts for the ISE tools and puts them in the output folder
  • Rapid HDL copies firmware files from the firmware directory to the output folder
  • Rapid HDL compresses the output folder into a .tar.gz format file
  • Rapid HDL uses http transfer to send the .tar.gz compressed output folder to the build server
  • Rapid HDL invokes a webservice on the build server to begin the build process
  • The build server uncompresses the .tar.gz output folder
  • The build server service launches the ISE synthesis chain, calling xst, bitgen, etc.
  • Rapid HDL uses the webservice to monitor the status of the build
  • When the build completes, Rapid HDL receives any error message
  • Rapid HDL downloads the bitfile to the local output folder
  • Rapid HDL downloads the Xilinx build logs to the local output folder
  • Rapid HDL continues as usual

Setting Up the Client

A client Windows computer that uses the build server needs two utilities installed.
  • tar
  • gzip

Both programs can be installed from the GnuWin32 project.

The programs should be available from any directory through the windows path environment variable.

Setting Up the Server

The server must have mono installed (or the .Net runtime).

Set up a build folder on the server (~/rhdl_out). Copy the RapidHDL.dll Assembly into this folder.

RhdlSynthOnly.exe

RhdlSynthOnly.exe is the build server executable that launches the Xilinx build. The program itself is quite simple and relies on the RapidHDL.dll assembly for most of its work. Presently, paths are hard coded. You should probably update these settings and compile RhdlSynthOnly.exe on your own system.

using System;
using System.Collections.Generic;
using System.Text;
using RapidHDL;

namespace RHDLSynthOnly
{
    class Program
    {
        static void Main(string[] args)
        {
			bool bDebug = false;
			
			while(true)
			{
				if (WriteHandshake("ready"))
				{
					System.Console.WriteLine("RHDLSynthOnly Ready...");
				}
				else
				{
					System.Console.WriteLine("Error writing to file.");
					return;
				}
				
				string sHandshake = "";
				while (sHandshake != "go" && !bDebug)
				{
					WriteHandshake("ready");
					System.Threading.Thread.Sleep(2000);
					System.Console.Write(".");
					sHandshake = ReadHandshake();
				}
				
				WriteHandshake("working");
                
                System.Console.WriteLine("\n\nUnpacking...");
                XilinxTools.UnpackUploadedDirectory("/home/user/rhdl_out/","v");


				System.Console.WriteLine("\n\nCompiling...");
				
				
				RapidHDL.Settings oSettings = new Settings();
	            string sBuildErrors = 
	                XilinxTools.LaunchXilinxBuild(
	                    "", 
	                    "/home/user/rhdl_out/", 
	                    oSettings.TopComponentName, 
	                    oSettings.XilinxChip, 
	                    oSettings.OptimizeSpeed,
	                    "CFBase-noppc.ucf"
	                    );
	            if (sBuildErrors == "")
				{
					WriteHandshake("success");
	                Console.WriteLine("\n OK!");
				}
	            else
				{
					WriteHandshake(sBuildErrors);
	                Console.WriteLine(sBuildErrors);
				}

				if (bDebug)
					return;
				
				Console.WriteLine("Waiting For Client");
				sHandshake = "";
				while (sHandshake != "done")
				{
					System.Threading.Thread.Sleep(2000);
					System.Console.Write(".");
					sHandshake = ReadHandshake();
				}

			}
        }

		
		public static string ReadHandshake()
        {
            return ReadStatusFile("handshake.txt");
        }

        public static bool WriteHandshake(string psStatus)
        {
            WriteStatusFile("handshake.txt", psStatus);
            return true;
        }

        public static string WriteStatusFile(string psFileName, string psStatus)
        {
            try
            {
                System.IO.StreamWriter oFile = RapidHDL.TextFile.OpenFileReWrite(psFileName);
                oFile.Write(psStatus);
                oFile.Close();
                return "";
            }
            catch
            {
                return "Unable to open status file : " + psFileName.ToString();
            }
        }

        public static string ReadStatusFile(string psFileName)
        {
            try
            {
                System.IO.StreamReader oFile = RapidHDL.TextFile.OpenFileRead(psFileName);
                string sResult = oFile.ReadToEnd();
                oFile.Close();
                return sResult;
            }
            catch
            {
                return "Unable to read status file : " + psFileName.ToString();
            }
        }

	}
}

Copy RhdlSynthOnly.exe to the build folder on the server.

RhdlSynthOnly.exe is a console application that runs at all times and monitors for updates from the webservice. A simple script to start the build service using mono is shown below. The first command initializes Xilinx environment variables on a linux system. The second line launches the application using mono.

    source home/user/xilinx.sh
    mono RHDLSynthOnly.exe

Installing The WebService

The mono xsp2 web server is used to implement a simple webservice. The webservice is located in SynthXilinx.asmx.

SynthXilinx.asmx

	<%@ WebService language="C#" class="RemoteSynth.Synth" Debug="true" %>
	
	using System;
	using System.Web.Services;
	using System.Xml.Serialization;
	using System.IO;
	using RapidHDL;
	
	
	namespace RemoteSynth
	{
		[WebService(Namespace="http://server.org/RemoteSynth")]
		public class Synth : WebService 
		{
		    	[WebMethod]
	    		public byte[] GetFile(string filename) 
	 	   	{
	        		BinaryReader binReader = new 
					BinaryReader(File.Open(Server.MapPath(filename), FileMode.Open, FileAccess.Read));
	        		binReader.BaseStream.Position = 0;
			        byte[] binFile =
					 binReader.ReadBytes(Convert.ToInt32(binReader.BaseStream.Length));
	        		binReader.Close();
	        		return binFile;
			}
	
			[WebMethod]
	    		public void PutFile(byte[] buffer, string filename) 
			{
	        		BinaryWriter binWriter = new
				BinaryWriter(File.Open(Server.MapPath(filename), FileMode.Create, FileAccess.Write));
	        		binWriter.Write(buffer);
			        binWriter.Close();
			}
	    
	    
			[WebMethod]
			public string SynthXilinx(string psTopComponentName, string psXilinxChip, bool pbOptimizeSpeed,	string psUCF) 
			{
				try 
				{
					RapidHDL.Settings oSettings = new RapidHDL.Settings();
					string sBuildErrors = RapidHDL.XilinxTools.LaunchXilinxBuild("","/home/user/rhdl_out/", 
				                    psTopComponentName, 
	        	        		    psXilinxChip, 
	        	        		    pbOptimizeSpeed,
				                    psUCF);
			            	if (sBuildErrors == "")
				                 sBuildErrors = "OK!";
		       	    		return sBuildErrors;
				}
				catch (Exception e)
				{
					return e.Message;
				}
	 		}
		}   
	} 


SynthXilinx.asmx should also be located in the output folder.

To start the webservice, run xsp2 in the output folder.

Amazon Web Services

The build server can be run in the Amazon Compute Cloud, where an 8-processor virtual machine can be rented for $.80 per hour. We used the Alestic Ubuntu Desktop images, installed Xilinx ISE, and set up the build folder as described above.

Build Server Security

What? Security?

Last edited Sep 10, 2009 at 11:24 PM by allen248, version 4

Comments

No comments yet.