You are on page 1of 19

GCD OF TWO NUMBERS

BY K.ARUN KUMAR ADITYA RAJA ABURI

WHAT IS GCD?


GCD (Greatest Common Divisor) of two or more numbers is the largest number that divides the numbers without any remainder.

GCD is always a non-zero positive number. GCD can be computed only for positive numbers.

DESIGN AND IMPLEMENTATION


The design is implemented by dividing it into two parts. DATAPATH

CONTROLLER

DESIGN AND IMPLEMENTATION




CONTROLLER: The controller is a finite state machine which gives commands to the datapath based on the current state and the external inputs.

DATAPATH: The datapath performs the actual GCD computation.

LOGIC:


Two numbers a & b are considered. a & b are compared. If a>b then a=a-b. If b>a then b=b-a. If a=b then GCD is found.

EXAMPLE:

LET a=9, b=6 SINCE a>b, a=a-b SINCE b>a, b=b-a

a=3 b=3

SINCE a=b, GCD is computed and is equal to 3.

STATE DIAGRAM:

STRUCTURE OF GCD

CODE:
//REGISTER module register(clk, rst, load, in, out); input clk, rst; input load; input [3:0] in; output reg[3:0] out; always@(posedge clk) begin if( rst ) out<= 4'b0000; else if( load ) out <= in; end endmodule //MULTIPLEXER module mux ( in1,in2,sel,out); input[3:0] in1, in2; input sel; output reg[3:0] out; always @(sel or in1 or in2) begin if(!sel) out <= in1; else out <= in2; end endmodule

CODE:
//COMPARATOR module comparator(in1, in2, x_gt_y_o, x_eq_y_o, x_lt_y_o ); input[3:0] in1,in2; output x_gt_y_o, x_eq_y_o, x_lt_y_o; reg x_gt_y, x_eq_y, x_lt_y; always @ (in1 or in2) begin if (in1 > in2) begin x_gt_y <= 1; x_eq_y <= 0; x_lt_y <= 0; end else if (in1 < in2) begin x_gt_y <= 0; x_eq_y <= 0; x_lt_y <= 1; end else if(in1 == in2) begin x_gt_y <= 0; x_eq_y <= 1; x_lt_y <= 0; end else begin x_gt_y <= 0; x_eq_y <= 0; x_lt_y <= 0; end end assign x_gt_y_o = x_gt_y; assign x_lt_y_o = x_lt_y; assign x_eq_y_o = x_eq_y; endmodule

CODE:
//SUBTRACTOR module subtractor (in1, in2, out); input[3:0] in1,in2; output reg[3:0] out; always @( in1 or in2 ) begin out <= (in1 - in2); end endmodule //DATAPATH module datapath ( clk, rst, x_i, y_i, x_sel, y_sel, x_ld, y_ld, out_en, input clk, rst; input[3:0] x_i, y_i; input x_sel, y_sel,x_ld, y_ld,out_en; output x_gt_y,x_lt_y,x_eq_y; output[3:0] data_out; wire[3:0] xmux_w, ymux_w; wire[3:0] reg1_out_w, reg2_out_w,reg3_out_w, reg4_out_w; wire[3:0] subx_out_w, suby_out_w; mux M1 (.in1(x_i),.in2(reg3_out_w),.sel(x_sel),.out(xm ux_w)); mux M2 (.in1(y_i),.in2(reg4_out_w),.sel(y_sel),.out(ym ux_w)); register R1 ( .clk(clk), .rst(rst), .load(x_ld), .in(xmux_w), .out(reg1_out_w) ); register R2 ( .clk(clk), .rst(rst), .load(y_ld), .in(ymux_w), .out(reg2_out_w) ); register R3 ( .clk(clk), .rst(rst), .load(x_gt_y), .in(subx_out_w), .out(reg3_out_w) ); register R4 ( .clk(clk), .rst(rst), .load(x_lt_y), .in(suby_out_w), .out(reg4_out_w) ); register R5 ( .clk(clk), .rst(rst), .load(out_en), .in(reg1_out_w), .out(data_out) ); subtractor SUBX ( .in1(reg1_out_w), .in2(reg2_out_w), .out(subx_out_w) ); subtractor SUBY ( .in1(reg2_out_w), .in2(reg1_out_w), .out(suby_out_w) ); comparator COMP ( .in1(reg1_out_w),.in2(reg2_out_w),.x_gt_y_o( x_gt_y), endmodule

