The RASSP Digest - Vol. 3, September 1996


ANSI C to Behavioral VHDL Translator
Ada to Behavioral VHDL Translator

by Robert J. Sheraga


1. Introduction

JRS Research Labs has developed two source language Translators, an Ada-to-VHDL Translator and a C-to-VHDL Translator, as part of the RASSP BAA program, under contract No. F33615-94-C-1497 with Wright Laboratory WL/AAKE.

The Translators perform source-to-source code translation, i.e., given an input program coded in Ada or C, the output is a behavioral VHDL source code program which is functionally equivalent to the original input program, in the sense that a VHDL compilation and simulation of the translated file will produce the same results as an Ada or C compilation and execution of the original source file.

Much of the program structure, data structures, identifier names, and even comments from the input program are preserved. The VHDL source file produced by the Translators is portable and independent of a specific VHDL implementation.

The Translators provide an automated method for translating existing code libraries from Ada or C into behaviors in VHDL which can be directly simulated. This provides a generalized tool to aid the process of hardware/software codesign, which can be used either standalone or incorporated into a larger tool framework.

2. Technical Approach

An intermediate form called the HIL (High-level Intermediate Language) was defined as an intermediate step in the translation process. The HIL form is at a relatively high level of abstraction, so that high level language constructs such as declarations, expressions, statements, etc. can be directly expressed. Compilers were developed using the Unix tools Lex (scanner) and Yacc (parser generator) to compile both Ada and C to the HIL form. A single HIL-to-VHDL Translator was then developed, which accepts the HIL form from both frontends and generates behavioral VHDL source code. This Translator module utilizes a rules file which defines the translation rules for each HIL statement. The user is permitted to provide certain types of special application-specific extensions to the translation rules. A runtime library was hand-coded in VHDL to provide some necessary runtime support for the translated programs.

3. Operation Summary

The input to the Translators is a source file coded in either Ada 95 or ANSI C. The full languages are supported for parsing, although some program constructs or statements may not be translatable into VHDL, and appropriate error or warning messages are issued for such statements. Ada input files may contain any number of compilation units. For C input files, the user has a choice of preprocessing header files or not.

The output program is structured such that any translated input file results in a VHDL output file which can be directly compiled in VHDL. Since VHDL does not permit subprograms as compilation units, procedures and functions which are translated are encapsulated in a package. The Ada Translator supports a rudimentary library system for context clauses, so that translating a set of Ada programs has the same order-of-translation requirements as compiling them with an Ada compiler, i.e., WITH'ed units must be translated first. For C programs, each input file is translated into a single VHDL package; statements outside functions are placed in the package specification, along with a subprogram declaration for each function. The package body contains the subprogram bodies.

The Translators can also automatically generate an entity/architecture testbench for validating the translated programs, subject to some limitations.

4. Restrictions and Limitations

The Translators are, in general, limited to those features which are directly supportable in VHDL; however, there are some exceptions to this rule. Although the Ada-to-VHDL Translator accepts Ada 95 syntax, virtually all of the Ada 95 extensions, such as tagged, abstract, and protected types, child packages, etc., are not supported for VHDL translation, since there are no corresponding VHDL capabilities. The major features of Ada 83 which are unsupported are tasking, exceptions, subunits, fixed point types, representation clauses, most attributes, and certain classes of records not supported in VHDL, such as variant and discriminated records.

The C-to-VHDL Translator does not support variable length argument lists, abstract declarators, GOTO statements, automatic type conversions, certain types of complex switch statements, subarrays, and some other minor items. Because pointers are so important in C programs, partial support for pointers and pointer operations is provided even though VHDL does not support pointers directly. Support is limited to simple local pointers to scalar types. Thus, parameters or local variables declared as "int *" or "float *" are supported, but constructs such as pointers to functions, arrays, or structures, arrays of pointers, functions returning pointers, and pointers to pointers are not supported at this time.

