/*
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
Register File Example needs clockUnit.h and clockUnit.cvoid 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 );
Rom Example needs romfile
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
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 & );