|
CNets and Datapaths |
|||
|
Home Generators vs. synthesis >> << CNets
Usenet Postings |
Subject: Re: Has anyone ever used a C -> Xilinx netlister?
Date: 24 Oct 1996 00:00:00 GMT
newsgroups: comp.arch.fpga
Austin Franklin <darkroom-@ix.netcom.com> wrote in article
<01bbbefd$7414e3b0$a1cab7c7@drt1>...
> There are two C -> Xilinx netlisters I know of, and I am curious if
anyone
> has any experience with them, or any others.
>
> The first I know of is called NLC, developed by Christian Iseli at the
> System Logic Lab of the Federal Polytechnical School of Lausanne,
> Switzerland. The second I know of was developed by the networking group
of
> Digital in California.
>
> Thanks,
>
> Austin Franklin
> darkroom-@ix.netcom.com
Certainly Digital has one.
I have my own tool, called CNets, which emits XC4000 XNF. It is a set of
classes which extend C++ with user defined types to describe nets, buses
(vector of nets), and gate expressions. There are also functions to emit
primitives such as flip-flops, SRAMs, TBUFs, IBUFs, etc. My processor
designs are specified in CNets.
I wrote CNets for three reasons.
* I was growing old drawing and labeling 32-bit datapath elements in
ViewLogic
* the DOS WorkView tools didn't seem to work very well under Win95 or NT,
and I loathe DOS
* I couldn't afford Verilog or VHDL tools, and neither could other people
(computer engineering hobbyists) with whom I wish(ed) to share my tools
In retrospect, and particularly in light of recent discussions about doing
Xilinx designs using VHDL, CNets, though primitive, has turned out to be
quite a pleasant design environment -- the best of both worlds.
Like schematic capture, all primitive instantiations, placements, and other
constraints, are explicit (if you wish). No "pushing on a rope" to get the
design you have in mind through the HDL synthesis tool. Floorplanning
datapaths is a breeze. And since I tend to do my own "mental technology
mapping" (of gates into LUTs), by default CNets automatically emits FMAPs
for 2-4 input logic functions.
Like HDLs, CNets is based on a programming language, therefore it is easy
to have functions, loops, conditionals, variable-width structures,
lookup-tables, conditional emission of logic, etc. Best of all, CNets
designs recompile, relink, run, and emit the new XNF, ready for place and
route, in less than ten seconds. Wait another 30 minutes for PPR and
you're done. :-) Also, for users familiar with C++, CNets should be more
familiar than Verilog or VHDL.
To give you a feel for CNets, attached below are some examples of code from
one of my designs. Keep in mind this was a first cut, a quick hack, to get
my darn designs going.
This past summer I started CNets, version 2, in Java -- "JHDL" if you will.
Key new features included better support for design 'modules' and a
cycle-based simulator. Unfortunately, I didn't finish this project. I may
yet try again this fall in my copious spare time.
Cheers,
Jan Gray
lfsr_div emits lfsr counters to divide by arbitrary n. It is similar to an
XBLOX counter with style LFSR. The first half of the function determines
how many bits are in 'n', what the lfsr shift register bits 'w' look like
after 'n' clockings. The second half of the function actually emits an
n-bit shift register, whose input is the xnor of certain taps off the shift
register. The formal arguments are
out -- the net which is true after n clockings of the LFSR counter
ce -- the counter clock enable
reset -- if true, reset the counter on next clock edge
n -- the divisor
// emit an lfsr counter and decoder to divide by n
//
// See "Efficient Shift Registers, LFSR Counters, and
// Long Pseudo-Random Sequence Generators", Peter Alfke,
// Xilinx App Note, Aug. 1995
//
void lfsr_div(Net out, Net ce, Net reset, unsigned n) {
Env e;
e.setModule(out.getName());
// choose appropriate width counter
static unsigned taps[32][4] = {
{ 0 }, { 0 }, { 0 }, { 3, 2 },
{ 4, 3 }, { 5, 3 }, { 6, 5 }, { 7, 6 },
{ 8, 6, 5, 4 }, { 9, 5 }, { 10, 7 }, { 11, 9 },
{ 12, 6, 4, 1 }, { 13, 4, 3, 1 }, { 14, 5, 3, 1 }, { 15, 14 },
{ 16, 15, 13, 4 }, { 17, 14 }, { 18, 11 }, { 19, 6, 2, 1 },
{ 20, 17 }, { 21, 19 }, { 22, 21 }, { 23, 18 },
{ 24, 23, 22, 17 }, { 25, 22 }, { 26, 6, 2, 1 }, { 27, 5, 2, 1 },
{ 28, 25 }, { 29, 27 }, { 30, 6, 4, 1, }, { 31, 28 }
};
check(n <= (1 << 30));
for (unsigned bits = 1; n >= (1U << bits); bits++)
;
check((1U << (bits-1)) <= n && n < (1U << bits));
// determine bit pattern of terminal state (after n-1 clockings of lfsr)
unsigned w = 0;
for (unsigned i = 1; i < n; i++) {
unsigned in = 0;
for (unsigned j = 0; j < 4 && taps[bits][j]; j++)
in ^= (w >> (taps[bits][j]) - 1) & 1;
w = ((w << 1) & ((1 << bits) - 1)) ^ !in;
check(w != 0);
}
// emit shift register and gates to compare to terminal state
bus(lfsr, bits+1);
out = lfsr(bits,1) == w;
lfsr[0] = gnd;
net(lfsr_in) = xnor(lfsr[taps[bits][0]], lfsr[taps[bits][1]],
lfsr[taps[bits][2]], lfsr[taps[bits][3]]);
net(lfsr_reset) = out | reset;
ff(lfsr[1], lfsr_in & ~lfsr_reset, ce);
for (i = 2; i <= bits; i++)
ff(lfsr[i], lfsr[i-1] & ~lfsr_reset, ce);
}
Some of the trickier constructions:
out = lfsr(bits,1) == w;
-- drive 'out' with an AND gate which is true when the bits lfsr[bits:1]
match the bit pattern in the integer 'constant' w.
net(lfsr_in) = xnor(lfsr[taps[bits][0]], lfsr[taps[bits][1]],
lfsr[taps[bits][2]], lfsr[taps[bits][3]]);
-- drive
Copyright © 2000, Gray Research LLC. All rights reserved. |