module tube_ctl (
    input wire clk,
    input wire rst_n,
    input wire  [47:0] num_display,

    output reg [5:0] SEL,
    output reg [7:0] DIG
);

// 解包
wire [7:0] numbers[5:0];
assign numbers[0] = num_display[7:0];
assign numbers[1] = num_display[15:8];
assign numbers[2] = num_display[23:16];
assign numbers[3] = num_display[31:24];
assign numbers[4] = num_display[39:32];
assign numbers[5] = num_display[47:40];
/********************************状态机写法*******************************/
parameter [5:0] s1 = 6'b000_001;
parameter [5:0] s2 = 6'b000_010;
parameter [5:0] s3 = 6'b000_100;
parameter [5:0] s4 = 6'b001_000;
parameter [5:0] s5 = 6'b010_000;
parameter [5:0] s6 = 6'b100_000;
reg [5:0] cur_state;
reg [5:0] next_state;

 // 第一段
 always @(posedge clk or negedge rst_n) begin
     if(!rst_n)begin
         cur_state <= s1;
     end
     else begin
         cur_state <= next_state;
     end
 end
// 第二段
// 计时
reg [15:0] cnt;
wire [15:0] reach_1ms;
assign reach_1ms = (16'd50_000 - 16'b1 == cnt);
always @(posedge clk or negedge rst_n) begin
    if(!rst_n)begin
        cnt <= 16'b0;
    end
    else if(reach_1ms)begin
        cnt <= 16'b0;
    end
    else begin
        cnt <= cnt + 16'b1;
    end
end
// 状态转移
always @(*) begin
    if(!rst_n)begin
        next_state <= s1;
    end
    else begin
        case (cur_state)
            s1:begin
                if(reach_1ms)
                    next_state <= s2;
                else
                    next_state <= cur_state;
                end
            s2:begin
                if(reach_1ms)
                    next_state <= s3;
                else
                    next_state <= cur_state;
                end
            s3:begin
                if(reach_1ms)
                    next_state <= s4;
                else
                    next_state <= cur_state;
                end
            s4:begin
                if(reach_1ms)
                    next_state <= s5;
                else
                    next_state <= cur_state;
                end
            s5:begin
                if(reach_1ms)
                    next_state <= s6;
                else
                    next_state <= cur_state;
                end
            s6:begin
                if(reach_1ms)
                    next_state <= s1;
                else
                    next_state <= cur_state;
                end  
            default:next_state <= s1;
        endcase
    end
end
// 第三段
always @(*) begin
    if(!rst_n)begin
        SEL <= 6'b111_111;
        DIG <= 8'h0;
    end
    else begin
        case (cur_state)
            s1:begin
                SEL <= 6'b011111;
                DIG <= numbers[0];
            end
            s2:begin
                SEL <= 6'b101111;
                DIG <= numbers[1];
            end
            s3:begin
                SEL <= 6'b110111;
                DIG <= numbers[2];
            end
            s4:begin
                SEL <= 6'b111011;
                DIG <= numbers[3];
            end
            s5:begin
                SEL <= 6'b111101;
                DIG <= numbers[4];
            end
            s6:begin
                SEL <= 6'b111110;
                DIG <= numbers[5];
            end
        endcase
    end
end
// always @(*) begin
//     SEL <= 6'b110_011;
//     DIG <= 8'h0;    
// end
// /********************************普通写法*******************************/
// // 计时
// reg [15:0] cnt;
// wire [15:0] reach_1ms;
// assign reach_1ms = (16'd50_000 - 16'b1 == cnt);
// always @(posedge clk or negedge rst_n) begin
//     if(!rst_n)begin
//         cnt <= 16'b0;
//     end
//     else if(reach_1ms)begin
//         cnt <= 16'b0;
//     end
//     else begin
//         cnt <= cnt + 16'b1;
//     end
// end
// // 同步DIG 和 SEL
// reg [3:0] index;
// always @(posedge clk or negedge rst_n) begin
//     if(!rst_n)begin
//         index <= 4'b0;
//     end
//     else if(reach_1ms)begin
//         if (index == 4'd5)
//             index <= 4'b0;
//         else
//             index <= index + 4'b1;
//     end    
// end
// // 输出
// always @(posedge clk or negedge rst_n) begin
//     if(!rst_n)begin
//         SEL <= 6'b111_111;
//         DIG <= 8'hff;
//     end
//     else begin
//         case (index)
//             4'd0: SEL = 6'b011_111;
//             4'd1: SEL = 6'b101_111;
//             4'd2: SEL = 6'b110_111;
//             4'd3: SEL = 6'b111_011;
//             4'd4: SEL = 6'b111_101;
//             4'd5: SEL = 6'b111_110;
//             default: SEL = 6'b111_111;
//         endcase
//         DIG <= numbers[index];
//     end
// end
endmodule