A limited runtime support library is provided with the Translators, which includes primarily basic math routines. Specifically, the Translators do not include support for the full standard Ada 95 and ANSI C libraries. However, references to these library routines are not errors, per se, since they will result in the generation of valid VHDL source code containing equivalent calls. However, the user is responsible for creating the VHDL support packages necessary to compile and/or simulate programs which utilize these library functions.

5. Results and Status

The Ada-to-VHDL Translator correctly translates 302 of 315 Ada routines in a library of signal processing primitives obtained from the government. The C-to-VHDL Translator correctly translates 410 of 499 C routines in a commercial library of signal processing routines. These translations were validated by VHDL simulation of the translated source files. Numerous other test cases were also run successfully, including some standard Ada ACVC tests and standard C benchmark programs.

6. Summary and Conclusions

Hardware and software development are no longer separate camps, but are fast merging as a result of hardware/software codesign methodologies utilizing tools which focus on the overall system design problem. As the boundary between hardware design and software design continues to blur, it becomes increasingly important that algorithms be transportable, or at least easily convertible, between functionality expressed in Ada and C on the software side, and VHDL on the hardware side. If we view Ada and C not only as programming languages but also as specification languages for algorithms for which we intend to eventually synthesize hardware implementations, then the importance of these issues becomes even more apparent. A VHDL version of an algorithm coded in Ada or C can be used to synthesize custom hardware to implement the algorithm, or as part of a VHDL functional simulation of a processor designed to execute the algorithm.

Future considerations for the Translators include removing some of the language restrictions, generating optimized VHDL code, and generating VHDL code which is optimized for synthesis and/or targeted to a specific synthesis environment.

7. Example Program

Input file:
------------
/* Complex Vector Power Computation -- C version */

void voc_pwr_c (n, x, y, z)
int    n;
float  *x;
float  *y;
float  *z;
{
	int i;
	float *xp, *yp, re, im;
	xp = x;
	yp = y;
	*z = 0.0;
	for (i=0; i < n; i++) {
		re = *xp++;
		im = *xp++;
		*yp = re*re + im*im;
		*z += *yp++;
	}
}
Output file:
--------------
use work.C_Data_Types.all;
use work.HVT_Runtime_Library.all;
package voc_pwr_c is   
	-- Source file is /a+b/sonia/hvt/c2h/src/voc_pwr_c.c
	-- Source language is C
	--/* Complex Vector Power Computation -- C version */
	procedure voc_pwr_c
		(n : in Integer;
		x_Array : inout Float_Array;
		y_Array : inout Float_Array;
		z_Array : inout Float_Array);
end voc_pwr_c;
package body voc_pwr_c is   
	procedure voc_pwr_c
			(n : in Integer;
			x_Array : inout Float_Array;
			y_Array : inout Float_Array;
			z_Array : inout Float_Array) is   
		variable x : Pointer_to_Float := x_Array'Left;
		variable y : Pointer_to_Float := y_Array'Left;
		variable z : Pointer_to_Float := z_Array'Left;
		variable i : Integer;
		variable xp : Pointer_to_Float := nil;
		variable yp : Pointer_to_Float := nil;
		variable re : Real;
		variable im : Real;
	begin   
		xp := x;
		yp := y;
		z_Array(z) := 0.0;
		i := 0;
		while i < n loop   
			re := x_Array(xp);
			xp := xp + 1;
			im := x_Array(xp);
			xp := xp + 1;
			y_Array(yp) := re * re + im * im;
			z_Array(z) := z_Array(z) + 						y_Array(yp);
			yp := yp + 1;
			i := i + 1;
		end loop;
	end voc_pwr_c;
end voc_pwr_c;

Robert J. Sheraga
JRS Research Laboratories, Inc.
1036 W. Taft Avenue
Orange, California 92665-4121
bob@jrs.com


Newsletter Index
The RASSP Digest - Vol. 3, September 1996
newsletter/html/96sep/news_11.html