Editor's Note:  ESNUG 276 was an ambivalemt post for me.  On the up side,
  by posting Evan Shattock's letter about using a weird sort of natural
  selection to "breed" progressively better a FPGA design, I recieved all
  sorts of interesting letters from some of the great thinkers of the
  hardware design world currently examining this unusual design approach.
  I love that.  Makes for great ESNUG.

  The down side is that I then also (humorously) have to deal with what I
  affectionately call the "Wrath of Kurt".  :^)

  Kurt Baty and I have a great friendship that's developed over many years
  of independent consulting, dealing with Synopsys bugs, and just a shared
  general interest of all things technical.  Because we're independant
  consultants doing our own gigs, we usually only get to see each other a
  few times throughout the year.  When we do get together, we have a blast
  sharing what we've learned/discovered since we last saw each other.  Cool
  stuff.  But, in between those meetings, occassionally, out-of-the-blue,
  Kurt will send me these positively cryptic e-mails sharing some great new
  insight he's found.  The problem is that Kurt writes about the same amount
  of dialog Arnold Schwartzeneggar used in the movie "Terminator".  That
  is, he usually sends the e-mail equivalent of "grunts" accompanying his
  Great Discovery letters.  So, when I get these e-mails, I usually look at
  them for about 10 minutes, scratch my head, and make a mental note to make
  sure to ask Kurt "What the hell was that e-mail on XYZ all about?"

  And, of course, sometimes I forget to follow up on some topics.

  And then when they're independently mentioned by someone (sometimes years
  later) in ESNUG, I invariably get Kurt phoning with

    Kurt: "Hey, John, I told you about this X years ago!"

      Me: "No, you sent me some bizarre, stoic e-mail that might have
           contained an inkling of that idea X years ago and I forgot
           to ask you about it."

    Kurt: "No, it's right here!  See!  I've even remailed you the original
           e-mail I sent you X years ago!  See!  That's the very same idea
           being discussed in ESNUG now!"

      Me: "You know, Kurt, there's this invention called 'writing'.  It's
           pretty cool.  It lets you convey ideas to other people.  The
           only catch is that you've GOT TO PUT YOUR IDEAS IN WRITING!  Ugh!"

  And this recent mention of Genetic Programming in ESNUG is no different.
  In fact, this time I got two "Wrath of Kurt" phone calls on this.  And
  although I may bitch about it, I wouldn't have it any other way.  Kurt's a
  great guy.  I just wish he could learn to *write* sometimes...  :^)

                                              - John Cooley
                                                the ESNUG guy

( ESNUG 277 Item 1 ) ----------------------------------------------- [1/97]

Subject: (ESNUG 276 #0)  "Breeding" FPGA Designs Via Natural Selection

> Editor's Note: The implications of the following letter (below) just blew
> me away.  See http://www.newscientist.com/971115/features.html to
> read the complete details of what this guy is saying.  Whoa!  - John
> 
> From: "Evan Shattock" <ems@riverside-machines.com>
> 
> > There's a pretty amusing article in the 15th november '97 issue of "New
> > Scientist."   A 'researcher' loaded random configurations into a device
> > (he doesn't say which one, but it's probably a Xilinx XC4003) in an
> > attempt to produce a tone discriminator.  By selecting configurations
> > according to how successful they were, & 'breeding' these configurations
> > (i.e. randomly swapping bits between configurations), he eventually,
> > after 3500 generations, found a configuration that successfully
> > discriminated between a 1KHz and a 10KHz tone.  The circuit is
> > unclocked.  The cover describes the circuit as 'smart, strange, & beyond
> > our understanding'.
> >
> > According to the article, he produced this solution with "fewer than
> > one-tenth of the components that a human designer would have used".  (It
> > appears to have used 37 cells out of the 100).  But...
> >
> >  1.)  The circuit works only over a 10 degrees C range.
> >  2.)  It only works on one device.
> >  3.)  He doesn't seem to have checked the voltage range over which
> >       it works.
> >  4.)  Five of the cells are not logically connected to the others,
> >       but the circuit doesn't work without these cells.


From: Steve Casselman <sc@einstein.vcc.com>

John,

Try http://www.cogs.susx.ac.uk/users/adrianth/ices96/paper.html.  Of course,
it was done on a XC6200 which is pretty much the only chip you could do
this with.  It is really an awesome experiment.  Check out the part about
the cells that are not logically connected it is kinda scary.

The other experiment have been with a robot with an evolved avoidance
circuit and a evolved sorter (by John Kosa at Stanford).  Reconfigurable
computing is getting interesting now that you can generate hardware at
runtime.  The system that we sell has hardware programming tool that lets
you name a part (in VHDL or schematic) and change that gate at run time so
you can say "MyGate = nand2;" in your C code, and the bits that control
the gate called MayGate are changed during the running of the program.

  - Steve Casselman, President
    Virtual Computer Corporation

         ----    ----    ----    ----    ----    ----   ----

