题解 | 求最小公倍数

求最小公倍数

https://www.nowcoder.com/practice/ce067d6beee2413c8a26d37ca1a9431f

`timescale 1ns/1ns

module lcm#(
parameter DATA_W = 8)
(
input [DATA_W-1:0] A,
input [DATA_W-1:0] B,
input 			vld_in,
input			rst_n,
input 			clk,
output	wire	[DATA_W*2-1:0] 	lcm_out,
output	wire 	[DATA_W-1:0]	mcd_out,
output	reg					vld_out
);

parameter S0=0,S1=1,S2=2;
reg  [DATA_W-1:0] data_a;
reg  [DATA_W-1:0] data_b;
reg  [DATA_W-1:0] sub_a;
reg  [DATA_W-1:0] sub_b;

reg [1:0]cs;
reg [1:0]ns;

always@(posedge clk or negedge rst_n)begin
    if(!rst_n)
    cs<=0;
    else
    cs<=ns;
end

always@(*)begin
    case(cs)
    S0:ns=(vld_in)?S1:S0;//数据输入
    S1:ns=S2;//数据相减状态
    S2:ns=(data_b==0)?S0:S1;//数据比较状态
    default:ns=S0;
    endcase
end


reg [DATA_W*2-1:0]AB;//两数乘积

always@(posedge clk or negedge rst_n)begin
    if(!rst_n)
        AB<=0;
    else if(cs==S0&&vld_in)
        AB<=A*B;
end

always@(posedge clk or negedge rst_n)begin
    if(!rst_n)begin
        sub_a<=0;
        sub_b<=0;
    end
    else if(cs==S0&&vld_in)begin//减数和被减数赋值
        if(A>B)begin
        sub_a=A;
        sub_b=B;
        end
        else begin
        sub_a=B;
        sub_b=A;
        end
    end
    else if(cs==S2)
        if(data_a>data_b)begin//比较不等于零时换位赋值
        sub_a=data_a;
        sub_b=data_b;
        end
        else begin
        sub_a=data_b;
        sub_b=data_a;
        end
end

always@(posedge clk or negedge rst_n)begin
    if(!rst_n)begin
        data_a<=0;
        data_b<=0;
    end
    else if(cs==S1)begin
        data_a<=sub_b;//最大公约数结果
        data_b<=sub_a-sub_b;//作差结果
    end
end

reg [DATA_W-1:0] gys;
reg [DATA_W-1:0] gys1;
reg [DATA_W-1:0] gys2;
always@(posedge clk or negedge rst_n)begin
    if(!rst_n)
    gys<=0;
    else if(cs==S2&&data_b==0)
    gys<=data_a;
end

always@(posedge clk or negedge rst_n)begin
    if(!rst_n)begin
    gys1<=0;
    gys2<=0;
    end
    else begin
    gys1<=gys;
    gys2<=gys1;
    end
end
reg valid;
reg valid1;
always@(posedge clk or negedge rst_n)begin
    if(!rst_n)
    valid<=0;
    else if(cs==S2&&data_b==0)
    valid<=1;
    else
    valid<=0;
end

always@(posedge clk or negedge rst_n)begin
    if(!rst_n)begin
    valid1<=0;
    vld_out<=0;
    end
    else begin
    valid1<=valid;
    vld_out<=valid1;
    end
end

assign mcd_out=gys2;
assign lcm_out=AB/mcd_out;


endmodule

核心还是辗转相减法,用状态机分三个状态,初始,相减,比较,相应赋值即可

全部评论

相关推荐

评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务