「Verilog学习笔记」求最小公倍数

专栏前言

本专栏的内容主要是记录本人学习Verilog过程中的一些知识点,刷题网站用的是牛客网

题目要求求解两个数的最小公倍数,而最小公倍数可以通过两个数的乘积除以两个数的最小公约数得到。乘法是容易计算的,所以问题变成如何求解最大公约数。可以采用辗转相减法求解,

例如 :两个自然数35和14,用大数减去小数,(35,14)->(21,14)->(7,14),此时,7小于14,要做一次交换,把14作为被减数,即(14,7)->(7,7),再做一次相减,结果为0,这样也就求出了最大公约数7。

然后可以实现除法器IP核或者之间使用 '/'进行除法运算得到最小公倍数,'/'在多数的编译器中也可以进行综合。

复制代码
`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*2-1:0] mcd, a_buf, b_buf, mul_buf ; 
    reg mcd_vld ; 
    reg [1:0] state, nstate ; 
    parameter idle = 0, S0 = 1, S1 = 2, S2 = 3 ; 

    always @ (posedge clk or negedge rst_n) 
        if (!rst_n) state <= idle ; 
        else state <= nstate ; 
    
    always @ (posedge clk or negedge rst_n) 
        if (!rst_n) begin 
            nstate <= idle ; 
            mcd <= 0 ; 
            mcd_vld <= 0 ; 
            a_buf <= 0 ; 
            b_buf <= 0 ; 
            mul_buf <= 0 ; 
            vld_out <= 0 ; 
        end
        else begin 
            case (state) 
            idle : 
            if (vld_in) begin 
                a_buf <= A ; 
                b_buf <= B ; 
                nstate <= S0 ; 
                mul_buf <= A * B ; 
                mcd_vld <= 0 ; 
                vld_out <= 0 ; 
            end
            else begin 
                nstate <= idle ; 
                mcd_vld <= 0 ; 
                vld_out <= 0 ; 
            end
            S0 : 
            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 
                    b_buf <= b_buf - a_buf ; 
                    a_buf <= a_buf ; 
                    vld_out <= 0 ; 
                end
                nstate <= S0 ; 
            end
            else begin 
                nstate <= S1 ; 
                vld_out <= 0 ; 
            end
            S1 : begin 
                mcd <= b_buf ; 
                mcd_vld <= 1 ; 
                nstate <= idle ; 
                vld_out <= 1 ; 
            end
            default : begin 
                nstate <= idle ; 
                vld_out <= 0 ; 
            end
            endcase
        end
            
    assign mcd_out = mcd ; 
    assign lcm_out = mul_buf / mcd ; 

endmodule
相关推荐
通信小呆呆6 小时前
当算法有了“五感”:多模态数据融合如何向人体感官协同学习?
人工智能·学习·算法·机器学习·机器人
H__Rick6 小时前
自动对焦学习-3
人工智能·学习·计算机视觉
Daisy Lee6 小时前
量化学习-第1章-什么是量化金融
学习·金融·datawhale
Alsn867 小时前
等待学习-学习目录:Docker 容器安全攻防
学习·安全·docker
YM52e7 小时前
买菜计算器小应用 - HarmonyOS ArkUI 开发实战-PC版本
学习·华为·harmonyos·鸿蒙·鸿蒙系统
小雨下雨的雨8 小时前
HarmonyOS ArkUI训练营入门-组件掌握系列-Animation 动画效果实现-PC版本
学习·华为·harmonyos·鸿蒙
闪闪发亮的小星星8 小时前
高斯光以及高斯光公式解释
笔记
cqbzcsq9 小时前
CellFlow虚拟细胞论文阅读
论文阅读·人工智能·笔记·学习·生物信息
YangYang9YangYan10 小时前
2026初入职场学习数据分析的价值
学习·数据挖掘·数据分析
阿米亚波10 小时前
【Windows】QEMU 启动 openEuler aarch64/arm64 架构系统 + 离线软件源
linux·windows·经验分享·笔记·架构·arm