一、综合来说
本程序是基于黄乐天老师的《跨越算法与实现的鸿沟——如何用数字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