From: "Peter Alfke" <Peter.Alfke@xilinx.com>

John,

The researcher's name is Adrian Thompson, at the University of Sussex
(England). He needed an SRAM-based FPGA that tolerates a randomly generated
configuration pattern, and the only FPGA family with that feature is the
Xilinx XC6200 family.

The general topic is Generic Programming, and the sub-topic is Evolvable
Hardware.  There is an annual (July ) conference on this subject at Stanford,
headed by Professor John R. Koza.  So this stuff is not quite as weird or
far-out as the posting implied.

Also: NEVER feed a random configuration pattern into any FPGA from Altera, 
Atmel, Lucent, Xilinx or others, except the XC6200 devices.  I have watched
a crater opening in the plastic package and black smoke curling up.  Not a
pretty sight.  Smelly, too.

  - Peter Alfke
    Xilinx

         ----    ----    ----    ----    ----    ----   ----

From: eory@chdasic.sps.mot.com (Frank Eory)

Hi John,

Remember the old theory that 1000 monkeys with 1000 typewriters will
eventually produce the complete works of Shakespeare?  Most publishers
wouldn't advocate that as a viable methodology for producing quality
literature, but what if the 1000 monkeys could type REALLY fast and they had
a human editor guiding their efforts toward the desired goal?

This "Darwinist circuit design" methodology is a long way from being able to
yield production-worthy designs, but it has enough merit to warrant further
research.

  - Frank Eory
    Motorola

         ----    ----    ----    ----    ----    ----   ----

From: landmh@taec.toshiba.com (Howard Landman)

Gosh John, this is old news.  The researcher is Adrian Thompson of University
of Sussex.  The full details were published in the Genetic Programming '96
conference 18 months ago.  (It was at Stanford; I attended.)  I believe his
papers are all available on the web.

Only the more recent Xilinx parts can be used for this kind of work.  Older
models may burn themselves up when programmed with random bit strings.

By the way, the bit string breeding is not "randomly swapping bits", but
the standard Genetic Algorithm.  A crossover point is selected randomly,
then the left portion of one string is mated to the right portion of the
other string (and vice versa).  This allows chunks of circuitry which work
well together to have some chance of not being disrupted.  Some random
flipping of single bits is also used, but this is infrequent.

The next challenges in this line of research are to figure out how to evolve
circuits that work on more than one chip and are testable.

I found this really exciting too, but even just out of the papers at that
one conference, I'd give it second place behind Frederic Gruau's work on
evolving programs that generate neural networks (rather than evolving the
networks directly).  The implications for hardware design-by-evolution
are staggering.

  - Howard Landman
    Toshiba

         ----    ----    ----    ----    ----    ----   ----

From: "Andre' DeHon" <amd@cs.berkeley.edu>

Just in case no one else corrects this guy, Adrian Thompson's work uses the
XC6200 series.  This is a part designed by Tom Kean's group in England which
used to be Algotronix before Xilinx acquired them (and hence, the
architecture descends from the CAL architecture more than from the XC2-3-4K
series).  It has the features that:

  1) No bitstream will burn up the part (a feature which the XC2/3/4/5K do
     not share.)

  and

  2) The bitstream composition is published for the public (again, a feature
     which the XC2/3/4/5K do not share...  however, I believe Adrian does
     not take advantage of this fact, other genetic-programming researchers,
     such as the group at Stanford, do, however, take advantage of this
     feature.)

  - Andre' DeHon
    UC Berkeley BRASS

         ----    ----    ----    ----    ----    ----   ----

From: "Brad L. Hutchings" <hutch@ee.byu.edu>

Hi John,

I'm sure you probably have already gotten a busload of mail about this, but
these random bitstreams were loaded into a Xilinx 6200 series device.  This
device supports only single-sourced wires thus making it impossible to wire
two outputs together and cause a heat-producing short.  Randomly loading
bitstreams into a 4K series part in the hope that you would get something
useful would be akin to lobbing lemmings off of a cliff hoping one of them
would learn to fly before smacking the ground below.  The 4K part would
probably just burn up on the first random configuration.

I'm curious.  What implications do you see in all this?

  - Brad L. Hutchings (on sabbatical leave)
    Hewlett Packard Laboratories, Ltd.  Bristol, UK

         ----    ----    ----    ----    ----    ----   ----

From: Christopher Rose <chris@saros.co.uk>

Hi John,

This is similar to an demonstration we saw where a PhD student at Cambridge 
University demonstrated a "robot" vehicle which was placed in an 
environment with a number of obstacles.  On entry into the environment the 
car "knew" nothing of either the boundaries of the environment nor the 
obstacles.  It then proceeded to move about, crashing into the obstacles 
and building a map, so that after a short period of time is was able to 
rapidly move about within its space, and without coming into contact with 
any of the obstacles.

