乘法计算器 FPGA 设计 Verilog Vivado
名称乘法计算器 FPGA 设计 Verilog Vivado软件Vivado语言Verilog功能介绍本项目实现的是一个 FPGA 乘法计算器使用 Verilog 编写在 Vivado 环境下完成工程设计。系统通过 4x4 矩阵键盘输入数字和功能按键支持两个操作数的输入、乘法运算、清除/取消以及确认等基本计算器操作适合用于数字逻辑课程设计、FPGA 综合实验和矩阵键盘/数码管综合应用练习。 计算器顶层模块提供时钟、复位、符号控制、结果高低位切换、键盘行列扫描以及六位数码管显示接口。操作数 A 和操作数 B 均按 16 位数据处理乘法结果为 32 位显示部分结合状态机和数码管扫描逻辑根据当前输入阶段或计算结果输出对应内容。 设计中还加入了符号开关控制signal_A 和 signal_B 分别用于设置两个输入数的符号switch_dis 用于切换乘积高位和低位显示使有限位数的数码管能够查看较宽的乘法结果。整体功能覆盖了键盘输入、按键消抖、状态控制、二进制/BCD 数据处理、乘法运算和动态显示等多个常见 FPGA 实验知识点。运行环境开发语言Verilog 开发软件Vivado 顶层模块calculator 工程类型FPGA 数字逻辑工程 主要接口系统时钟、低电平复位、4x4 矩阵键盘、六位数码管位选/段选、符号控制开关、结果高低位切换开关设计思路系统采用模块化结构设计顶层 calculator 负责连接各个功能单元。外部 50MHz 时钟先经过分频模块生成键盘扫描和显示处理所需的较低频率时钟矩阵键盘模块负责识别数字键、乘号键、确认键和取消键并输出单次有效的按键脉冲避免长按或抖动造成重复输入。 运算流程由状态控制模块管理。用户先输入第一个操作数再通过乘法功能键进入第二个操作数输入阶段按确认键后进入结果显示阶段取消键可用于退出或清除当前输入流程。数字输入模块根据当前状态把键盘输入转换为操作数 A、操作数 B同时保留 BCD 形式用于显示并把二进制操作数送入乘法处理链路。 显示部分根据当前状态选择显示操作数或乘法结果。由于乘法结果为 32 位而数码管数量为 6 位设计提供 switch_dis 开关用于切换结果显示范围便于在开发板上查看乘积的不同部分。signal_A、signal_B 两个符号输入开关参与显示逻辑使计算器能够表达正负输入相关的显示状态。 该设计的重点不只是单独的乘法器而是把输入、控制、运算和输出完整串联成一个可交互的 FPGA 小系统。对于学习者来说可以重点参考状态机划分、矩阵键盘扫描、按键上升沿处理、BCD 显示转换以及多模块顶层集成方式。模块结构顶层模块calculator 主要模块包括 1. div_clk时钟分频模块将输入时钟分频到键盘扫描/显示处理使用的时钟。 2. data_input键盘输入模块负责 4x4 矩阵键盘扫描并输出数字键及功能键的有效触发信号。 3. key_4x4、key_jitter矩阵键盘扫描与按键消抖相关模块。 4. state_ctrl状态控制模块处理 ESC、乘号、Enter 等功能键输出当前计算状态。 5. num_in数字输入模块根据状态接收数字键生成操作数 A、操作数 B 及其 BCD 数据。 6. Multiplier_16bit16 位乘法运算模块输出 32 位乘法结果。 7. binTobcd二进制到 BCD 转换模块用于数码管显示数据处理。 8. display数码管显示模块根据操作数、结果、状态和开关信号输出位选与段选。 9. v_ajxd、v_disp1、v1、divclk 等辅助显示、分频或工程扩展相关模块。 顶层 calculator 将键盘输入、状态机、数字录入、乘法结果和六位数码管显示连接为完整系统。开发板验证工程配有 Vivado 管脚约束文件 pins.xdc并包含开发板实物参考图片可用于开发板上板验证。顶层接口已经面向实际硬件资源组织包括矩阵键盘行列接口、六位数码管位选/段选接口、复位开关、符号控制开关以及结果高低位切换开关。 开发板验证时可通过键盘输入两个操作数使用乘法键进入运算流程按确认键后在数码管上查看结果通过 switch_dis 开关切换乘积显示范围通过 signal_A、signal_B 开关控制两个输入数的符号显示状态。仿真图/仿真说明/设计文档图片工程包含 Vivado 仿真相关文件测试文件为 bcd_tb.v仿真对象主要围绕 BCD 转换/显示数据处理链路展开。仿真工程中保留了 xsim 行为仿真生成文件和波形配置文件可作为查看转换逻辑和验证基础功能的参考。部分代码以下展示顶层模块calculator的部分代码完整代码可关注下方公众号卡片获取。module calculator( input clk,//时钟 input reset,//低电平复位--SW0 input signal_A,//输入第一个数的符号--SW1 input signal_B,//输入第二个数的符号--SW2 input switch_dis,//切换乘积高位和低位--SW3 //数字按键 input [3:0] L_row,//行 output [3:0] H_col,//列 output [5:0] bit_select,//6个数码管位选信号 output [7:0] seg_select//数码管段选信号 ); wire [2:0] current_state;//当前状态 wire key_0_p; wire key_1_p; wire key_2_p; wire key_3_p; wire key_4_p; wire key_5_p; wire key_6_p; wire key_7_p; wire key_8_p; wire key_9_p; wire esc;//ESC键 wire mul;//乘 wire enter;//Enter键 wire [15:0] OP_A;//输入的操作数A--65535最大 wire [15:0] OP_B;//输入的操作数B--65535最大 wire [31:0] OP_Result;//结果 wire [19:0] OP_A_bcd;//输入的操作数A wire [19:0] OP_B_bcd;//输入的操作数B wire clk_500KHz; //分频 div_clk i_div_clk( . clk(clk),//50M . clk_500KHz(clk_500KHz)//分频到500K ); //输入模块 data_input i_data_input( . clk(clk),//500KHZ . reset(reset), . L_row(L_row),//行 . H_col(H_col),//列 . key_0_rise(key_0_p), . key_1_rise(key_1_p), . key_2_rise(key_2_p), . key_3_rise(key_3_p), . key_4_rise(key_4_p), . key_5_rise(key_5_p), . key_6_rise(key_6_p), . key_7_rise(key_7_p), . key_8_rise(key_8_p), . key_9_rise(key_9_p), . key_A_rise(mul),//乘 . key_B_rise(enter),//等于 . key_C_rise(esc),//取消 . key_D_rise(), . key_E_rise(), . key_F_rise() ); //状态控制模块 state_ctrl i_state_ctrl( . clk(clk),//时钟 . esc(esc),//ESC键 . mul(mul),//乘 . enter(enter),//Enter键 . current_state(current_state)//当前状态 ); //数字输入模块 num_in i_num_in( . clk(clk),//时钟 . esc(esc),//ESC键 . key_0(key_0_p), . key_1(key_1_p), . key_2(key_2_p), . key_3(key_3_p), . key_4(key_4_p), . key_5(key_5_p), . key_6(key_6_p), . key_7(key_7_p), . key_8(key_8_p), . key_9(key_9_p), . current_state(current_state),//当前状态 . OP_A_bcd(OP_A_bcd), . OP_B_bcd(OP_B_bcd), . OP_A(OP_A),//输入的操作数A . OP_B(OP_B),//输入的操作数B . OP_Result(OP_Result)//结果 ); //数码管显示模块 display i_display( . clk(clk),// . signal_A(signal_A),//输入第一个数的符号--SW1 . signal_B(signal_B),//输入第二个数的符号--SW2 . switch_dis(switch_dis),//切换乘积高位和低位--SW3 . OP_A(OP_A),//输入的操作数A . OP_B(OP_B),//输入的操作数B . OP_A_bcd(OP_A_bcd), . OP_B_bcd(OP_B_bcd), . OP_Result(OP_Result),//结果 . state(current_state),//定义状态 . bit_select(bit_select),//6个数码管位选信号 . seg_select(seg_select)//数码管段选信号 ); endmodule代码获取点击下方公众号卡片