题解 | #求最小公倍数#

求最小公倍数

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

辗转相除法,不需要使用状态机,而是引入了一个flag_r标志正在进行辗转相除,比参考答案节约了7个cycle

`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
);
    
    reg [DATA_W-1:0] a_r;
    reg [DATA_W-1:0] b_r;
    wire [DATA_W-1:0] a_w;
    wire [DATA_W-1:0] b_w;
    wire [DATA_W-1:0] res_w;
    reg flag_r;
    reg [DATA_W*2-1:0] lcm_out_r;
    
    assign vld_out = flag_r && (a_r == b_r);
    assign res_w = a_r - b_r;
    assign {a_w, b_w} = res_w > b_r ? {res_w, b_r} : {b_r, res_w};
    assign mcd_out = vld_out ? a_r : 'd0;
    assign lcm_out = lcm_out_r/ mcd_out;
    
    always @(posedge clk or negedge rst_n) begin
        if (!rst_n) begin
            a_r <= 'd0;
            b_r <= 'd0;
            flag_r <= 'd0;
        end
        else if (vld_in) begin
            {a_r, b_r} <= A > B ? {A, B} : {B, A};
            lcm_out_r <= A * B;
            flag_r <= 'd1;
        end
        else if (vld_out) begin
            flag_r <= 'd0;
        end
        else if (flag_r) begin
            a_r <= a_w;
            b_r <= b_w;
        end
    end
endmodule
全部评论
这叫更相减损术。。不是辗转相除法
1 回复 分享
发布于 2022-09-06 09:48 北京
更省时但和答案时序对不上。。
点赞 回复 分享
发布于 2022-10-22 15:09 河北
这个逻辑好复杂啊
点赞 回复 分享
发布于 2022-09-07 15:57 四川
代码根本就是错的还发出来?
点赞 回复 分享
发布于 2022-07-23 19:42
因为跟答案时钟周期不同,系统会判错。不过这应该是更优解。
点赞 回复 分享
发布于 2022-04-03 12:24
vld_out 是reg型,前面不能用assign吧
点赞 回复 分享
发布于 2022-03-31 14:18

相关推荐

迷茫的大四🐶:干脆大厂搞个收费培训得了,这样就人均大厂了
点赞 评论 收藏
分享
敢逐云霄志:你打招呼语怎么能这么长,hr都没看下去的欲望,简明扼要说重点,就读于某某学校某某专业,26届应届毕业生,学信网可查,先后在某某公司实习过(如有),然后做过什么项目,想找一份什么样的工作,可实习几个月以上,期待您的回复。
点赞 评论 收藏
分享
评论
17
收藏
分享

创作者周榜

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