So far this is all good AI stuff.

The interesting thing is that the map was not built in memory, but by the 
random seeding of an algorithm within a Xilinx device, which was constantly 
reprogramming itself.  Analysing the content in the device once the vehicle 
had completed the learning process showed that many parts of the design had 
no physical connection to others, that two devices placed in the same 
vehicle and same environment would produce different designs, and that 
there was no obvious understanding of how the design actually worked.

Scary !

  - Chris Rose
    Saros Technology Ltd   Herts, UK

         ----    ----    ----    ----    ----    ----   ----

From: [ Kryton of the Red Dwarf ]

Hi, John.

Please withhold my name and company name if you choose to publish this.

Thompson's work is being done using a Xilinx 6200 series device, which has
some peculiar features that allow random bitstreams to not damage the
device.  Mainly the fact that there is no possibility of internal signals to
conflict and damage the device.  One of the main disadvantages with the
technique is that isolated and logically unconnected circuits on the device
can interact to produce the working design.  All the design effort that
people put in so that the variations in analogue signal levels due to
manufacturing processes do not effect the digital circuit operation are
reversed by this work.  It only works because of the analogue imperfections
in the device and capacitive loading and crosstalk between circuits.

If this approach was attempted with any other FPGA device it is almost
guaranteed to damage the device, due to the potential for multiple drivers
on a single line.

It is certainly a very interesting research result, but as it requires the
design to be 'grown' or 'evolved' for each particular device it operates on,
and actually requires the process irregularities to operate.  It doesn't
appear to be a useful general way forward. 

Saying all this, the guy did get his PhD based on this result...

  -  [ Kryton of the Red Dwarf ]

         ----    ----    ----    ----    ----    ----   ----

From: Paul Chow <pc@eecg.toronto.edu>

I was talking to John Koza and Forrest Bennett last year at FCCM (FPGA's for
Custom Computing Machines).  They are GA (Genetic Alogorithm) guys from
Stanford.  They mentioned that someone had "evolved" a 741 op amp circuit
using GA techniques (not on an FPGA).  This may have even been work that was
done at Stanford, but my memory fades.  It also had temperature stability
problems, but they figured they could add more into the list of
"requirements" to fix this.  Anyways, from talking to them the GA people
seem to be really latching onto the reconfigurable FPGAs that are now
available.

I don't think the circuit designers of the world need to worry about
their jobs...  yet.   :-)

  - Paul Chow
    University of Toronto

         ----    ----    ----    ----    ----    ----   ----

From: "Duncan M. (Hank) Walker" <walker@cs.tamu.edu>

John,

Why is this surprising?  Genetic learning can basically be viewed as a more
complex version of simulated annealing or simulated evolution.  It has been
widely used in optimization problems.  The fact that the specifications
above are relatively high level isn't that big a deal either, since the
same is true for analog synthesis tools (e.g. op amp with gain > 1000).
The big issue in all these things is what is the move function.  If you put
enough intelligence into the move function, you cut the number of
generations way down.  Xilinx array design and configuration logic already
highly constrains the design space.  Imagine instead if you were randomly
plopping down polygons on a mask.  One simple change that would probably
dramatically improve the results would be to constrain the configurations
to be legal circuits, i.e. no branchouts, nets must have only one source
and at least one sink, all gate inputs must be connected, etc.

Another way to think of this problem is that the researcher has created a
black box that can produce a binary result when fed two signals an order of
magnitude apart in frequency.  I think I could do it with a few Rs, Cs, and
gates.  I am not sure why one needs 37 CLBs to do it.

  - Duncan M. (Hank) Walker
    Texas A&M University

         ----    ----    ----    ----    ----    ----   ----

From: Tim Davis <timdavis@tdcon.com>

John,

Before you know it they will be trying to evolve engineers this way as a
cost savings measure.

  - Tim Davis
    Timothy Davis Consulting

         ----    ----    ----    ----    ----    ----   ----

From: kurt@wsfdb.com (Kurt Baty)

Sometimes, John Cooley, you amaze me.

I told you about this stuff three years ago.  I will admit that I learned
about it from Steve Goody in 1993, who got me to read Steven Levy's book
"Artificial Life", which devotes a chapter to this "emergent technology."
(In which technology emerges from random numbers.)

I immediately (in 1993) thought this was a terribly cool thing, and embarked
on a 3-day coding orgy to be able to breed AMD MACH parts.  

In June of 1996 I sent you a specimen set of code for a simple small PAL
breeding program.  Now, I will admit, I did not write you a lay-person 
article explaining this technology.  I have never claimed to be able to
write such things.  However, YOU could have understood what I was telling you.

I'm including my original mail and code to you at the end of this message.  

I will paraphrase the NEW SCIENTIST article to explain my code in more
detail:

