Skip to content

Commit

Permalink
Merge branch '3-implement-multiplication-operator' into 'cingu_v2_mas…
Browse files Browse the repository at this point in the history
…ter'

Resolve "Implement multiplication operator"

Closes #3
  • Loading branch information
Sergiu Carpov committed Mar 6, 2019
2 parents e966e9a + 46f9c07 commit 59cdc7f
Show file tree
Hide file tree
Showing 7 changed files with 92 additions and 27 deletions.
21 changes: 9 additions & 12 deletions common/include/int_op_gen/impl/multiplier.hxx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#ifndef MULTIPLIER_OPER
#define MULTIPLIER_OPER

#include <cassert>
#include <int_op_gen/impl/operator.hxx>

namespace cingulata
Expand All @@ -9,25 +10,21 @@ namespace cingulata
{

/**
* @brief Multiplier implementations
* @brief Wallace Multiplier implementations
*/
class Multiplier : public BinaryOper {
class WallaceMultiplier : public BinaryOper {
/**
* @brief Implementation
* @brief Wallace multiplier
*
* @details lhs and rhs have the same length in bits
*
* @param[in] lhs The left hand side
* @param[in] rhs The right hand side
*
* @return Product between inputs
* @return Product between inputs, having the same bit length as inputs
*/
CiBitVector oper(const CiBitVector& lhs, const CiBitVector& rhs) const override {
const int size = lhs.size();
CiBitVector res(size);

/** @todo implement */
return res;
}
};
CiBitVector oper(const CiBitVector& lhs, const CiBitVector& rhs) const override;
};
}
}

Expand Down
10 changes: 5 additions & 5 deletions common/include/int_op_gen/mult_depth.hxx
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,11 @@ namespace cingulata
const CiBitVector& rhs) const override;

private:
int_ops::SklanskyAdder m_add;
int_ops::Negate m_neg;
int_ops::Multiplier m_mul;
int_ops::EqualDepth m_equal;
int_ops::LowerCompDepth m_lower;
int_ops::SklanskyAdder m_add;
int_ops::Negate m_neg;
int_ops::WallaceMultiplier m_mul;
int_ops::EqualDepth m_equal;
int_ops::LowerCompDepth m_lower;
};
}

Expand Down
10 changes: 5 additions & 5 deletions common/include/int_op_gen/size.hxx
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,11 @@ namespace cingulata
const CiBitVector& rhs) const override;

private:
int_ops::RippleCarryAdder m_add;
int_ops::Negate m_neg;
int_ops::Multiplier m_mul;
int_ops::EqualSize m_equal;
int_ops::LowerCompSize m_lower;
int_ops::RippleCarryAdder m_add;
int_ops::Negate m_neg;
int_ops::WallaceMultiplier m_mul;
int_ops::EqualSize m_equal;
int_ops::LowerCompSize m_lower;
};
}

Expand Down
1 change: 1 addition & 0 deletions common/src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ set(SRCS
int_op_gen/impl/equal.cxx
int_op_gen/impl/dec.cxx
int_op_gen/impl/mux.cxx
int_op_gen/impl/multiplier.cxx
)

include_directories(${INCLUDE_DIR})
Expand Down
10 changes: 5 additions & 5 deletions common/src/int_op_gen/impl/adder.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ CiBitVector RippleCarryAdder::oper(const CiBitVector& lhs, const CiBitVector& rh
return res;
}

namespace
namespace
{
void pre_computation( std::vector<CiBitVector>& P, std::vector<CiBitVector>& G, const CiBitVector& lhs, const CiBitVector& rhs) {
const int size = lhs.size();
Expand All @@ -47,8 +47,8 @@ namespace
CiBitVector post_computation( std::vector<CiBitVector>& P, std::vector<CiBitVector>& G, int size) {
CiBitVector res(size);
res[0] = P[0][0];
for ( int i = 1; i < size; ++i)
res[i] = P[i][i] ^ G[i-1][0];
for ( int i = 1; i < size; ++i)
res[i] = P[i][i] ^ G[i-1][0];
return res;
}
}
Expand All @@ -69,15 +69,15 @@ CiBitVector SklanskyAdder::oper(const CiBitVector& lhs, const CiBitVector& rhs)
for (int step = 1; step <= num_steps; ++step ) {
int row = 0;
int col = 0;
/* shift row */
/* shift row */
row += (int) pow(2,step-1);
/* do while the size of enter is not reach*/
while (row < size) {
/* define column value */
col = (int) floor(row/pow(2,step)) * (int) pow(2,step);
for (int i = 0; i <(int) pow(2,step-1); ++i) {
evaluate_G(P, G, row, col, step);
if (col != 0)
if (col != 0)
evaluate_P(P, G, row, col, step);
/* increment row value */
row += 1;
Expand Down
58 changes: 58 additions & 0 deletions common/src/int_op_gen/impl/multiplier.cxx
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
#include <int_op_gen/impl/adder.hxx>
#include <int_op_gen/impl/multiplier.hxx>

using namespace cingulata;
using namespace cingulata::int_ops;

namespace
{
std::vector<CiBitVector> reduce(const std::vector<CiBitVector>& tree) {
const unsigned iter = (unsigned int)(tree.size() / 3);
const unsigned mod = tree.size() % 3;
std::vector<CiBitVector> res;

for (unsigned int i = 0; i < iter; ++i) {
auto sum = tree[3*i];
sum ^= (tree[3*i+1] ^ tree[3*i+2]);
res.push_back(sum);

CiBitVector carry(tree[3*i].size(), CiBit::zero);
for (unsigned int j = 0; j < (tree[3*i].size() - 1); ++j) {
carry[j+1] = ((tree[3*i][j] ^ tree[3*i+2][j]) & (tree[3*i+1][j] ^ tree[3*i+2][j])) ^ tree[3*i+2][j];
}
res.push_back(carry);
}

if (mod != 0) {
res.insert(res.end(), tree.end()-mod, tree.end());
}

const unsigned res_size = 2 * iter + mod;
assert(res.size() == res_size);

return res;
}
}

CiBitVector WallaceMultiplier::oper(const CiBitVector& lhs, const CiBitVector& rhs) const {
const unsigned out_size = lhs.size();
std::vector<CiBitVector> tree;

for (unsigned int i = 0; i < out_size; ++i) {
if (lhs[i].get_val() == 0) {
tree.push_back(CiBitVector(out_size, CiBit::zero));
}
else {
tree.push_back(CiBitVector(rhs >> i));
}
}

while (tree.size() >= 3) {
tree = reduce(tree);
}

BinaryOper *adder = new SklanskyAdder();
CiBitVector res = (*adder)(tree[0], tree[1]);

return res;
}
9 changes: 9 additions & 0 deletions common/test/unittest/test_int_op_gen_impl.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,15 @@ BinaryParam binary_params[] =
[](const unsigned a, const unsigned b) -> unsigned {
return a + b;
}
},
{
"WallaceMultiplier",
[](const CiBitVector& a, const CiBitVector& b) -> CiBitVector {
return WallaceMultiplier()(a,b);
},
[](const unsigned a, const unsigned b) -> unsigned {
return a * b;
}
}
};

Expand Down

0 comments on commit 59cdc7f

Please sign in to comment.