VHDL includes two major additions to Ada for component interface and behavior, oblivious to the Ada Package construct. These two additions are primarily responsible for VHDL being incompatible as a regular programming language. VHDL syntax and examples are available on the CD-ROM distributed by SIGAda. VHDL AND ADA DESCRIPTION OF AN ADDER. A ripple carry adder is probably taught to every computer science student and will be used here as an example. It is abstracted from Ref.[1], p.511. -- VHDL full_addr entity entity full_addr is -- one bit adder port (ci: in bit; -- carry in a,b: in bit; -- summands sum, co: out bit); -- co is carry out end full_addr; Without studying the VHDL syntax, the reader is invited to participate in deciphering the above for translation into Ada. The Entity appears to be similar to a Package specification. The port looks like either a functional subprogram declaration or a record type declaration. The latter is more appropriate because many objects of that type may be declared in a circuit, such as each bit of a word-sized adder. The data type "bit" is probably defined in some "standard package" and could be represented as boolean but then what do we do with the in/out distinctions. VHDL was first defined at a time when bipolar transistor-transistor logic (TTL) were dominant components. In Kernel Ada, we define all signals as basically boolean but with subtypes of input and output, more for purpose of readability than for typing. This is put into a global declaration package. package HDL is -- contains standard type definitions subtype input is boolean; subtype output is boolean; type bus is array (natural range <>) of boolean; subtype inbus is bus; subtype outbus is bus; end HDL; The next step is translating entity full_addr to a package specification. The names ci and co are needlessly concise, a half-century tradition of circuit designers. These are extended to be more directly meaningful. The VHDL reserved word "port" has been changed to "device" as more descriptive of current usage. Avoidance of VHDL non-Ada reserved words as identifiers is also desirable for future translations between the two languages. This format is adopted for all component package specifications. The Ada package specification contains the declaration of procedure update for the device. FULL_ADD.update is obviously different from MULTIPLY.update. The name update is used throughout other component packages for uniformity. The reason that the update parameter is of in out type is to enable various types of devices to be updated. Some components contain internal state memories which are necessary for correct outputs. The contents of an accumulator is such a device. -- Kernel Ada package specification for FULL_ADD device with HDL; package FULL_ADD is type device is record carry_in, input1, input2 : HDL.input := FALSE; sum, carry_out : HDL.output:= TRUE; end record; procedure update (d: in out device); end FULL_ADD; We next look at the VHDL architecture for full_addr: -- VHDL full_addr architecture architecture full_addr of full_addr is begin sum <= a xor b xor ci; co <= ((a or b) and ci) or (a and b); end; The architecture of VHDL looks like it belongs to a procedure all by itself. In Ada, this unit properly belongs in a Package Body. The VHDL peculiarity of repeating full_addr in the architecture declaration need not be of concern for translation to Ada; we leave that to writers of translators between Ada and VHDL. The contents of architecture full_addr looks much like Ada statements except for the symbol "<=" which is not a less-equal symbol. Considering it as an assignment symbol makes sense. VHDL designers may have been influenced by Algol's "<-" symbol. Since the statement assigns values to outputs as functions of inputs, it amounts to updating a procedure whenever inputs are changed. However, ":=" is also used in other parts of VHDL not shown in this simple example. More specifically, IEEE 1076 VHDL LRM syntax 8.4 [1]: sequence of statement::= ... signal_assignment_statement ::= [label:] target <= [delay_mechanism] waveform; variable_assignment_statement ::= [label:] target := expression; indicates that the VHDL designers may have been unfamiliar with logic circuit design experience. There is no need to separate signals from variables at the logic design level. They can both be modeled as boolean variables. We next translate the VHDL Architecture to the Ada package body: -- Kernel Ada package body FULL_ADD package body FULL_ADD is procedure update (d: in out device) is begin d.sum := d.input1 xor d.input2 xor d.carry_in; d.carry_out := ((d.input1 or d.input2) and d.carry_in) or (d.input1 and d.input2); end update; end FULL_ADD; The above simple example demonstrates that it is trivial to change from VHDL Entity and Architecture to Kernel Ada. The next step is a test of the implementation to check for correctness. Unlike VHDL, Kernel Ada is a programming language, so that a test program using package add is relatively trivial. Before this is done, a UTILITY package is added for convenience in generating texts for testing purposes. -- Kernel Ada testing utilities with HDL; package UTILITY is procedure put (s: boolean); procedure putms1st (b: HDL.bus); end UTILITY; with TEXT_IO; -- assuming compiled with -gnat83 switch package body THDL is procedure put (s: boolean) is begin if s then TEXT_IO.put ('1'); else TEXT_IO.put ('0'); end if; TEXT_IO.put (" "); end put; procedure putms1st (b: cdl.bus) is begin for i in reverse b'range loop if b(i) then TEXT_IO.put ('1'); else TEXT_IO.put ('0'); end if; end loop; TEXT_IO.put(" "); end putms1st; end UTILITY; Next follows a simple testing program: -- Kernel Ada sample testing program for device FULL_ADD with FULL_ADD, HDL, UTILITY, TEXT_IO; procedure test_adder is d: FULL_ADD.device; begin TEXT_IO.put_line ("a b carry_in sum carry_out"); for i in false..true loop d.carry_in:= i; for j in false..true loop d.input2:= j; for k in false..true loop d.input1:= k; UTILITY.put(d.input1); UTILITY.put(d.input2); UTILITY.put(d.carry_in); ADDER.update(d); UTILITY.put(d.sum); UTILITY.put(d.carry_out); TEXT_IO.new_line; end loop; end loop; end loop; end test_adder; The test output for FULL_ADD is a (correct) table as follows: input1 input2 carry_in sum carry_out 0 0 0 0 0 1 0 0 1 0 0 1 0 1 0 1 1 0 0 1 0 0 1 1 0 1 0 1 0 1 0 1 1 0 1 1 1 1 1 1 COMPARISON BETWEEN VHDL AND KERNEL ADA RIPPLE ADDERS Ref[1] goes on to declare an 8-bit adder. -- VHDL RIPPLE ADDER entry ripadd_8 is port (ci: in bit; a7,a6,a5,a4,a3,a2,a1,a0: in bit; b7,b6,b5,b4,b3,b2,b1,b0: in bit; sum7,sum6,sum5,sum4,sum3,sum2,sum1,sum0: out bit; co: out bit); end ripadd_8; architecture ripadd_8 of ripadd_8 is component bit_adder port (ci: in bit; a,b: in bit; sum, co: out bit); end component; signal c1,c2,c3,c4,c5,c6,c7: in bit; begin u1: bit_adder port map(ci, a0, b0, sum0, c1); u2: bit_adder port map(c1, a1, b1, sum1, c2); u3: bit_adder port map(c2, a2, b2, sum2, c3); u4: bit_adder port map(c3, a3, b3, sum3, c4); u5: bit_adder port map(c4, a4, b4, sum4, c5); u6: bit_adder port map(c5, a5, b5, sum5, c6); u7: bit_adder port map(c6, a6, b6, sum6, c7); u8: bit_adder port map(c7, a7, b7, sum7, co); end; There is no valid reason that word length must be a power of 2 such as 8, 16, 32, 64 or even 128 bits. This was a valid consideration in the old days when a few vacuum tubes were saved by recognizing counts of powers of 2 by checking the carry, but this is the VLSI age. The following generic Ada package is valid for adders of arbitrary number of bits. -- KERNEL ADA RIPPLE ADDER with HDL; generic n: positive; package ADDN is type device is record a, b : HDL.inbus (0..n-1); sum : HDL.outbus (0..n-1); carry_in : HDL.input; carry_out: HDL.output; end record; procedure update(d: in out device); end ADDN; with ADDER; package body ADDN is procedure update(d: in out device) is n_adder: array (0..n-1) of ADDER.device; carry_out: boolean := d.carry_in; begin for i in reverse 0..n-1 loop n_adder(i).carry_in:= carry_out; n_adder(i).a:= d.a(i); n_adder(i).b:= d.b(i); ADDER.update(n_adder(i)); d.sum(i):= n_adder(i).sum; carry_out:= n_adder(i).carry_out; end loop; d.carry_out:= carry_out; end update; end ADDN; We leave it to the reader to implement a test program for the above adder. [1] IEEE Standard VHDL Language Reference Manual, IEEE Std 1076-1993, VHDL. (revised from 1076-1987) June 6, 1994.