My sample verilog code uses a standard genetic algorithm to evolve a
configuration program for a PAL and then tests each new circuit design
immediately in the PAL, in the verilog simulator.  

My method, which involves a pure digital solution of digital resources,
will not suffer from temperature instabilities because I'm only allowing
the logic to evolve digital solutions, not analog ones.  

To start the simulation, I create a population of 256 configuration programs
("genes" --PAL fuse maps) in the verilog simulator, each consisting of a
random string of 1s and 0s. The simulator "downloads" each fuse map in turn
into 256 copies of a PAL.  Each PAL has different genes (fuse map).  The PAL
genes define that PAL's circuit.  Then the PAL tester code tests that
circuit against a goal.  The goal in the case of my sample code is to add
two nibbles.  The genetic algorithm tests the fitness of each PAL by checking
how well it achieves the goal.  It looks for some characteristic that might
prove useful in evolving a solution.  (Can it get the most significant bit
right?)  At first, this is just an indication that the circuit's output is
not completely random. 

After testing the initial population, the genetic algorithm kills off the
least fit individuals by deleting them and lets the most fit produce copies
of themselves--offspring.  It mates some individuals (my program mates the
best two), swapping sections of their code/genes/fuse map.  Finally, the
algorithm introduces a small number of mutations by randomly switching 1s 
and 0s within individual programs/genes/fuse maps.  The deleted PAL
individuals are replaced by individuals who are offspring of the most fit.
The fitness test is run again.  By generation 418, the fittest individual
produced outputs within two bits of the right answer.  
     
