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

查看7道真题和解析