Announcing CHDL

by chad

Strange things happen as a consequence of the lack of freedom in the hardware world. Consider the case of the man who made a CPU out of discrete transistors because he was uncomfortable with FPGA vendor lock-in. (http://www.6502.org/users/dieter/mt15/mt15.htm) I do not pretend to understand the EDA community enough to make any claims about the tools they do or do not have, open source or otherwise. I have experienced a lack, but it may just be the rarified air of the field when compared to software-oriented disciplines. Other tools exist. I have not found the ones I have encountered particularly well-suited to my personal needs, so I have built another.

CHDL (call it “the” CHDL at your peril) is two things: a C++-based hardware description language and a C++ hardware design library. The former fills a perceived need for radical generality and simplicity in gate-level design specification and the latter fills a need for a free software toolchain for realizing these designs.

CHDL (the language) can be used to specify abstract digital logic designs with uncommonly terse syntax. Designs specified in this way can then be subject to optimizations and simulated directly or written out to netlists. It is the processing of these netlists that is the domain of CHDL (the library) and the related utilities. The netlist files may be translated to other HDLs (like ones supported by FPGA vendor toolchains), translated to C and simulated more quickly, or technology mapped and physically implemented.

What does CHDL code look like? Here is a a nontrivial design from the standard library: a Kogge-Stone adder:

 template  bvec Adder(bvec a, bvec b, node cin = Lit(0)) {
    vector<bvec<N+1>> g(log2(N)+3), p(log2(N)+3), i(log2(N)+3);
    bvec s;

    g[0][0] = cin;
    p[0][0] = Lit(0);

    for (unsigned j = 0; j < N; ++j) p[0][j+1] = Xor(a[j], b[j]);
    for (unsigned j = 0; j < N; ++j) g[0][j+1] = a[j] && b[j];

    unsigned k;
    for (k = 0; (1l<<k) < 2*N; ++k) {
      for (unsigned j = 0; j < N+1; ++j) {
        if (j < (1l<<l)) {
          g[k+1][j] = g[k][j];
          p[k+1][j] = p[k][j];
        } else {
          i[k+1][j] = p[k][j] && g[k][j - (1l<<k)];
          g[k+1][j] = i[k+1][j] || g[k][j];
          p[k+1][j] = p[k][j] && p[k][j - (1l<<k)];
        }
      }
    }

    for (unsigned j = 0; j < N; ++j) s[j] = Xor(p[0][j+1], g[k][j]);
    return s;
  }

This template function, when called, instantiates an adder of the given size. It will instantiate one of these adders each time it is called. Note that all of the loops are run at design instantiation time. The function’s goal is to create some gates. Once it has returned, those gates occupy some global state, where they can then be simulated, optimized, or written out to a file.

I have placed the very-much-in-development CHDL on GitHub (https://github.com/cdkersey/chdl) along with the hope that I am not alone in my ambition, and that likeminded individuals will find value in these manic machinations.