CODE:
//CONTROLLER module controller( clk, rst, go, x_gt_y_i, x_lt_y_i, x_eq_y_i, x_sel, y_sel, x_ld, y_ld, out_en ); parameter IDLE= 3'b0000 LOAD = 3'b001, COMPARE = 3'b010, SUBX = 3'b011, SUBY = 3'b100; input clk,rst,go; input x_gt_y_i,x_lt_y_i,x_eq_y_i; output reg x_sel, y_sel,x_ld, y_ld,out_en; reg[2:0] state; always @(posedge clk) begin if(rst) begin out_en <= 1'b0; x_sel <= 1'b0; y_sel <= 1'b0; x_ld <= 1'b0; y_ld <= 1'b0; //CONTROLLER state <= IDLE; end else begin case(state) IDLE: begin if(go) begin x_ld <= 1'b1; y_ld <= 1'b1; x_sel <= 1'b0; y_sel <= 1'b0; out_en <= 1'b0; state <= LOAD; end else begin x_ld <= 1'b0; y_ld <= 1'b0;

CODE:
//CONTROLLER x_sel <= 1'b0; y_sel <= 1'b0; state <= IDLE; end end LOAD: state <= COMPARE; COMPARE: begin if(x_gt_y_i) begin x_sel <= 1'b1; state <= SUBX; end else if(x_lt_y_i) begin y_sel <= 1'b1; state <= SUBY; end //CONTROLLER else if(x_eq_y_i) begin out_en <= 1'b1; state <= IDLE; end end SUBX: state <= COMPARE; SUBY: state <= COMPARE; default: state <= IDLE; endcase end end endmodule

CODE:
//MAIN MODULE module gcd_cal(clk, rst, go, x_i, y_i, out_en, data_out ); input clk,rst; input go; input[3:0] x_i,y_i; output[3:0] data_out; output out_en; wire x_sel_w, y_sel_w,x_ld_w, y_ld_w; wire x_gt_y_w, x_lt_y_w, x_eq_y_w; controller C(.clk(clk), .rst(rst), .go(go),.x_gt_y_i(x_gt_y_w),.x_lt_y_i(x_lt_y_), .x_eq_y_i(x_eq_y_w), .x_sel(x_sel_w),.y_sel(y_sel_w), .x_ld(x_ld_w), .y_ld(y_ld_w), .out_en(out_en) ); datapath D(.clk(clk), .rst(rst), .x_i(x_i), .y_i(y_i), .x_sel(x_sel_w),.y_sel(y_sel_w), .x_ld(x_ld_w), .y_ld(y_ld_w), .x_gt_y(x_gt_y_w),.x_lt_y(x_lt_y_w), .x_eq_y(x_eq_y_w), .out_en(out_en), .data_out(data_out) ); endmodule //TESTBENCH module gcd_tb; reg CLK, RST; reg GO; reg[3:0] X_I, Y_I; wire[3:0] DATA_OUT; wire OUT_EN; gcd_cal GCD ( .clk(CLK), .rst(RST), .go(GO), .x_i(X_I), .y_i(Y_I), .out_en(OUT_EN), .data_out(DATA_OUT) ); initial begin CLK = 1'b0; forever #5 CLK = ~CLK; end initial

CODE:
//TEST BENCH begin @(posedge CLK); RST = 1'b1; X_I = 4'b1000; Y_I = 4'b0100; GO = 1'b1; @(negedge CLK); GO = 1'b0; @(negedge CLK); RST = 1'b0; repeat(8) @(posedge CLK); GO = 1'b1; X_I = 4'b1000; Y_I = 4'b0100; @(negedge CLK); GO = 1'b0; wait(OUT_EN) begin @(posedge CLK); GO = 1'b1; //TEST BENCH X_I = 4'b1011; Y_I = 4'b0010; @(negedge CLK); GO = 1'b0; end wait(OUT_EN) begin @(posedge CLK); GO = 1'b1; X_I = 4'b1001; Y_I = 4'b0110; @(negedge CLK); GO = 1'b0; end wait(OUT_EN) begin @(posedge CLK); GO = 1'b1; X_I = 4'b1001; Y_I = 4'b0110; @(negedge CLK);

CODE:
//TEST BENCH GO = 1'b0; end wait(OUT_EN) begin @(posedge CLK); GO = 1'b1; X_I = 4'd1010; Y_I = 4'b0101; @(posedge CLK); GO = 1'b0; end wait(OUT_EN) #10 $finish; end always @(posedge CLK) $strobe("\nRESET = %d\tGO = %d\ tinput1 = %d\tinput2 = %d\t GCD = %d\n", RST, GO, X_I, Y_I, DATA_OUT); endmodule

WAVEFORMS:

THANK YOU

QUESTIONS???

You might also like