题解 | 求最小公倍数
求最小公倍数
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
核心还是辗转相减法,用状态机分三个状态,初始,相减,比较,相应赋值即可