// // 最小公倍数,最大公约数 module lcm#( parameter DATA_W = 8) ( input [DATA_W-1:0] A, // 输入2个无符号数 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 ); reg [DATA_W-1:0] mcd, a_buf, b_buf; reg [DATA_W*2-1:0] mul_buf; // reg mcd_vld; reg [1:0] cur_st, nx_st; parameter idle = 2'b00, s1 = 2'b01, s2 = 2'b10; // s2 = 2'b11; // 两段式状态机 always@(posedge clk or negedge rst_n) if(!rst_n) cur_st <= idle; else cur_st <= nx_st; always@(posedge clk or negedge rst_n) begin if(!rst_n) begin a_buf <= 8'd0; b_buf <= 8'd0; mul_buf <= 16'd0; mcd <= 8'd0; vld_out <= 1'b0; nx_st <= idle; end else case(cur_st) idle: begin if(vld_in) begin a_buf <= A; b_buf <= B; mul_buf <= A*B; nx_st <= s1; end else begin nx_st <= idle; end vld_out <= 1'b0; end s1: if(a_buf != b_buf) begin if(a_buf > b_buf) begin a_buf <= a_buf - b_buf; b_buf <= b_buf; end else begin a_buf <= a_buf; b_buf <= b_buf - a_buf; end nx_st <= s1; end else nx_st <= s2; s2: begin vld_out <= 1'b1; mcd <= a_buf; // 最大公约数 nx_st <= idle; end default: nx_st <= idle; endcase end // 注意:这里也是对的,但是在牛客网的测试上没通过. // assign mcd_out = (vld_out == 1'b1) ? mcd : 8'd0; // assign lcm_out = (vld_out == 1'b1) ? mul_buf/mcd_out : 16'd0; assign mcd_out = mcd; assign lcm_out = mul_buf/mcd_out; endmodule