Verilog:求两数最大公约数的程序

一、综合来说

本程序是基于黄乐天老师的《跨越算法与实现的鸿沟——如何用数字IC/FPGA实现算法》这个视频中27分21秒时提到的最大公约数算法的基础上进行完善修改的。
原视频贴在下面,关于求最大公约数算法的原理在视频中讲解比较详细,如果不懂的话,务必观看视频或提前搜索了解算法。

跨越算法与实现的鸿沟——如何用数字IC/FPGA实现算法

代码已上传github:https://github.com/hzccn/GCD-in-verilog
本文代码后续又做了部分修改,代码以Github为准。

二、程序框图

视频中程序的框图如下,整体分为状态控制器和数据通路。
系统框图
其中数据通路模块及wire的名字如图。
数据通路

三、数据通路的代码详解

数据通路模块的输入输出接口wire、reg定义如下

`timescale 1ns / 1ps
module calc #(parameter  width = 8)
(
	input 	[width-1:0] operand_A,		//输入计算数A
	input 	[width-1:0] operand_B,		//输入计算数B
	input				A_en,			//A的触发器触发信号,上升沿触发
	input				B_en,			//B的触发器触发信号,上升沿触发
	input	[1:0]		A_mux_sel,		//A的触发器控制信号,用于选择数据的来源
	input				B_mux_sel,      //B的触发器控制信号,用于选择数据的来源
	output 	[width-1:0] result_data,	//A、B的最大公约数,在result_rdy为高时有效
	output				B_zero,			//计算完成标志位
	output				A_lt_B			//交换两数的标志位
	);
	
wire	[width-1:0] 	A_mux_InA;
wire	[width-1:0] 	A_mux_InSub;
wire	[width-1:0] 	A_mux_InB;
reg 	[width-1:0] 	A_mux_out;

wire	[width-1:0] 	B_mux_InA;
wire	[width-1:0] 	B_mux_InB;
reg 	[width-1:0] 	B_mux_out;

reg 	[width-1:0] 	DA_out;
wire	[width-1:0] 	DA_in;
 
reg 	[width-1:0] 	DB_out;
wire	[width-1:0] 	DB_in;

wire 	[width-1:0]		sub_out;

assign A_mux_InA	=operand_A;
assign A_mux_InSub	=sub_out;
assign A_mux_InB	=DB_out;

assign B_mux_InA	=DA_out;
assign B_mux_InB	=operand_B;

assign DA_in		=A_mux_out;
assign DB_in		=B_mux_out;

A_mux选择器、B_mux选择器的代码如下

//A_mux选择器的代码
always@(*)
	begin
	case(A_mux_sel)
		2'b00:A_mux_out=A_mux_InA;
		2'b01:A_mux_out=A_mux_InSub;
		2'b10:A_mux_out=A_mux_InB;
		default:A_mux_out=8'b0;
	endcase
	end

//B_mux选择器的代码
always@(*)
	begin
	case(B_mux_sel)
		0:B_mux_out=B_mux_InA;
		1:B_mux_out=B_mux_InB;
		default:B_mux_out=8'b00;
	endcase
	end

A_D触发器、B_D触发器的代码如下

//A_D触发器的代码
always@(posedge A_en
  • 3
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Verilog中,可以使用辗转相除法来两个数的最大公约数。 辗转相除法的基原理是,两个数的最大公约数等于它们中较小的数和两数之差的最大公约数。可以使用以下的Verilog代码来实现这个功能: ``` module GCD (input [31:0 a, input [31:0 b, output reg [31:0 gcd); always @* begin reg [31:0 x, y, temp; x = a; y = b; while (y != 0) begin temp = y; y = x % y; x = temp; end gcd = x; end endmodule ``` 这段代码定义了一个模块`GCD`,它有两个输入`a`和`b`,一个输出`gcd`。在`always`块中,使用了辗转相除法来计算最大公约数。首先,将输入的两个数赋值给变量`x`和`y`。然后使用一个`while`循环,在循环中计算`y`和`x`的余数,并将`y`赋值给`x`,将余数赋值给`y`,直到`y`为0为止。最后,将最终的结果赋值给输出变量`gcd`。 需要注意的是,在Verilog中,`while`语句是不可综合的,因此不能在实际的硬件设计中使用。这段代码仅用于演示如何用Verilog实现最大公约数的算法。在实际的设计中,可以使用其他的方法来实现这个功能,比如使用状态机或者有限状态机。 <span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [Verilog最大公约数](https://download.csdn.net/download/u010420969/5290775)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *2* *3* [Verilog -- 两数最大公因数(gcd)和最小公倍数(lcm)](https://blog.csdn.net/darknessdarkness/article/details/106048061)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值