module GCD ( input wire CLK, input wire RST_N, input wire [7:0] A, input wire [7:0] B, input wire START, output reg [7:0] Y, output reg DONE, output reg ERROR ); wire found, err; reg [7:0] reg_a, reg_b, next_a, next_b; reg [7:0] big_one; reg error_next; reg [1:0] state, state_next; parameter [1:0] IDLE = 2'b00; parameter [1:0] CALC = 2'b01; parameter [1:0] FINISH = 2'b10; always @(posedge CLK, negedge RST_N) begin if (RST_N == 0) state <= IDLE; else state <= state_next; end always @*begin state_next = IDLE; case(state) IDLE: begin if (!START) state_next = IDLE; else state_next = CALC; end CALC: begin if (!found && !ERROR) state_next = CALC; else state_next = FINISH; end FINISH: begin state_next = IDLE; end endcase end always @*begin if (state == IDLE) begin if (!START) error_next = 0; else error_next = ((A == 0) || (B == 0)); end else if (state == CALC) error_next = ERROR; else if (state == FINISH) begin DONE = 1'd1; error_next = 0; end end always @(posedge CLK, negedge RST_N) begin ERROR <= error_next; end assign start_A_out = START == 1 ? A : next_a; assign start_B_out = START == 1 ? B : next_b; always @(posedge CLK, negedge RST_N) begin reg_a <= start_A_out; end always @(posedge CLK, negedge RST_N) begin reg_b <= start_B_out; end wire cout; always @*begin if (reg_a >= reg_b) begin adder8(cout, next_a, reg_a, reg_b, 1); next_b = reg_b; end else begin adder8(cout, next_b, reg_b, reg_a, 1); next_a = reg_a; end end assign found = (next_a == 0 || next_b == 0) ? 1 : 0; always @*begin if (reg_a > reg_b) begin big_one = reg_a; end else begin big_one = reg_b; end end assign found_out = (found == 0) ? Y : big_one; always @(posedge CLK, negedge RST_N) begin Y <= found_out; end endmodule module adder8( output cout, //MSB, determines if answer is positive or negative output [7:0] s, input [7:0] a, input [7:0] b, input cin // if 1, subtract, if 0, add. This is XOR'ed with b ); wire [7:0] bin; assign bin[0] = b[0]^cin; assign bin[1] = b[1]^cin; assign bin[2] = b[2]^cin; assign bin[3] = b[3]^cin; assign bin[4] = b[4]^cin; assign bin[5] = b[5]^cin; assign bin[6] = b[6]^cin; assign bin[7] = b[7]^cin; wire [8:1] carry; full_adder FA0(carry[1],s[0],a[0],bin[0],cin); full_adder FA1(carry[2],s[1],a[1],bin[1],carry[1]); full_adder FA2(carry[3],s[2],a[2],bin[2],carry[2]); full_adder FA3(carry[4],s[3],a[3],bin[3],carry[3]); full_adder FA4(carry[5],s[4],a[4],bin[4],carry[4]); full_adder FA5(carry[6],s[5],a[5],bin[5],carry[5]); full_adder FA6(carry[7],s[6],a[6],bin[6],carry[6]); full_adder FA7(carry[8],s[7],a[7],bin[7],carry[7]); assign cout = cin^carry[8]; endmodule module full_adder( output cout, output sum, input ain, input bin, input cin ); //assign bin2 = cin^bin; // XORing the inputs to bin with cin. If 1, subtract; if 0, add assign sum = ain^bin^cin; assign cout = (ain&bin) | (ain&cin) | (bin&cin); endmodule