Professional Documents
Culture Documents
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.
CONTROLLER
CONTROLLER: The controller is a finite state machine which gives commands to the datapath based on the current state and the external inputs.
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:
a=3 b=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???