PETRICK FUNCTION MACHINE.


From           Travis A. Bonifield


**************************************************************************************


The following is the sum of what I have accomplished while trying to
implement the Petrick function.  Granted there is little that actually fits 
together because I spent the majority of my time working on this homework
trying to learn the basics of VHDL and Mentor Tools.  For lack of a better
visual tool, my state machine is described as thus:

A0. Start
A1. Load covering table to register array
A2. Find prime implicant
P1. Implicant found? (yes => A3, no => P2)
P2. Done with prime implicants? (yes => A4, no => A2)
A3. Write zeros to implicant column.
P3. Done with prime implicants? (yes => A4, no => A2)
A4. Find dominant row.
P4. Dominant row found? (yes => A5, no => P5)
P5. Done with Dominant rows? (yes => P7, no => A4)
A5. Write zeros to dominated rows found.
P6. Done with Dominant rows? (yes => P7, no => A4)
P7. Solution?  (i.e. table all zeros) (yes => A6, no => A2)
A6. Stop. 


To realize this machine I first designed a 3 to 8 decoder for memory
addressing which is shown below in VHDL code.

LIBRARY mgc_portable;
USE mgc_portable.qsim_logic.ALL;

ENTITY decode3_8 IS
	PORT(a: IN qsim_state_vector(0 to 2);
		  q: OUT qsim_state_vector(0 to 7);
		  ck: IN qsim_state);
END decode3_8;

