用verilog编写一个简易抽签器设计要实现以下功能:1初始状态显示00000000;开始抽签后每100ms显示1组8位有意义的数字如学号20180101等;所有数字均事先存储在内部存储器中;2设置S2为功能选择键可在抽签开始确认之间轮流切换;抽签开始后所存各组数字以随机方式进行显示每组数字显示时长100ms;抽签确认后已显示的8位数字保持不变并存储到内部存储器中直到下次抽签开始;已抽中的所有数字
以下是简易抽签器的Verilog代码:
module lottery (
input clk, rst, // 时钟和复位信号
input [3:0] sw, // 开关输入
output reg [7:0] num_out // 数字输出
);
// 内部存储器,存储所有数字
reg [7:0] nums [0:9] = {8'h20, 8'h18, 8'h01, 8'h80, 8'h10, 8'h10, 8'h00, 8'h02, 8'h00, 8'h01};
// 状态机状态定义
parameter IDLE = 0, SELECT = 1, CONFIRM = 2, VIEW = 3, MODIFY = 4;
// 状态机变量定义
reg [3:0] state = IDLE;
reg [3:0] view_idx = 0;
reg [3:0] modify_idx = 0;
reg [7:0] modify_num = 0;
// 计数器和随机数生成器
reg [3:0] count = 0;
reg [7:0] rand_num = 0;
// 抽签结果存储器
reg [7:0] selected_nums [0:9];
reg [3:0] selected_count = 0;
always @(posedge clk or posedge rst) begin
if (rst) begin
// 复位状态机和计数器
state <= IDLE;
count <= 0;
num_out <= 8'h00;
end
else begin
case (state)
IDLE: begin
// 初始状态,显示“00000000”
num_out <= 8'h00;
if (sw[0]) begin
// 进入抽签模式,随机生成数字序列
state <= SELECT;
selected_count <= 0;
for (int i = 0; i < 10; i = i + 1) begin
repeat (10) begin
rand_num = nums[$random() % 10];
if (rand_num != selected_nums) break;
end
selected_nums[selected_count] = rand_num;
selected_count = selected_count + 1;
end
count <= 0;
end
else if (sw[1]) begin
// 进入查看模式,显示已抽中的数字序列
state <= VIEW;
view_idx <= 0;
num_out <= selected_nums[view_idx];
end
else if (sw[2]) begin
// 进入修改模式,显示待修改的数字序列
state <= MODIFY;
modify_idx <= 0;
modify_num <= selected_nums[modify_idx];
num_out <= modify_num;
end
end
SELECT: begin
// 抽签模式
if (count < 10) begin
// 显示当前数字
num_out <= selected_nums[count];
count <= count + 1;
end
else begin
// 进入确认模式
state <= CONFIRM;
count <= 0;
num_out <= selected_nums[selected_count-1];
end
end
CONFIRM: begin
// 确认模式
if (sw[0]) begin
// 再次进入抽签模式
state <= SELECT;
for (int i = 0; i < 10; i = i + 1) begin
repeat (10) begin
rand_num = nums[$random() % 10];
if (rand_num != selected_nums) break;
end
selected_nums[selected_count] = rand_num;
selected_count = selected_count + 1;
end
count <= 0;
end
else if (sw[1]) begin
// 进入查看模式
state <= VIEW;
view_idx <= 0;
num_out <= selected_nums[view_idx];
end
else if (sw[2]) begin
// 进入修改模式
state <= MODIFY;
modify_idx <= 0;
modify_num <= selected_nums[modify_idx];
num_out <= modify_num;
end
end
VIEW: begin
// 查看模式
if (sw[0]) begin
// 向前翻页
if (view_idx > 0) view_idx <= view_idx - 1;
num_out <= selected_nums[view_idx];
end
else if (sw[1]) begin
// 向后翻页
if (view_idx < selected_count - 1) view_idx <= view_idx + 1;
num_out <= selected_nums[view_idx];
end
else if (sw[2]) begin
// 返回初始状态
state <= IDLE;
count <= 0;
num_out <= 8'h00;
end
end
MODIFY: begin
// 修改模式
if (sw[0]) begin
// 选择上一个数字进行修改
if (modify_idx > 0) modify_idx <= modify_idx - 1;
modify_num <= selected_nums[modify_idx];
num_out <= modify_num;
end
else if (sw[1]) begin
// 选择下一个数字进行修改
if (modify_idx < selected_count - 1) modify_idx <= modify_idx + 1;
modify_num <= selected_nums[modify_idx];
num_out <= modify_num;
end
else if (sw[2]) begin
// 确认修改结果
state <= VIEW;
selected_nums[modify_idx] <= modify_num;
view_idx <= modify_idx;
num_out <= selected_nums[view_idx];
end
else if (sw[3]) begin
// 修改数字
if (sw[1]) begin
// 加1
if (modify_num < 8'h09) modify_num <= modify_num + 1;
end
else if (sw[2]) begin
// 减1
if (modify_num > 8'h00) modify_num <= modify_num - 1;
end
num_out <= modify_num;
end
end
endcase
end
end
endmodule
``
原文地址: https://www.cveoy.top/t/topic/cqFE 著作权归作者所有。请勿转载和采集!