2012-10-06

SCIP in C++11 ― 3.3.4節その3


事象駆動シミューレションその3 デジタル回路のシミュレータその3:繰り上がり伝搬加算器と 問題3.30

途中の繰り上がり信号Ciが、前後両方の全加算器に絡むのでなければ、
accumulate一発ですむところだが、絡むので、丁寧に再帰を書く。

----
const List rippleCarryAdder
(const List& aWires, const List& bWires,
 const List& sumWires,const List& carryWire)
{
    const int order(length(aWires));

    if(order!=length(bWires)||order!=length(sumWires)){
        cerr<<"lengths of bits must be same ("
            <<order<<" , "<<length(bWires)<<" , "
            <<length(sumWires)<<")."<<endl;
        exit(1);
    }

    const List cWires
        (cons(carryWire,
              mapping
              (function<List(List)>
               ([](const List& counter){
                   return(makeLeaf(makeWire()));
               }),enumerateInterval(1,order))));

    function<void(List,List,List,List)> connectFullAdders;
    connectFullAdders=[&connectFullAdders]
        (const List& ai, const List& bi, const List& ciMinus1, const List& si){
        if(!isNull(ai)){
            fullAdder
                (executable<List,List>(car(ai)),
                 executable<List,List>(car(bi)),
                 executable<List,List>(cadr(ciMinus1)),
                 executable<List,List>(car(si)),
                 executable<List,List>(car(ciMinus1)));
            connectFullAdders(cdr(ai),cdr(bi),cdr(ciMinus1),cdr(si));
        }
    };

    connectFullAdders(aWires,bWires,cWires,sumWires);
    return(makeLeaf("OK"));
}

const List makeWireList(const List& signalList)
{
    return
        (mapping
         (function<List(List)>
          ([](const List& signal){
              const Wire signalWire(makeWire());
              setfSignal(signalWire,signal);
              return(makeLeaf(signalWire));
          }),signalList));
          
}


const List getWireListSignals(const List& wireList)
{
    return
        (mapping
         (function<List(List)>
          ([](const List& wireLeaf){
              return(getSignal(executable<List,List>(wireLeaf)));
          }),wireList));
          
}

int main(int argc, char** argv)
{
    cout<<"Excersize 3.30:"<<endl;

    const auto aWires(makeWireList(makeList(1,0,1)));
    const auto bWires(makeWireList(makeList(0,1,1)));

    const auto sumWires(makeWireList(makeList(0,0,0)));
    const auto carryWire(makeWire());

    rippleCarryAdder(aWires,bWires,sumWires,makeLeaf(carryWire));
    propagate();

    cout<<listString(getWireListSignals(aWires))<<"+"
        <<listString(getWireListSignals(bWires))<<":"<<endl;
    cout<<"carry = "<<listString(getSignal(carryWire))
        <<", sum = "<<listString(getWireListSignals(sumWires))<<endl;

    return(0);
}
----
出力
----
Excersize 3.30:
(1 0 1)+(0 1 1):
carry = 1, sum = (0 0 0)

0 件のコメント :

コメントを投稿