CPE 315
Professor Stearns
Winter 2008
SIM library signatures (with some examples)
Use the example makefile to build the examples.

/* 
SIM Written by Dr. Reed's Michigan State students

Modifications:
  11/08/04 -  dan improved Rom specification

/
    
void Adder (const SD&, const Signals& in, const Signal& out);
// requires:  in.length/2 == out.length
//                 in.length mod 2 == 0
// postcondition:
//    out = in + in
// out =  first in.length/2 signals + remaining in.length/2 signals
// no overflow nor carry generated

void And (const SD& sd, const Signals& in, const Signals& out);
// single And for a single out.
// A vector of And gates if out is a vector, then in.length = N * out.length
// and each And has N inputs.

void And (const SD& sd,
	  const Signals& in1, const Signals& in2,
	  const Signals& out );
// A vector of out.length And's:
// if in1 & in2 are the same length: each And has two inputs, one from
//        in1 and one from in2.
// in1.length>1 && in2.length==1: the single in2 is an input for
//        each of the Ands.
// in1.length==1 && in2.length>1: the single in1 is an input for
//        each of the Ands.

void CiOr (const SD &, const Signals & trueSignals,
		const Signals & complemented, const Signal & out);
// Complemented-input Or

void CiNor ( const SD &, const Signals & trueSignals,
		const Signals & complemented, const Signal & out);
// Complemented-input Nor

void Clock (const SD &, const Signal &, const int duration,
	    const int offset, const int period,
	    const Signal & init = Zero );
// duration is ON time, offset is displacement of first ON from t=0,
// period is the time until the next repetition.
// init is the initial output--ON is taken to be the complement of this value.

void Counter ( const SD &, const Signals & in, const Signals & out );


void Decoder ( const SD &, const Signals & enable, const Signals & data,
           const Signals & out );
// N data-in lines are decoded to 2^N out lines
// single active-high enable 
Decoder Example

void Dff (const SD& sd, const Signals& in, const Signals& out );
// D flip-flop
// in: (set,Din,clock,reset)
// out: Q

void Encoder (const SD& sd, const Signals& in,
              const Signals& out, const Signal& valid );
// 2^N data-in lines are examined for a One
// the most significant position where there is a One is
// encoded as the out value.
// valid == One iff one output == One

void Iand (const SD& sd, const Signals& trueSignals,
           const Signals& invertedSignals, const Signal& out);
// And gate that can invert some or all of its inputs
// Parameters:
//     trueSignals     - intput signals that will not be inverted
//     invertedSignals - input signals that will be inverted 
//     out             - output of the AND gate
8 bit adder (8bitAdd.c uses the Iand gate)


void Inand (const SD& sd, const Signals& trueSignals,
            const Signals& invertedSignals, const Signal& out);
// Identical to Iand gate except out is inverted.

void loadRom (unsigned char* romContents, int size,
	      char * filename = "romfile" );
// fill the unsigned char array, up to "size" bytes with
// hex bytes from "romfile"
// "romfile" is a series of hex bytes: 0xA0 0x9C 0x34 0xAB
//           with 4 bytes/line regardless of ROM width
// whitespace is immaterial, but comma separators are NOT allowed.

void MultiLevelCompare ( const SD &, const Signals &, const Signal & );
// Compares two inputs for equality, over ALL the
// Signal values: ZERO, UNINITIALIZED, XXX, HIZ, ONE
// Output is ONE for equal, ZERO otherwise.

void Mux (const SD& sd, const Signals& select, const Signals& data,
          const Signals& out );
// out.length defines the width of the input ports and the output port.
// data.length/out.length => numberOfPorts
// select is the port selection
// select.length must == log2(numberOfPorts)
// data[port,bit]order: [P-1,n-1],[P-1,n-2],...[P-1,0],...[0,1],[0,0]
//                       top Port                         bottom Port
Mux Example


void Nand ( const SD &, const Signals & in, const Signal & out );

void Nor ( const SD &, const Signals & in, const Signal & out );

void Not ( const SD & sd, const Signals & in, const Signals & out );
// Single inverter or vector of inverters if out.length > 1.

void Or ( const SD & sd, const Signals & in, const Signals & out );
// single Or for a single out.
// A vector of Or's if out is a vector, then in.length = N * out.length
//  and each Or has N inputs.

void Or (const SD & sd,
	  const Signals & in1, const Signals & in2,
	  const Signals & out );
// A vector of out.length Or's:
// if in1 & in2 are the same length: each Or has two inputs, one from
//        in1 and one from in2.
// in1.length>1 && in2.length==1:the single in2 is an input for
//        each of the Ors.
// in1.length==1 && in2.length>1:the single in1 is an input for
//        each of the Ors.
OR Examples


void Probe (const SD&, const Signals& sig, const int numberOfPartitions = 0,
	    const int* partitionSize = 0 );
// if sig is a bus, construct sig.length probes
// Places a space after each partition to ease the reading of field separations.
// Last partition size repeated, if necessary.
// ZERO->backGroundColor
// ONE->foreGroundColor
// UNINITIALIZED->Slash displayed
// HIZ-> Horizontal Line displayed
// XXX->crossed lines displayed  -- signal in transition
// Set profRunTimeFlag[15] == 0 to suppress run-time Probe output.

void ProbeH ( const SD &, const Signals & );
// Display arranged horizontally--uses Probe, so labeling is compounded.

void Pulser ( const SD &, const Signal &, const char, const int duration,
	       const Signal & init = Zero ); 
// generate one clock pulse
// char is keyboard association, duration is the pulse length. 
// init is the initial output--ON is taken to be the complement of this value.

void Ram (const SD& sd,
     //  This is a word-addressable Ram; the address busses access
     //    a word regardless of wordsize
     //  Note:  requires violations cause a run-time length error message

     const Signals& controlIn,
     // control signals must be ordered as follows
     //   enable    -  allows Ram write
     //   clock     -  loads dataIn into mem[waddress] on leading edge
     //   waddress  -  write address bus
     //   raddress  -  read address bus - same as waddress in Fig. 5-19 

     const Signals& dataIn
     //   input data bus
     //   requires:  dataIn.length == wordSize

     const Signals& out
     //   output data bus
     //   requires:  out.length == wordSize

     const int numWords,
     //   size of Ram in units of wordSize
     //   requires:
     //       waddress.length == raddress.length == log2(numWords)
     //   warning:  this is unrealistic but must be met
     //              it should be address.length == log2(address space)

     const int wordSize,
     //   word size in bits

     const int addressBusSize,
     //   requires:  addressBusSize == log2(numWords)

     const int numberOfReadPorts,
     //   1 for mips Ram

     const int numberOfWritePorts
     //   1 for mips Ram
     );

Ram Example needs clockUnit.h and clockUnit.c

void Register ( const SD& sd, const Signals& enable, const Signal& clock, const Signals& dataIn, const Signals& out); // dataIn is loaded on the leading edge of the clock signal but // only if enable == One at that time. // out is always available regardless of clock. // requires: dataIn.length == out.length void RegisterFile (const SD& sd, const Signals& control, // control signals are ordered as follows - see Chapt. 5 for terms // RegWrite - turns on register file write // clock - loads WriteData in Write register on leading edge // Write register // Read register N, ... Read register 2, Read register 1 const Signals& writeData, // clock strobes WriteData into Write register // reqires: WriteData.length == wordSize const Signals& ReadData // Read data signals are ordered: // Read data N, ... , Read data 2, Read data 1 // Note: Register 0 always == 0 // requires: ReadData.length == wordSize const int numberOfRegisters, const int wordSize, // register size in bits const int portAddressSize, // requires: portAddressSize = log2(numberOfRegisters) const int numberOfReadPorts, const int numberOfWritePorts );

Register File Example needs clockUnit.h and clockUnit.c


void Rom ( const SD & sd, // This is a word-addressable Rom; the address bus accesses // a word regardless of wordsize. // Regardless of word size, contents must be specified // in groups of 8 bits (e.g. 0x4a) Note: requires violations cause a run-time length error message const Signals& input, // input address bus // requires: input.length == log2 words const Signals& output, // output data bus // requires: output.length == bitsPerWord const int words, // number of words in the ROM // suggestion: specify words as a power of 2 const int bitsPerWord, // definition of a word // suggestion: specify as a power of 2 const unsigned char* romContents); // holds the bits in the ROM // hardcode the values (see example) or load the structure // from a file with the loadRom function
Rom Example needs romfile
Rom Example (hardcoded values)

void Space(const SD& sd);
void Space(const SD& sd, char* text);
// create blank space in the display - to separate components
// text is displayed in the space

void Stop (const SD& sd, const Signal& input);
// when the input Signal comes on, SIM exits.

void Switch (const SD&, const Signal& sig, const char c, 
	     const Signal & init = Zero ); 
// c is key that toggles sig
// init is the initial value of sig
// if sig is a bus, sig.length switches are constructed; for each
//    switch, c is incremented to next char

void Xnor ( const SD &, const Signals &, const Signal & );

void Xor ( const SD &, const Signals &, const Signal & );