Stein算法求最大公约数 verilog实现
实然想写写博客,最近在学verilog。然后就想记录一下
算法步骤:
1、先装载A和B的值,C初始值设为1。
2、若A=0,则B是最大公约数;若B=0,则A是最大公约数;若A=B,则A是最大公约数。若上面三种情况都不成立,则跳到3,否则跳到4
3、 若A是偶数,B是偶数;则A>>1,B>>1,C<<1(LSB填充1);
若A是偶数,B是奇数;则A>>1,B不变,C不变;
若A是奇数,B是偶数;则A不变,B>>1,C不变;
若A是奇数,B是奇数;则if(A>B) A=A-B;else B=B-A,C不变;
4、输出结果。
更详细的原理可以参考这个博主:https://blog.csdn.net/k331922164/article/details/48195893
总体来说这个算法比较简单,用一段式写的。把2和3用五个状态表示
直接看程序
//copyright:Qing
//Date:2020.04
module stein(
input [11:0] in_a,
input [11:0] in_b,
input clk,
input rst_n,
output reg [11:0] done
);
reg [11:0] A,B,C,D,A1,B1;
reg [4:0] state;
//wire [11:0] done;
parameter N01='b00001,
N02='b00010,
N03='b00100,
N04='b01000,
N05='b10000;
always @(posedge clk or negedge rst_n)
begin
if(!rst_n)
begin
A<=in_a;
B<=in_b;
C<=1'b1;
state<=N01;
end
else
begin
case(state)
N01:
if(A==0)
begin
B1<=B;
D<=C;
end
else if(B==0)
begin
A1<=A;
D<=C;
end
else
begin
if(A[0]==0&&B[0]==0)
begin
state<=N02;
end
else if(A[0]==1'b1&&B[0]==1'b1)
begin
state<=N03;
end
else if(A[0]==1'b0&&B[0]==1'b1)
begin
state<=N04;
end
else
begin
state<=N05;
end
end
N02:
begin
A<=(A>>1);
B<=(B>>1);
C<=(C<<1);
state<=N01;
end
N03:
begin
if(A>B)
begin
A<=A-B;
end
else
begin
B<=B-A;
end
state<=N01;
end
N04:
begin
A<=(A>>1);
state<=N01;
end
N05:
begin
B<=(B>>1);
state<=N01;
end
default: state<=N01;
endcase
end
end
always @(posedge clk or negedge rst_n)
begin
done<=(A1+B1)*D;
end
//assign done=(A1+B1)*D;
endmodule
输入数据比较简单,直接用Quartus。仿真结果:
从结果可以看出,56和24的最大公约数是8。