RISC-V ALU 运算器 Verilog Quartus
名称:RISC-V ALU 运算器 Verilog Quartus
软件:Quartus
语言:Verilog
开发板/平台:Cyclone IV FPGA开发板
功能介绍
这是一个基于 Verilog 的 RISC-V 整数 ALU FPGA 验证工程。设计支持 32 位两个操作数和 5 位功能码输入,用户可在开发板上通过 8 位拨码开关逐字节设置数据,使用确认按键完成输入锁存,再按启动键执行一次运算。\n\n运算结果除了输出 32 位数据,还提供结果有效、加法进位、减法借位、有符号溢出和结果为零等状态标志,便于通过 LED 直接观察 ALU 的运算状态。结果会锁存到顶层寄存器,避免输入变化影响当前显示。\n\n六位七段数码管以十六进制显示结果,并通过动态扫描和流动窗口展示完整的 32 位数据。工程同时配套顶层 Testbench、按键驱动任务、自动检查逻辑及 ModelSim 脚本,适合学习 RISC-V ALU 结构、按键采样、边沿检测、状态锁存和 FPGA 外设显示控制。运行环境
EDA 工具为 Quartus II 13.0 SP1,目标器件为 Cyclone IV E 系列 EP4CE6F17C8,主时钟为开发板 50 MHz 时钟。仿真使用 ModelSim SE-64 10.1c,工程文件包含 QPF、QSF、管脚约束、Verilog RTL、Testbench 和一键运行脚本。\n\n顶层显示参数默认 SCAN_DIV=50000、SHIFT_DIV=50000000,适用于 50 MHz 时钟下的板级动态扫描和约 1 秒流动移动;仿真时可使用较小参数,例如 SCAN_DIV=4、SHIFT_DIV=100。设计思路
本设计面向 RISC-V 整数 ALU 的板级验证,将输入采集、算术逻辑运算、结果锁存和人机显示拆分为独立模块。用户通过 8 位拨码开关设置功能码或一个操作数的当前字节,再使用低电平有效按键逐段确认。输入模块分别保存功能码、src0 和 src1,并在所需字段全部确认后产生对应的有效标志,避免未完成输入时启动计算。\n\n核心 riscv_alu 采用组合逻辑支持 ADD、SUB、SLT、SLTU、AND、OR、XOR、SLL、SRL、SRA、MOV_A 和 MOV_B 等功能码。加法输出进位标志,减法输出借位标志,有符号加法产生溢出标志,所有合法运算均提供结果有效和零结果标志。顶层对启动按键进行两级同步和高到低边沿检测,只有功能码及两个操作数均有效时才锁存结果和标志,从而让显示内容保持稳定。\n\n显示模块接收锁存后的 32 位结果,以十六进制拆分为多个 nibble,通过动态扫描驱动六位低电平有效七段数码管,并在环形序列中移动显示窗口。SCAN_DIV 用于调节位扫描速度,SHIFT_DIV 用于调节约 1 秒一次的流动速度;仿真时可将两个参数设置为较小值以缩短观察时间。模块结构
顶层模块为 alu_top,负责按键边沿检测、子模块连接、结果与标志锁存以及外部 LED/数码管接口。alu_key_input 将拨码开关和低电平有效按键转换为 alu_func、alu_src0、alu_src1 及对应 vld 信号;每个 32 位操作数由四个 8 位字节依次确认,四段完成后置有效。riscv_alu 根据功能码完成算术、逻辑、移位和比较运算,输出结果及进位、借位、溢出、零结果标志。alu_display 对锁存结果进行十六进制译码、六位动态扫描和环形流动显示。工程还包含 alu_top_tb、riscv_alu_tb 及 run_alu_top_tb.do 仿真文件。开发板验证
工程已在 CX401 Cyclone IV FPGA 开发板上完成验证,使用 Quartus 的管脚分配约束连接 50 MHz 时钟、低电平复位、8 位拨码开关、功能确认按键、两个 32 位操作数的分字节确认按键以及启动按键。板上通过 LED0~LED4 指示结果有效、加法进位、减法借位、溢出和零结果,6 位低电平有效七段数码管显示锁存后的 32 位运算结果。操作时先复位,再依次确认功能码和两个操作数的 4 个字节,最后按下启动键锁存结果;数码管按约 1 秒的节奏进行十六进制流动显示。

演示视频
配套演示视频展示了 CX401 开发板上的实际操作流程和显示效果,包括拨码开关输入功能码、分字节确认两个 32 位操作数、按下启动键完成一次 ALU 运算,以及 LED 标志和六位七段数码管流动显示结果的过程。仿真图/仿真说明/设计文档图片
工程配套设计说明覆盖系统架构、数据流、顶层锁存、按键输入、ALU 运算、数码管显示、上板操作、引脚分配和常见问题排查,并提供 RTL 结构、管脚分配、仿真图和模块说明。alu_top_tb 采用顶层驱动方式模拟拨码与按键输入,包含复位后重新计算场景,自动检查 LED 标志及七段数码管反解出的十六进制数据。run_alu_top_tb.do 通过 vlib、vlog 和 vsim 命令完成编译与全流程仿真。文档中的仿真与设计图片可用于配合代码理解信号时序、模块连接和显示过程。











