以下是简易抽签器的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
``
用verilog编写一个简易抽签器设计要实现以下功能:1初始状态显示00000000;开始抽签后每100ms显示1组8位有意义的数字如学号20180101等;所有数字均事先存储在内部存储器中;2设置S2为功能选择键可在抽签开始确认之间轮流切换;抽签开始后所存各组数字以随机方式进行显示每组数字显示时长100ms;抽签确认后已显示的8位数字保持不变并存储到内部存储器中直到下次抽签开始;已抽中的所有数字

原文地址: https://www.cveoy.top/t/topic/cqFE 著作权归作者所有。请勿转载和采集!

免费AI点我,无需注册和登录