#include <systemc>

using namespace sc_core;
using namespace sc_dt;
using namespace std;

template <typename T>
SC_MODULE(gcd) {
    sc_in_clk clk;
    sc_in<bool> reset;
    sc_in<bool> go_i;
    sc_in<T> x_i, y_i;
    sc_out<bool> done_o;
    sc_out<T> r_o;
    SC_CTOR(gcd) {
        SC_CTHREAD(run, clk.pos());
        reset_signal_is(reset, true);
    }
private:
    void run() {
        wait();
        while(1) {
            do {
                wait();
            } while (!go_i.read());
            T x = x_i.read();
            T y = y_i.read();
            wait();
            while (go_i.read() && x != y) {
                if (x > y) {
                    x -= y;
                } else {
                    y -= x;
                }
                wait();
            }
            if (go_i.read()) {
                r_o.write(x);
                done_o.write(true);
            }
            do {
                wait();
            } while (go_i.read());
            done_o.write(false);
        }
    }
};

int sc_main(int argc, char *argv[]) {
    gcd<unsigned int> gcd("gcd");
    return 0;
}
