| Welcome! |
|
Maia is a low-level verification language. Its purpose is to verify Verilog and VHDL modules, by using simple 'vectors' to drive the module inputs, and to check the resulting outputs. Maia code is simple and intuitive, and lets you trivially check HDL modules, without writing any Verilog or VHDL code. You don’t need to be a verification engineer to use Maia. You don't need to know how to write a testbench. If you know how your module should respond to a given set of inputs, then you can verify it. You can download a Maia compiler (
The Tutorials section contains a number of simple tutorial examples, which should get you up and running with Maia within a couple of hours. If you want to keep up to date with new releases, make sure to sign up on the Announcements mailing list.
What does a Maia program look like?At its simplest level, a program is no more than a declaration of the DUT, together with a list of test vectors; see tut8.tv, for example, from the Tutorials section. However, this style is suitable only for the simplest testbenches. More complex programs have the look-and-feel of C code (and, in fact, Maia will compile many simple C programs without modification). However, Maia is not simply a C-lookalike: it automates the processes of driving and testing timed device inputs and outputs, clock generation, stability checking, pipeline handling, and so on. This housekeeping is all handled implicitly by the compiler, rather than being explicitly coded by the user. Maia also provides the features which are required for HDL coding and verification, and which are missing from traditional C-like languages: 4-value logic, arbitrarily-sized variables, and bitfield handling, for example. For an example of a more complex program, see the triple-DES code in the Tutorials section. des_kats.tv is the Maia testbench; the equivalent Verilog testbench, for comparison, is des_kats.v.
What is a 'low-level verification language'?Early versions of VHDL and Verilog were first released in 1985. In the succeeding 25 years there has, arguably, been only one significant development in commercial functional verification: the release of 'e' in 1996 (and, to a lesser extent, System Science's Vera, at about the same time). These languages introduced or popularised a number of key verification methodologies, including the use of temporal assertions, constrained randomised stimulus generation, and coverage analysis. For any significant ASIC development, there's little question that the use of the methodologies pioneered by these languages is fundamental to producing a Right-First-Time device. Given this, surely it's clear that low-level verification - in other words, the verification of individual modules or limited groups of modules - should also be carried out using these languages, or their derivatives, such as SystemVerilog? Well... no. There are two very simple reasons:
This is where Maia fits in. Maia is targeted at module-level verification. It was specifically designed to be trivially easy to learn and use; by, and for, hardware engineers. It is simple to use because it is a declarative language. This means that you don't need to derive and write down a recipe for solving your problem; you instead write down the expected solution. Finding a route to that solution is the computer's problem, not yours.
A what language?Declarative. Take a look at this Maia program:
DUT { // the declaration of the Device Under Test
module MAC1 // declare the module interface...
@(.stages(3)) // ...just paste in the Verilog module
(input RST, CLK, // declaration (replacing '#' with '@')
input [3:0] A, B,
output [9:0] Q);
[RST, CLK, A, B] -> [Q]; // declare the format of any vectors used below
create_clock CLK; // declare clock inputs, with default timing
}
main() {
var4 i, j;
var10 sum = 0;
[1, .C, -, -] ->3 [sum]; // check that Q resets to 0 after 3 cycles
for all i // loop over all input combinations
for all j {
/* derive the expected sum using an 8-bit multiply. Apply i and j to
* the A and B inputs of the DUT, clock it, and confirm that the Q
* output has the expected value 3 cycles later */
sum += (i *$8 j);
[0, .C, i, j] ->3 [sum];
}
}
This is a complete, working, program; it tests a pipelined multiply-accumulate HDL module. The HDL code (in Verilog) multiplies two 4-bit inputs to give an 8-bit result, and adds the result to a 10-bit accumulator, over a period of 3 cycles. There's nothing in this Maia code that describes how the test should be carried out: the Maia code simply specifies the expected result. The compiler is smart enough to work out for itself how to carry out the test. Compare this to the traditional 'imperative' solution, coded in Verilog or VHDL: you have to provide clock and reset generators; you have to generate and drive device inputs; you have to collect device outputs and compare them against expected values; you have to carry out stability checking; you have to carry out manual pipeline loading and flushing; you have to write multi-process code to synchronise everything, advance time, report errors, and so on. But why bother? What value does any of this actually add to the design process? And surely you have something better to do than repeat this pointless exercise on every project? This is what distinguishes declarative languages from imperative languages, such as C, 'e', and SystemVerilog. You provide the expected solution: you don't waste your time explaining in minute detail how the computer might carry out the individual steps to arrive at an answer. This is 2010, after all; not 1985. |