随机数生成系统设计说明
开发环境:QuartusII
编程语言:Verilog
系统名称:基于FPGA的随机数生成器
功能概述
本系统实现了一款运行于FPGA平台的随机数生成装置,能够在1至99的范围内生成不重复的随机数值。用户可通过外部按键控制系统的启动与取数操作,所生成的随机数将实时显示在7段数码管上。系统集成了状态管理、防重复机制及可视化输出功能,适用于抽奖、随机选取等需要公平性保障的应用场景。
核心设计思路
整个系统采用模块化架构,并通过有限状态机(FSM)协调各部分工作流程。其核心原理是利用高频时钟驱动一个循环计数器,在用户触发“取数”动作时捕获当前计数值作为随机结果。为确保每个数字仅出现一次,系统引入双重去重策略:
- 自动跳过机制:计数器模块(counter.v)内部记录已产生的随机数,当计数过程遇到这些值时会自动跳过,避免重复选取。
- 重复检测修正:随机数处理模块(random_num.v)对新生成的数值进行比对检查,若发现与已有数据冲突,则执行加1操作以规避重复。
系统工作状态
系统共定义五个运行状态,由状态控制器统一调度:
- s_idle:空闲状态,等待开始指令
- s_count:计数状态,高速循环计数
- s_random:取随机数状态,响应按键获取当前值
- s_display:显示状态,更新数码管内容
- s_end:结束状态,完成一轮生成任务
系统结构与模块划分
| 模块名称 |
文件名 |
功能描述 |
| 顶层模块 |
top.v |
集成所有子模块,作为系统主控入口 |
| 分频模块 |
div.v |
将输入的50MHz时钟分频为1Hz信号,用于时间基准 |
| 状态控制模块 |
state_ctrl.v |
实现状态转换逻辑,协调各模块协同运行 |
| 计数器模块 |
counter.v |
执行1-99范围内的循环计数,并跳过已使用数值 |
| 随机数模块 |
random_num.v |
存储已生成数据,检测并处理潜在重复情况 |
| 显示模块 |
display.v |
将数值转换为7段数码管可识别的段码信号 |
关键技术特点
- 非重复随机生成:结合预跳过和后校验双重机制,确保最多6个输出互异
- 高内聚低耦合设计:各模块职责清晰,便于后期维护与功能扩展
- 状态机驱动控制:采用有限状态机精确掌控流程切换,提升系统稳定性
- 良好人机交互:通过简单按键实现操作,配合直观的数码管显示反馈
应用领域
该系统可广泛应用于需公正随机性的场合,例如现场抽奖、课堂随机点名、游戏事件触发机制等。同时,也适合作为高校电子类专业中FPGA数字系统设计的教学实例,帮助学生理解状态机、模块化设计与时序控制等关键概念。
工程实现与验证
系统开发过程中完成了完整的工程构建与测试验证流程:
工程文件结构如上所示,包含源码、约束与仿真配置。
程序源文件组织合理,模块独立性强。
编译成功后的综合信息显示无误。
RTL视图展示了各模块间的连接关系与数据流向。
管脚分配已完成,适配目标开发板硬件资源。
Testbench测试平台用于功能仿真验证。
仿真结果展示
整体功能仿真波形,涵盖各个模块响应情况。
分频模块输出稳定,准确产生1Hz时钟。
计数模块按预期在1-99间循环递增。
随机数模块正确记录历史值并防止重复。
状态机模块严格按照设定顺序进行状态迁移。
显示模块正确输出对应段码,支持数码管正常显示。
系统架构图示
┌─────────────┐? ? ?┌─────────────┐? ? ?┌─────────────┐
│? ?分频模块??│────>│ 状态控制模块 │<────│? ?按键输入??│
└─────────────┘? ? ?└─────┬───────┘? ? ?└─────────────┘
? ? ? ? ? ? ? ? ? ? ? ? ?│
? ? ? ? ? ??┌────────────┼────────────┐
? ? ? ? ? ??▼? ? ? ? ? ??▼? ? ? ? ? ??▼
? ? ?┌─────────────┐?┌─────────────┐ ┌─────────────┐
? ? ?│?计数器模块??│─>│ 随机数模块??│─>│? ?显示模块??│
? ? ?└─────────────┘?└─────────────┘ └─────────────┘
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ??│
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ??┌────────┴────────┐
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ??│? ??7段数码管? ??│
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ??└─────────────────┘
以上为系统多层次架构图,从顶层到底层详细呈现了模块连接与信号交互方式。
// 随机数生成模块
module random_num(
input clk, // 50MHz时钟信号
input key_0, // 启动按键,低电平有效
input [2:0] state, // 当前状态输入
input [4:0] repeat_cnt, // 重复次数计数器
input [6:0] count, // 主计数器值
output reg [6:0] data_temp1,
output reg [6:0] data_temp2,
output reg [6:0] data_temp3,
output reg [6:0] data_temp4,
output reg [6:0] data_temp5,
output reg [6:0] data_temp6
);
parameter s_idle = 3'd0;
parameter s_count = 3'd1;
parameter s_random = 3'd2;
parameter s_display = 3'd3;
parameter s_end = 3'd4;
// data_temp1~data_temp6 用于存储六次产生的随机数值,便于后续跳过重复值处理
always @(posedge clk or negedge key_0)
begin
if (key_0 == 0) begin
// 按键复位:所有随机数寄存器清零
data_temp1 <= 7'd0;
data_temp2 <= 7'd0;
data_temp3 <= 7'd0;
data_temp4 <= 7'd0;
data_temp5 <= 7'd0;
data_temp6 <= 7'd0;
end
else if (state == s_random && repeat_cnt == 5'd0) begin
// 第一次随机数生成:直接取当前计数器值
data_temp1 <= count;
end
else if (state == s_random && repeat_cnt == 5'd1) begin
// 第二次随机数生成
if (count == data_temp1) begin
// 若当前计数器值与第一次随机数相同,则加1避免重复
data_temp2 <= count + 6'd1;
end
end
end