My sample program is evolving only a combinatorial logic PAL.  The code can
be changed to have flip-flops for state and feedback.  You can increase the
size of the PAL array.  My code for MACHs models all the fuses in the MACH
so it can have loops and feedback, however the fuse map/genes is obviously
much larger.  This method can be applied to any FPGA.

  - Kurt Baty


 [ Editor's Note: Bellow is Kurt's *original* e-mail from 18 months ago.
   Ask yourself: "If I had NOT read all the preceeding letters in this
   ESNUG, could I have figured out what Kurt was saying?"  :^)  - John ]


From kurt Fri Jun 28 17:34:02 1996
Date: Fri, 28 Jun 96 17:34:01 EDT
To: jcooley@world.std.com
Subject: alife code

alife code aka steven levy's book

Breed up you own adder's

Warning this "little" code can take 40Megs.

       408 in  7 +  4
       408 one was  17 at age          2 av_diff          3
       408 two was   0 at age         22 av_diff          4
       408 last was  76 at age        38 av_diff         16
       418 in 11 + 10
       418 one was   0 at age         23 av_diff          4
       418 two was  14 at age          6 av_diff          4
       418 last was  26 at age        39 av_diff         18
 
emergent technology!

  - Kurt Baty


-----------------------
X-Sun-Data-Name: pal_top.vc
X-Sun-Content-Lines: 4

pal_top.v
	pal_tester.v
		pal.v

-----------------------
X-Sun-Data-Name: pal_top.v
X-Sun-Content-Lines: 360

module pal_top;

reg          clk,pwr_up_resetL;
wire         resetL,delayed_resetL;

integer      i,j;

reg	[7:0]    in;

reg	[31:0]   temp;

reg [1023:0] genes[255:0];
reg	[31:0]   age[255:0];
reg	[31:0]   total_diff[255:0];

reg	[7:0]    one,two,last;
reg [1023:0] temp_gene1,temp_gene2,temp_gene3;

reg          bit;
reg	[9:0]    desplacement,mutation;

initial
begin
	clk = 1'b0;
	pwr_up_resetL = 1'b0;
	in = $random;
	for (i=0;i<256;i=i+1)
		for (j=0;j<33;j=j+1) begin
			temp = $random;
			genes[i] = {genes[i],temp};
		end
//	$readmemh("genes.dat",genes);
	for (i=0;i<256;i=i+1) begin
		age[i] = 0;
		total_diff[i] = 0;
	end
	#32
	pwr_up_resetL = 1'b1;
	#30000
//	$stop;
	$finish;
end

always
	clk = #5 ~clk;

assign	resetL = pwr_up_resetL;

always @ (posedge clk)
	if(resetL) begin
		#3
		{one,two,last} = 24'h000100;
		// look for the top two pals and the last one
		for (i=1;i<256;i=i+1)begin
			if((total_diff[i]/age[i]) < (total_diff[one]/age[one])) begin
				two = one;
				one = i;
			end
			else if((total_diff[i]/age[i]) < (total_diff[two]/age[two]))
				two = i;
			if((total_diff[i]/age[i]) > (total_diff[last]/age[last]))
				last = i;
		end
		// do some reproduction
		begin
			bit = $random;
			desplacement = $random;
			mutation = $random;
			if(bit) begin
				temp_gene1 = genes[one];
				temp_gene2 = genes[two];
			end
			else begin
				temp_gene1 = genes[two];
				temp_gene2 = genes[one];
			end
			for (j=0;j<1024;j=j+1) begin
				if(j < desplacement)
					temp_gene3[j] = temp_gene1[j];
				else
					temp_gene3[j] = temp_gene2[j];
			end	
			if(mutation < 1024)
				temp_gene3[mutation] = !temp_gene3[mutation];
		end
		// do some reporting
		$display($time,,"in %d + %d",in[7:4],in[3:0]);
		$display($time,,"one was %d at age %d av_diff %d",
				one,age[one],total_diff[one]/age[one]);
		$display($time,,"two was %d at age %d av_diff %d",
				two,age[two],total_diff[two]/age[two]);
		$display($time,,"last was %d at age %d av_diff %d",
				last,age[last],total_diff[last]/age[last]);
		// clear up last's stats
		genes[last] = temp_gene3;
		age[last] = 0;
		total_diff[last] = 0;
		in = $random;
	end

pal_tester h00(clk,resetL,8'h00,in);
pal_tester h01(clk,resetL,8'h01,in);
pal_tester h02(clk,resetL,8'h02,in);
pal_tester h03(clk,resetL,8'h03,in);
pal_tester h04(clk,resetL,8'h04,in);
pal_tester h05(clk,resetL,8'h05,in);
pal_tester h06(clk,resetL,8'h06,in);
pal_tester h07(clk,resetL,8'h07,in);
pal_tester h08(clk,resetL,8'h08,in);
pal_tester h09(clk,resetL,8'h09,in);
pal_tester h0a(clk,resetL,8'h0a,in);
pal_tester h0b(clk,resetL,8'h0b,in);
pal_tester h0c(clk,resetL,8'h0c,in);
pal_tester h0d(clk,resetL,8'h0d,in);
pal_tester h0e(clk,resetL,8'h0e,in);
pal_tester h0f(clk,resetL,8'h0f,in);
pal_tester h10(clk,resetL,8'h10,in);
pal_tester h11(clk,resetL,8'h11,in);
pal_tester h12(clk,resetL,8'h12,in);
pal_tester h13(clk,resetL,8'h13,in);
pal_tester h14(clk,resetL,8'h14,in);
pal_tester h15(clk,resetL,8'h15,in);
pal_tester h16(clk,resetL,8'h16,in);
pal_tester h17(clk,resetL,8'h17,in);
pal_tester h18(clk,resetL,8'h18,in);
pal_tester h19(clk,resetL,8'h19,in);
pal_tester h1a(clk,resetL,8'h1a,in);
pal_tester h1b(clk,resetL,8'h1b,in);
pal_tester h1c(clk,resetL,8'h1c,in);
pal_tester h1d(clk,resetL,8'h1d,in);
pal_tester h1e(clk,resetL,8'h1e,in);
pal_tester h1f(clk,resetL,8'h1f,in);
pal_tester h20(clk,resetL,8'h20,in);
pal_tester h21(clk,resetL,8'h21,in);
pal_tester h22(clk,resetL,8'h22,in);
pal_tester h23(clk,resetL,8'h23,in);
pal_tester h24(clk,resetL,8'h24,in);
pal_tester h25(clk,resetL,8'h25,in);
pal_tester h26(clk,resetL,8'h26,in);
pal_tester h27(clk,resetL,8'h27,in);
pal_tester h28(clk,resetL,8'h28,in);
pal_tester h29(clk,resetL,8'h29,in);
pal_tester h2a(clk,resetL,8'h2a,in);
pal_tester h2b(clk,resetL,8'h2b,in);
pal_tester h2c(clk,resetL,8'h2c,in);
pal_tester h2d(clk,resetL,8'h2d,in);
pal_tester h2e(clk,resetL,8'h2e,in);
pal_tester h2f(clk,resetL,8'h2f,in);
pal_tester h30(clk,resetL,8'h30,in);
pal_tester h31(clk,resetL,8'h31,in);
pal_tester h32(clk,resetL,8'h32,in);
pal_tester h33(clk,resetL,8'h33,in);
pal_tester h34(clk,resetL,8'h34,in);
pal_tester h35(clk,resetL,8'h35,in);
pal_tester h36(clk,resetL,8'h36,in);
pal_tester h37(clk,resetL,8'h37,in);
pal_tester h38(clk,resetL,8'h38,in);
pal_tester h39(clk,resetL,8'h39,in);
pal_tester h3a(clk,resetL,8'h3a,in);
pal_tester h3b(clk,resetL,8'h3b,in);
pal_tester h3c(clk,resetL,8'h3c,in);
pal_tester h3d(clk,resetL,8'h3d,in);
pal_tester h3e(clk,resetL,8'h3e,in);
pal_tester h3f(clk,resetL,8'h3f,in);
pal_tester h40(clk,resetL,8'h40,in);
pal_tester h41(clk,resetL,8'h41,in);
pal_tester h42(clk,resetL,8'h42,in);
pal_tester h43(clk,resetL,8'h43,in);
pal_tester h44(clk,resetL,8'h44,in);
pal_tester h45(clk,resetL,8'h45,in);
pal_tester h46(clk,resetL,8'h46,in);
pal_tester h47(clk,resetL,8'h47,in);
pal_tester h48(clk,resetL,8'h48,in);
pal_tester h49(clk,resetL,8'h49,in);
pal_tester h4a(clk,resetL,8'h4a,in);
pal_tester h4b(clk,resetL,8'h4b,in);
pal_tester h4c(clk,resetL,8'h4c,in);
pal_tester h4d(clk,resetL,8'h4d,in);
pal_tester h4e(clk,resetL,8'h4e,in);
pal_tester h4f(clk,resetL,8'h4f,in);
pal_tester h50(clk,resetL,8'h50,in);
pal_tester h51(clk,resetL,8'h51,in);
pal_tester h52(clk,resetL,8'h52,in);
pal_tester h53(clk,resetL,8'h53,in);
pal_tester h54(clk,resetL,8'h54,in);
pal_tester h55(clk,resetL,8'h55,in);
pal_tester h56(clk,resetL,8'h56,in);
pal_tester h57(clk,resetL,8'h57,in);
pal_tester h58(clk,resetL,8'h58,in);
pal_tester h59(clk,resetL,8'h59,in);
pal_tester h5a(clk,resetL,8'h5a,in);
pal_tester h5b(clk,resetL,8'h5b,in);
pal_tester h5c(clk,resetL,8'h5c,in);
pal_tester h5d(clk,resetL,8'h5d,in);
pal_tester h5e(clk,resetL,8'h5e,in);
pal_tester h5f(clk,resetL,8'h5f,in);
pal_tester h60(clk,resetL,8'h60,in);
pal_tester h61(clk,resetL,8'h61,in);
pal_tester h62(clk,resetL,8'h62,in);
pal_tester h63(clk,resetL,8'h63,in);
pal_tester h64(clk,resetL,8'h64,in);
pal_tester h65(clk,resetL,8'h65,in);
pal_tester h66(clk,resetL,8'h66,in);
pal_tester h67(clk,resetL,8'h67,in);
pal_tester h68(clk,resetL,8'h68,in);
pal_tester h69(clk,resetL,8'h69,in);
pal_tester h6a(clk,resetL,8'h6a,in);
pal_tester h6b(clk,resetL,8'h6b,in);
pal_tester h6c(clk,resetL,8'h6c,in);
pal_tester h6d(clk,resetL,8'h6d,in);
pal_tester h6e(clk,resetL,8'h6e,in);
pal_tester h6f(clk,resetL,8'h6f,in);
pal_tester h70(clk,resetL,8'h70,in);
pal_tester h71(clk,resetL,8'h71,in);
pal_tester h72(clk,resetL,8'h72,in);
pal_tester h73(clk,resetL,8'h73,in);
pal_tester h74(clk,resetL,8'h74,in);
pal_tester h75(clk,resetL,8'h75,in);
pal_tester h76(clk,resetL,8'h76,in);
pal_tester h77(clk,resetL,8'h77,in);
pal_tester h78(clk,resetL,8'h78,in);
pal_tester h79(clk,resetL,8'h79,in);
pal_tester h7a(clk,resetL,8'h7a,in);
pal_tester h7b(clk,resetL,8'h7b,in);
pal_tester h7c(clk,resetL,8'h7c,in);
pal_tester h7d(clk,resetL,8'h7d,in);
pal_tester h7e(clk,resetL,8'h7e,in);
pal_tester h7f(clk,resetL,8'h7f,in);
pal_tester h80(clk,resetL,8'h80,in);
pal_tester h81(clk,resetL,8'h81,in);
pal_tester h82(clk,resetL,8'h82,in);
pal_tester h83(clk,resetL,8'h83,in);
pal_tester h84(clk,resetL,8'h84,in);
pal_tester h85(clk,resetL,8'h85,in);
pal_tester h86(clk,resetL,8'h86,in);
pal_tester h87(clk,resetL,8'h87,in);
pal_tester h88(clk,resetL,8'h88,in);
pal_tester h89(clk,resetL,8'h89,in);
pal_tester h8a(clk,resetL,8'h8a,in);
pal_tester h8b(clk,resetL,8'h8b,in);
pal_tester h8c(clk,resetL,8'h8c,in);
pal_tester h8d(clk,resetL,8'h8d,in);
pal_tester h8e(clk,resetL,8'h8e,in);
pal_tester h8f(clk,resetL,8'h8f,in);
pal_tester h90(clk,resetL,8'h90,in);
pal_tester h91(clk,resetL,8'h91,in);
pal_tester h92(clk,resetL,8'h92,in);
pal_tester h93(clk,resetL,8'h93,in);
pal_tester h94(clk,resetL,8'h94,in);
pal_tester h95(clk,resetL,8'h95,in);
pal_tester h96(clk,resetL,8'h96,in);
pal_tester h97(clk,resetL,8'h97,in);
pal_tester h98(clk,resetL,8'h98,in);
pal_tester h99(clk,resetL,8'h99,in);
pal_tester h9a(clk,resetL,8'h9a,in);
pal_tester h9b(clk,resetL,8'h9b,in);
pal_tester h9c(clk,resetL,8'h9c,in);
pal_tester h9d(clk,resetL,8'h9d,in);
pal_tester h9e(clk,resetL,8'h9e,in);
pal_tester h9f(clk,resetL,8'h9f,in);
pal_tester ha0(clk,resetL,8'ha0,in);
pal_tester ha1(clk,resetL,8'ha1,in);
pal_tester ha2(clk,resetL,8'ha2,in);
pal_tester ha3(clk,resetL,8'ha3,in);
pal_tester ha4(clk,resetL,8'ha4,in);
pal_tester ha5(clk,resetL,8'ha5,in);
pal_tester ha6(clk,resetL,8'ha6,in);
pal_tester ha7(clk,resetL,8'ha7,in);
pal_tester ha8(clk,resetL,8'ha8,in);
pal_tester ha9(clk,resetL,8'ha9,in);
pal_tester haa(clk,resetL,8'haa,in);
pal_tester hab(clk,resetL,8'hab,in);
pal_tester hac(clk,resetL,8'hac,in);
pal_tester had(clk,resetL,8'had,in);
pal_tester hae(clk,resetL,8'hae,in);
pal_tester haf(clk,resetL,8'haf,in);
pal_tester hb0(clk,resetL,8'hb0,in);
pal_tester hb1(clk,resetL,8'hb1,in);
pal_tester hb2(clk,resetL,8'hb2,in);
pal_tester hb3(clk,resetL,8'hb3,in);
pal_tester hb4(clk,resetL,8'hb4,in);
pal_tester hb5(clk,resetL,8'hb5,in);
pal_tester hb6(clk,resetL,8'hb6,in);
pal_tester hb7(clk,resetL,8'hb7,in);
pal_tester hb8(clk,resetL,8'hb8,in);
pal_tester hb9(clk,resetL,8'hb9,in);
pal_tester hba(clk,resetL,8'hba,in);
pal_tester hbb(clk,resetL,8'hbb,in);
pal_tester hbc(clk,resetL,8'hbc,in);
pal_tester hbd(clk,resetL,8'hbd,in);
pal_tester hbe(clk,resetL,8'hbe,in);
pal_tester hbf(clk,resetL,8'hbf,in);
pal_tester hc0(clk,resetL,8'hc0,in);
pal_tester hc1(clk,resetL,8'hc1,in);
pal_tester hc2(clk,resetL,8'hc2,in);
pal_tester hc3(clk,resetL,8'hc3,in);
pal_tester hc4(clk,resetL,8'hc4,in);
pal_tester hc5(clk,resetL,8'hc5,in);
pal_tester hc6(clk,resetL,8'hc6,in);
pal_tester hc7(clk,resetL,8'hc7,in);
pal_tester hc8(clk,resetL,8'hc8,in);
pal_tester hc9(clk,resetL,8'hc9,in);
pal_tester hca(clk,resetL,8'hca,in);
pal_tester hcb(clk,resetL,8'hcb,in);
pal_tester hcc(clk,resetL,8'hcc,in);
pal_tester hcd(clk,resetL,8'hcd,in);
pal_tester hce(clk,resetL,8'hce,in);
pal_tester hcf(clk,resetL,8'hcf,in);
pal_tester hd0(clk,resetL,8'hd0,in);
pal_tester hd1(clk,resetL,8'hd1,in);
pal_tester hd2(clk,resetL,8'hd2,in);
pal_tester hd3(clk,resetL,8'hd3,in);
pal_tester hd4(clk,resetL,8'hd4,in);
pal_tester hd5(clk,resetL,8'hd5,in);
pal_tester hd6(clk,resetL,8'hd6,in);
pal_tester hd7(clk,resetL,8'hd7,in);
pal_tester hd8(clk,resetL,8'hd8,in);
pal_tester hd9(clk,resetL,8'hd9,in);
pal_tester hda(clk,resetL,8'hda,in);
pal_tester hdb(clk,resetL,8'hdb,in);
pal_tester hdc(clk,resetL,8'hdc,in);
pal_tester hdd(clk,resetL,8'hdd,in);
pal_tester hde(clk,resetL,8'hde,in);
pal_tester hdf(clk,resetL,8'hdf,in);
pal_tester he0(clk,resetL,8'he0,in);
pal_tester he1(clk,resetL,8'he1,in);
pal_tester he2(clk,resetL,8'he2,in);
pal_tester he3(clk,resetL,8'he3,in);
pal_tester he4(clk,resetL,8'he4,in);
pal_tester he5(clk,resetL,8'he5,in);
pal_tester he6(clk,resetL,8'he6,in);
pal_tester he7(clk,resetL,8'he7,in);
pal_tester he8(clk,resetL,8'he8,in);
pal_tester he9(clk,resetL,8'he9,in);
pal_tester hea(clk,resetL,8'hea,in);
pal_tester heb(clk,resetL,8'heb,in);
pal_tester hec(clk,resetL,8'hec,in);
pal_tester hed(clk,resetL,8'hed,in);
pal_tester hee(clk,resetL,8'hee,in);
pal_tester hef(clk,resetL,8'hef,in);
pal_tester hf0(clk,resetL,8'hf0,in);
pal_tester hf1(clk,resetL,8'hf1,in);
pal_tester hf2(clk,resetL,8'hf2,in);
pal_tester hf3(clk,resetL,8'hf3,in);
pal_tester hf4(clk,resetL,8'hf4,in);
pal_tester hf5(clk,resetL,8'hf5,in);
pal_tester hf6(clk,resetL,8'hf6,in);
pal_tester hf7(clk,resetL,8'hf7,in);
pal_tester hf8(clk,resetL,8'hf8,in);
pal_tester hf9(clk,resetL,8'hf9,in);
pal_tester hfa(clk,resetL,8'hfa,in);
pal_tester hfb(clk,resetL,8'hfb,in);
pal_tester hfc(clk,resetL,8'hfc,in);
pal_tester hfd(clk,resetL,8'hfd,in);
pal_tester hfe(clk,resetL,8'hfe,in);
pal_tester hff(clk,resetL,8'hff,in);

endmodule

-----------------------
X-Sun-Data-Name: pal_tester.v
X-Sun-Content-Lines: 23

module pal_tester(clk,resetL,gene_ptr,in);
input       clk,resetL;
input [7:0] gene_ptr;
input [7:0] in;

wire  [7:0] out;
wire  [7:0] sum;
wire  [7:0] diff;

pal pal(clk,gene_ptr,in,out);

assign	sum = in[7:4] + in[3:0];	
assign	diff = (out > sum)? out - sum : sum - out;

always @ (posedge clk)
	if(resetL) begin
		#2
		pal_top.age[gene_ptr] = pal_top.age[gene_ptr] + 1'b1;
		pal_top.total_diff[gene_ptr] = pal_top.total_diff[gene_ptr] + diff;
	end

endmodule

-----------------------
-
Sun-Data-Name: pal.v
X-Sun-Content-Lines: 55

module pal(clk,gene_ptr,in,out);
input  clk;
input  [7:0] gene_ptr;
input  [7:0] in;
output [7:0] out;

wire [1023:0]  my_genes;
reg  [7:0]     out;


function [15:0]	make_C;

input [1023:0] my_genes;
input [15:0]   ins;

reg      temp1,temp2;
integer	 i,j,k,l;

reg [7:0]  temp3;
reg [15:0] layer;

begin
    for (i=0;i<8;i=i+1) begin
	temp1 = 1'b0;
	for (j=0;j<4;j=j+1) begin
		temp2 = 1'b1;
		for (k=0;k<16;k=k+1) begin
			l = 64*i + 16*j + k;
			temp2 = temp2 & (ins[k] | my_genes[l]);
		end
		temp1 = temp1 | temp2;
	end
	temp3[i] = temp1;
    end
    layer = {temp3,~temp3};
    for (i=0;i<8;i=i+1) begin
	temp1 = 1'b0;
	for (j=0;j<4;j=j+1) begin
		temp2 = 1'b1;
		for (k=0;k<16;k=k+1) begin
			l = 512 + 64*i + 16*j + k;
			temp2 = temp2 & (layer[k] | my_genes[l]);
		end
		temp1 = temp1 | temp2;
	end
	make_C[i] = temp1;
   end
end
endfunction

assign	my_genes = pal_top.genes[gene_ptr];

always @ (negedge clk)
	out = make_C(my_genes,{in,~in});

endmodule


 Sign up for the DeepChip newsletter.
Email
 Read what EDA tool users really think.


Feedback About Wiretaps ESNUGs SIGN UP! Downloads Trip Reports Advertise

"Relax. This is a discussion. Anything said here is just one engineer's opinion. Email in your dissenting letter and it'll be published, too."
This Web Site Is Modified Every 2-3 Days
Copyright 1991-2024 John Cooley.  All Rights Reserved.
| Contact John Cooley | Webmaster | Legal | Feedback Form |

   !!!     "It's not a BUG,
  /o o\  /  it's a FEATURE!"
 (  >  )
  \ - / 
  _] [_     (jcooley 1991)