Skip to content

Commit

Permalink
Initial, failing implementation of div and mod cells
Browse files Browse the repository at this point in the history
  • Loading branch information
RCoeurjoly committed May 28, 2024
1 parent bda798f commit 06e05a5
Show file tree
Hide file tree
Showing 5 changed files with 48 additions and 1 deletion.
2 changes: 2 additions & 0 deletions backends/functional/cxx.cc
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,8 @@ class CxxComputeGraphFactory {
T logical_shift_right(T a, T b, int y_width, int) { return graph.add(CxxFunction(ID($shr), y_width, {{ID(WIDTH), y_width}}), 0, std::array<T, 2>{a, b}); }
T arithmetic_shift_right(T a, T b, int y_width, int) { return graph.add(CxxFunction(ID($asr), y_width, {{ID(WIDTH), y_width}}), 0, std::array<T, 2>{a, b}); }
T mul(T a, T b, int width) { return graph.add(CxxFunction(ID($mul), width), 0, std::array<T, 2>{a, b}); }
T mod(T a, T b, int width) { return graph.add(CxxFunction(ID($mod), width), 0, std::array<T, 2>{a, b}); }
T div(T a, T b, int width) { return graph.add(CxxFunction(ID($div), width), 0, std::array<T, 2>{a, b}); }

T constant(RTLIL::Const value) {
return graph.add(CxxFunction(ID($$const), value.size(), {{ID(value), value}}), 0);
Expand Down
30 changes: 30 additions & 0 deletions backends/functional/cxx_runtime/sim.h
Original file line number Diff line number Diff line change
Expand Up @@ -379,4 +379,34 @@ Signal<n> $mul(Signal<n> const& a, Signal<n> const& b)
return ret;
}

template<size_t n>
Signal<n> $div(Signal<n> const& a, Signal<n> const& b)
{
Signal<n> quotient = $const<n>(0);
Signal<n> remainder = a;
Signal<n> divisor = b;

for(int i = n - 1; i >= 0; i--) {
if(as_int(remainder) >= (as_int(divisor) << i)) {
remainder = $sub(remainder, $shl<n, n>(divisor, $const<n>(i)));
quotient[i] = true;
}
}
return quotient;
}

template<size_t n>
Signal<n> $mod(Signal<n> const& a, Signal<n> const& b)
{
Signal<n> remainder = a;
Signal<n> divisor = b;

for(int i = n - 1; i >= 0; i--) {
if(as_int(remainder) >= (as_int(divisor) << i)) {
remainder = $sub(remainder, $shl<n, n>(divisor, $const<n>(i)));
}
}
return remainder;
}

#endif
2 changes: 2 additions & 0 deletions backends/functional/smtlib.cc
Original file line number Diff line number Diff line change
Expand Up @@ -368,6 +368,8 @@ class SmtlibComputeGraphFactory {
T logical_shift_right(T a, T b, int y_width, int b_width) { return shift("bvlshl", a, b, y_width, b_width); }
T arithmetic_shift_right(T a, T b, int y_width, int b_width) { return shift("bvashr", a, b, y_width, b_width, true); }
T mul(T a, T b, int width) { return node(SExpr {"bvmul", Arg(1), Arg(2)}, width, {a, b}); }
T div(T a, T b, int width) { return node(SExpr {"bvudiv", Arg(1), Arg(2)}, width, {a, b}); }
T mod(T a, T b, int width) { return node(SExpr {"bvurem", Arg(1), Arg(2)}, width, {a, b}); }

T constant(RTLIL::Const value) { return node(SExpr(value), value.size(), {}); }
T input(IdString name, int width) {
Expand Down
12 changes: 12 additions & 0 deletions kernel/graphtools.h
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,18 @@ class CellSimplifier {
T a = extend(inputs.at(ID(A)), a_width, width, is_signed);
T b = extend(inputs.at(ID(B)), b_width, width, is_signed);
return extend(factory.mul(a, b, width), width, y_width, is_signed);
}else if(cellType == ID($div)){
bool is_signed = a_signed && b_signed;
int width = max(a_width, b_width);
T a = extend(inputs.at(ID(A)), a_width, width, is_signed);
T b = extend(inputs.at(ID(B)), b_width, width, is_signed);
return extend(factory.div(a, b, width), width, y_width, is_signed);
}else if(cellType == ID($mod)){
bool is_signed = a_signed && b_signed;
int width = max(a_width, b_width);
T a = extend(inputs.at(ID(A)), a_width, width, is_signed);
T b = extend(inputs.at(ID(B)), b_width, width, is_signed);
return extend(factory.mod(a, b, width), width, y_width, is_signed);
}else{
log_error("unhandled cell in CellSimplifier %s\n", cellType.c_str());
}
Expand Down
3 changes: 2 additions & 1 deletion tests/functional/single_bit/run-test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,8 @@ run_test() {
if ./vcd_harness ${base_name}_functional_cxx.vcd; then

# Run yosys to process each Verilog file
if ${BASE_PATH}yosys -p "read_verilog $verilog_file; sim -r ${base_name}_functional_cxx.vcd -scope my_module -timescale 1us -sim-cmp"; then
if ${BASE_PATH}yosys -p "read_verilog $verilog_file; sim -r ${base_name}_functional_cxx.vcd -scope my_module -vcd ${base_name}_yosys_sim.vcd -timescale 1us -sim-cmp"; then
# ${BASE_PATH}yosys -p "read_verilog $verilog_file; sim -vcd ${base_name}_yosys_sim.vcd -r ${base_name}_functional_cxx.vcd -scope my_module -timescale 1us"
echo "Yosys sim $verilog_file successfully."
else
echo "Yosys simulation of $verilog_file failed. There is a discrepancy with functional cxx"
Expand Down

0 comments on commit 06e05a5

Please sign in to comment.