ARCHITECTURE behav OF decode3_8 IS
BEGIN
 decode: PROCESS
	BEGIN
	WAIT UNTIL (ck'EVENT AND ck='0');
		q(0) <= a(2) or a(1) or a(0);
		q(1) <= a(2) or a(1) or not(a(0));
		q(2) <= a(2) or not(a(1)) or a(0);
		q(3) <= a(2) or not(a(1)) or not(a(0));
		q(4) <= not(a(2)) or a(1) or a(0);
		q(5) <= not(a(2)) or a(1) or not(a(0));
		q(6) <= not(a(2)) or not(a(1)) or a(0);
		q(7) <= not(a(2)) or not(a(1)) or not(a(0));
END PROCESS decode; 
END behav;


******************************
After the 3 to 8 decoder, I designed a 3 - bit counter to count the 
number of ones shown below in VHDL code.


LIBRARY mgc_portable;
USE mgc_portable.qsim_logic.ALL;

ENTITY three_bit_ctr IS
PORT(enable, clock, reset: IN qsim_state;
	  a0,a1,a2: OUT qsim_state);
END three_bit_ctr;

ARCHITECTURE behav OF three_bit_ctr IS
	TYPE state_type IS (s0,s1,s2,s3,s4,s5,s6,s7);
	SIGNAL current_state, next_state:state_type;
BEGIN

synch:PROCESS
BEGIN
	WAIT UNTIL clock'EVENT AND clock='1';
	current_state <= next_state;
END PROCESS;

count:PROCESS(current_state,enable,reset)
BEGIN
	IF (reset='0') THEN
		current_state <= s0;
		a0 <= '0';
		a1 <= '0';
		a2 <= '0';
		next_state <= s1;
	ELSIF (enable='0') THEN
		CASE current_state IS
			WHEN s0 =>
				a0 <= '0';
				a1 <= '0';
				a2 <= '0';
				next_state <= s1;
			WHEN s1 =>
				a0 <= '1';
				a1 <= '0';
				a2 <= '0';
				next_state <= s2;
			WHEN s2 =>
				a0 <= '0';
				a1 <= '1';
				a2 <= '0';
				next_state <= s3;
			WHEN s3 =>
				a0 <= '1';
				a1 <= '1';
				a2 <= '0';
				next_state <= s4;
			WHEN s4 =>
				a0 <= '0';
				a1 <= '0';
				a2 <= '1';
				next_state <= s5;
			WHEN s5 =>
				a0 <= '1';
				a1 <= '0';
				a2 <= '1';
				next_state <= s6;
			WHEN s6 =>
				a0 <= '0';
				a1 <= '1';
				a2 <= '1'; next_state <= s7;
			WHEN s7 =>
				a0 <= '1';
				a1 <= '1';
				a2 <= '1';
				next_state <= s0;
			END CASE;
		END IF;
	END PROCESS;
END behav;


*******************************************
The following is my attempt to design a memory register array.  Each memory
latch is enabled by three lines, a row - enable, a column - enable, and a
read/write_not signal.  In this way, each latch would be addressed only one
at a time and read or written to.  Following the initial description of
a single latch, I attempted to describe a row of latches and then a full
block of latches.  My attempt failed becuase I could not get the Mentor
Tools compiler to recognize a 'generate' statement and I became truly 
stuck on this matter.

library mgc_portable;
use mgc_portable.qsim_logic.ALL;

ENTITY ramem IS
	PORT(r_wn, din, e_row, e_col: IN qsim_state;
	     mem: BUFFER qsim_state;
		  dout: OUT qsim_state;
		  clock: IN qsim_state);
END ramem;

ARCHITECTURE behav OF ramem IS
BEGIN
 	PROCESS BEGIN
		WAIT UNTIL clock'EVENT AND clock='1';
			IF ((e_row='0') AND (e_col='0')) THEN
				IF (r_wn='0') THEN
					mem <= din;
				ELSE
					dout <= mem;
				END IF;
			END IF;
	END PROCESS;
END behav;

library mgc_portable;
use mgc_portable.qsim_logic.ALL;

ENTITY memrow IS
		PORT(enable_row:in qsim_state;
			  enable_column:in qsim_state (0 to 7);
			  data_in,ck,read_writenot:in qsim_state;
			  data_out:out qsim_state);
END memrow;

ARCHITECTURE mem1 OF memrow IS
	COMPONENT ramem 
		PORT(r_wn, din, e_row, e_col: IN qsim_state;
			  dout: OUT qsim_state;
			  clock: IN qsim_state);
	END COMPONENT;
	
	BEGIN
		
		gen1: FOR i IN 0 to 7 GENERATE
			U: ramem PORT MAP(read_writenot,data_in,enable_row,enable_column(i),data_out,ck);
		END GENERATE;
END mem1;
		

LIBRARY mgc_portable;
USE mgc_portable.qsim_logic.ALL;

ENTITY memblock IS
	PORT(input,clock,rd_wn: IN qsim_state;
		  row_en1: IN qsim_state_vector(0 to 7);
		  row_en2: IN qsim_state_vector(0 to 7);
		  row_en3: IN qsim_state_vector(0 to 7);
		  row_en4: IN qsim_state_vector(0 to 7);
		  col_en: IN qsim_state_vector(0 to 7);
		  output: OUT qsim_state);
END memblock;

ARCHITECTURE memblockstruct OF memblock IS
	COMPONENT ramem PORT(d_in,ck,e_row,e_col,r_wn: IN qsim_state;
								d_out: OUT qsim_state);
	END COMPONENT;

	BEGIN
		struct1: FOR i IN 0 TO 7 GENERATE
		U1: ramem PORT MAP(input,clock,row_en1(i),col_en(i),rd_wn,output);
		U2: ramem PORT MAP(input,clock,row_en2(i),col_en(i),rd_wn,output);
		U3: ramem PORT MAP(input,clock,row_en3(i),col_en(i),rd_wn,output);
		U4: ramem PORT MAP(input,clock,row_en4(i),col_en(i),rd_wn,output);
		END; 

;END memblockstruct;

*******************************************
The following is the beginning of a controller I started to design.  Although
not completed, the genral idea is evident, I think.  The controller is to
send an enable signal to the data path and upon recieving a signal back that
such and such an operation is completed, the controller decides which operation
to perform next and pulls a given line low, enabling the next process.

LIBRARY mgc_portable;
USE mgc_portable.qsim.ALL;

ENTITY controller IS
	PORT(p0,p1,p2,p3,p4,p5,p6,p7:IN qsim_state;
		  clock: IN qsim_state;
		  a1,a2,a3,a4,a5,a6: OUT qsim_state);
END controller;

ARCHITECTURE control OF controller IS
	TYPE state_type IS(s0,s1,s2,s3,s4,s5,s6);
	SIGNAL current_state,next_state: state_type;
BEGIN
	PROCESS(clock);
	BEGIN
		WAIT UNTIL clock'EVENT AND clock='1';
		current_state <= next_state;
CASE current_state IS
	WHEN s0 =>
		next_state <= s1;
		IF p0 ='1' THEN
			next_state <= s0;
		END IF;

	WHEN s1 =>
		a1 <= '0';
		IF p1 = '0' THEN
			next_state <= s2;
			a1 <= '1';
		END IF;

	WHEN s2 =>
		a2 <= '0';
		IF p1 = '0' THEN
			next_state <= s3;
			a2 <= '1';
		ELSIF p2 = '0' THEN
			next_state <= s4;
			a2 <= '1';
		END IF;

	WHEN s3 =>
		a3 <= '0';
		IF p3 = '0' THEN		
			
		
	
*******************************
Although very late and very incomplete, this is all that I have as
I am very new to this type of programming language and also quite new
to digital design concepts.  I do verily beg your pardon for sending this
assignment to you so late and so incomplete  and will attempt to do a 
much better job in the future. 

I have now, I think, learned well how to use the Mentor Tools for writing
VHDL code and compiling it and also have spent a considerable amount of 
time learning to simulate different components.  Having done this I am certain
I will be better equipped to use these tools in the future.
 
Thank you.

Travis Bonifield	
		
		

**************************************************************************************