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
**************************************************************************************