部分代码
以下展示顶层模块 alu_top 的部分代码,完整源码请下载压缩包查看。
module alu_top #(
parameter integer SCAN_DIV = 32'd50000, // 数码管位扫描分频
parameter integer SHIFT_DIV = 32'd50000000 // 数码管流动显示分频(约 1 秒)
)(
input clk, // 板上 50MHz 时钟
input rst_n, // 低电平复位(key4)
input [7:0] sw_in, // 8 位拨码开关输入(BM8~BM1)
input alu_func_key, // 功能码确认按键(SW55)
input alu_src1_key0,//按键,按下低电平,用于确认alu_src1_i[7:0] 输入完成SW33
input alu_src1_key1,//按键,按下低电平,用于确认alu_src1_i[15:8] 输入完成SW36
input alu_src1_key2,//按键,按下低电平,用于确认alu_src1_i[23:16]输入完成SW39
input alu_src1_key3,//按键,按下低电平,用于确认alu_src1_i[31:24]输入完成SW42
input alu_src2_key0,//按键,按下低电平,用于确认alu_src2_i[7:0] 输入完成SW47
input alu_src2_key1,//按键,按下低电平,用于确认alu_src2_i[15:8] 输入完成SW49
input alu_src2_key2,//按键,按下低电平,用于确认alu_src2_i[23:16]输入完成SW50
input alu_src2_key3,//按键,按下低电平,用于确认alu_src2_i[31:24]输入完成SW53
input start_key, // 启动 ALU 运算并锁存结果的按键(SW45)
output alu_rslt_vld_led, // 结果有效标志 LED0
output alu_add_carry_led, // 加法进位标志 LED1
output alu_sub_borrow_led,// 减法借位标志 LED2
output alu_overflow_led, // 溢出标志 LED3
output alu_zero_led, // 结果为 0 标志 LED4
output [5:0] bit_select, // 数码管位选(低电平选中)
output [7:0] seg_select // 数码管段选(低电平点亮)
);
// 来自输入模块的功能码与两个操作数
wire [4:0] alu_func;
wire alu_func_vld;
wire [31:0] alu_src0;
wire alu_src0_vld;
wire [31:0] alu_src1;
wire alu_src1_vld;
// 来自 ALU 的运算结果及标志位
wire [31:0] alu_rslt;
wire alu_rslt_vld;
wire alu_add_carry;
wire alu_sub_borrow;
wire alu_overflow;
wire alu_zero;
// 锁存后的结果与标志位(按下 start_key 后更新)
reg [31:0] alu_rslt_latch;
reg alu_rslt_vld_latch;
reg alu_add_carry_latch;
reg alu_sub_borrow_latch;
reg alu_overflow_latch;
reg alu_zero_latch;
// start_key 的两级打拍寄存器,用于做边沿检测
reg start_key_d0;
reg start_key_d1;
wire start_pulse; // start_key 从高到低的一个脉冲,表示“按下了一次”
assign start_pulse = start_key_d1 & ~start_key_d0;
//==========================================================
// 子模块例化:按键/拨码输入处理
//==========================================================
alu_key_input u_alu_key_input(
.clk (clk),
.rst_n (rst_n),
.sw_in (sw_in),
.alu_func_key (alu_func_key),
.alu_src1_key0 (alu_src1_key0),
.alu_src1_key1 (alu_src1_key1),
.alu_src1_key2 (alu_src1_key2),
.alu_src1_key3 (alu_src1_key3),
.alu_src2_key0 (alu_src2_key0),
.alu_src2_key1 (alu_src2_key1),
.alu_src2_key2 (alu_src2_key2),
.alu_src2_key3 (alu_src2_key3),
.alu_func_o (alu_func),
.alu_func_vld_o (alu_func_vld),
.alu_src0_o (alu_src0),
.alu_src0_vld_o (alu_src0_vld),
.alu_src1_o (alu_src1),
.alu_src1_vld_o (alu_src1_vld)
);
//==========================================================
// 子模块例化:核心 ALU 运算
//==========================================================
riscv_alu u_riscv_alu(
.alu_func_i (alu_func),
.alu_func_vld_i (alu_func_vld),
.alu_src0_i (alu_src0),
.alu_src0_vld_i (alu_src0_vld),
.alu_src1_i (alu_src1),
.alu_src1_vld_i (alu_src1_vld),
.alu_rslt_o (alu_rslt),
.alu_rslt_vld_o (alu_rslt_vld),
.alu_add_carry_o (alu_add_carry),
.alu_sub_borrow_o (alu_sub_borrow),
.alu_overflow_o (alu_overflow),
.alu_zero_o (alu_zero)
);
//==========================================================
// 子模块例化:数码管显示
// 注意:这里给显示模块的是“锁存后的”结果,
// 所以按一次 start_key,显示就更新一次。
//==========================================================
alu_display #(
.SCAN_DIV (SCAN_DIV),
.SHIFT_DIV (SHIFT_DIV)
) u_alu_display(
.clk (clk),
.rst_n (rst_n),
.alu_rslt_i (alu_rslt_latch),
.alu_rslt_vld_i (alu_rslt_vld_latch),
.bit_select (bit_select),
.seg_select (seg_select)
);
//==========================================================
// 主时序逻辑:按下 start_key 后锁存一次 ALU 结果
//==========================================================
// ... 以下代码略,完整源码请下载压缩包查看
代码文件(付费下载)
📥
付费后此处显示完整工程压缩包下载链接。
1、代码文件需要付费后才可见。
2、支付问题请联系微信公众号客服。
3、优质Verilog/VHDL代码资源,所见即所得。
Verilog/VHDL资源下载 » RISC-V ALU 运算器 Verilog Quartus
2、支付问题请联系微信公众号客服。
3、优质Verilog/VHDL代码资源,所见即所得。
Verilog/VHDL资源下载 » RISC-V ALU 运算器 Verilog Quartus