module LED_matrix (
    input wire clk,
    input wire rst_n,
   
    output reg matrix,
	 // 调试仿真
    output reg [5:0] cur_state,
    output reg [5:0] next_state,

    output reg [15:0] cnt
);

// parameter [23:0] data = 24'h33_99_FF;
reg [23:0] data;
parameter [15:0] interval_frame = 300*50;
// 如果为60，低电平的时长会增加40ns, 这是由于跳出SEND 状态后，到达其他状态，会给低电平增加额外的周期，故这里减2
parameter [5:0] period = 60 - 2;
parameter [5:0] T0H = 15;
parameter [5:0] T0L = 45;
parameter [5:0] T1H = 30;
parameter [5:0] T1L = 30;

// 状态
parameter [5:0] IDLE    = 5'b000010;
parameter [5:0] CHOOSE  = 5'b000100;
parameter [5:0] SEND1   = 5'b001000;
parameter [5:0] SEND0   = 5'b010000;
parameter [5:0] STOP    = 5'b100000;
parameter [5:0] DELAY   = 5'b000001;
// 变量
wire start;
assign start = 1'b1;

wire reach_60;
assign reach_60 = (cnt == period - 5'b1);
wire reach_300us;
assign reach_300us = (cnt == interval_frame - 16'd1);
reg [4:0] bit_index;
reg [4:0] cnt_bit;
reg [6:0] cnt_LED;
// 第一段
always @(posedge clk or negedge rst_n) begin
    if (!rst_n) begin
        cur_state <= DELAY;
    end
    else begin
        cur_state <= next_state;
    end
end
// 第二段
always @(*) begin
    if (!rst_n) begin
        next_state <= DELAY;
    end
    else begin
        case(cur_state)
            IDLE    :begin
                if(start == 1'b0)
                    next_state <= cur_state;
                else if(cnt_LED == 7'd64)
                    next_state <= DELAY;
                else
                    next_state <= CHOOSE;
            end
            CHOOSE  :begin
                if( ((data >> (bit_index)) & 24'd1) == 1 )
                    next_state <= SEND1;
                else
                    next_state <= SEND0;
            end
            SEND1   :begin
                if(reach_60)
                    next_state <= STOP;
                else
                    next_state <= cur_state;
            end
            SEND0   :begin
                if(reach_60)
                    next_state <= STOP;
                else
                    next_state <= cur_state;                
            end
            STOP    :begin
                if(cnt_bit >= 24)
                    next_state <= IDLE;
                else
                    next_state <= CHOOSE;
				end
            DELAY   :begin
                if(reach_300us)
                    next_state <= IDLE;
                else
                    next_state <= DELAY;
            end
           default:next_state <= DELAY;
        endcase
    end
end
// 第三段
always @(posedge clk or negedge rst_n) begin
    if (!rst_n) begin
        matrix      <= 0;
        cnt         <= 0;
        bit_index   <= 5'd23;
        cnt_bit     <= 0;
        cnt_LED     <= 0;
    end
    else begin
        case(cur_state)
            IDLE    :begin
                matrix      <= 0;
                cnt         <= 0;
                bit_index   <= 5'd23;
                cnt_bit     <= 0;
                cnt_LED     <= cnt_LED + 1'b1;           
            end
            CHOOSE  :begin
                matrix      <= 0;
                cnt         <= 0;
                // bit_index   <= 5'b1;
                // cnt_bit     <= 0;                
            end
            SEND1   :begin
                if(reach_60)begin
                    cnt <= 0;
                    cnt_bit <= cnt_bit + 1'b1;
                    bit_index <= bit_index - 1'b1;
                end
                else
                    cnt <= cnt + 1'b1;

                if(cnt <= (T1H - 1'b1))
                    matrix <= 1'b1;
                else
                    matrix <= 1'b0;
            end
            SEND0   :begin
                if(reach_60)begin
                    cnt <= 0;
                    cnt_bit <= cnt_bit + 1'b1;
                    bit_index <= bit_index - 1'b1;
                end
                else
                    cnt <= cnt + 1'b1;

                if(cnt <= (T0H - 1'b1))
                    matrix <= 1'b1;
                else
                    matrix <= 1'b0;                
            end
            STOP    :begin
                matrix      <= 0;
                cnt         <= 0;  
                // bit_index   <= 5'd23;
                // cnt_bit     <= 0;                
            end
            DELAY   :begin
                if(reach_300us)
                    cnt <= 0;
                else
                    cnt <= cnt + 1'b1;
                matrix      <= 0;
                cnt_LED     <= 0;
            end
            default:begin
                matrix      <= 0;
                cnt         <= 0;
                bit_index   <= 5'd23;
                cnt_bit     <= 0; 
                cnt_LED     <= 0;
            end
        endcase
    end
end
// 读入像素值
always @(*) begin
    if (!rst_n) begin
        data <= led_matrix_flat[0];
    end
    else begin
       data <= led_matrix_flat[cnt_LED - 1];
    end
end
// always @(posedge clk or negedge rst_n) begin
//     if (!rst_n) begin
        
//     end
//     else begin
        
//     end
// end

// 图片数据
parameter [23:0] YELLOW = 24'h04_04_00;
parameter [23:0] BLACK = 24'h12_09_12;// 改了
parameter [23:0] WHITE = 24'h02_02_02;
parameter [23:0] RED = 24'h00_02_00;
reg [23:0] led_matrix_flat [63:0];

always @(*) begin
    // 第 0 行
    led_matrix_flat[0*8 + 0] <= WHITE;
    led_matrix_flat[0*8 + 1] <= YELLOW;
    led_matrix_flat[0*8 + 2] <= YELLOW;
    led_matrix_flat[0*8 + 3] <= YELLOW;
    led_matrix_flat[0*8 + 4] <= YELLOW;
    led_matrix_flat[0*8 + 5] <= YELLOW;
    led_matrix_flat[0*8 + 6] <= YELLOW;
    led_matrix_flat[0*8 + 7] <= WHITE;

    // 第 1 行
    led_matrix_flat[1*8 + 0] <= YELLOW;
    led_matrix_flat[1*8 + 1] <= YELLOW;
    led_matrix_flat[1*8 + 2] <= YELLOW;
    led_matrix_flat[1*8 + 3] <= YELLOW;
    led_matrix_flat[1*8 + 4] <= YELLOW;
    led_matrix_flat[1*8 + 5] <= YELLOW;
    led_matrix_flat[1*8 + 6] <= YELLOW;
    led_matrix_flat[1*8 + 7] <= YELLOW;

    // 第 2 行
    led_matrix_flat[2*8 + 0] <= YELLOW;
    led_matrix_flat[2*8 + 1] <= BLACK;
    led_matrix_flat[2*8 + 2] <= BLACK;
    led_matrix_flat[2*8 + 3] <= YELLOW;
    led_matrix_flat[2*8 + 4] <= YELLOW;
    led_matrix_flat[2*8 + 5] <= BLACK;
    led_matrix_flat[2*8 + 6] <= BLACK;
    led_matrix_flat[2*8 + 7] <= YELLOW;

    // 第 3 行
    led_matrix_flat[3*8 + 0] <= YELLOW;
    led_matrix_flat[3*8 + 1] <= BLACK;
    led_matrix_flat[3*8 + 2] <= BLACK; // 左眼
    led_matrix_flat[3*8 + 3] <= YELLOW;
    led_matrix_flat[3*8 + 4] <= YELLOW;
    led_matrix_flat[3*8 + 5] <= BLACK; // 右眼
    led_matrix_flat[3*8 + 6] <= BLACK;
    led_matrix_flat[3*8 + 7] <= YELLOW;

    // 第 4 行
    led_matrix_flat[4*8 + 0] <= YELLOW;
    led_matrix_flat[4*8 + 1] <= YELLOW;
    led_matrix_flat[4*8 + 2] <= YELLOW;
    led_matrix_flat[4*8 + 3] <= YELLOW;
    led_matrix_flat[4*8 + 4] <= YELLOW;
    led_matrix_flat[4*8 + 5] <= YELLOW;
    led_matrix_flat[4*8 + 6] <= YELLOW;
    led_matrix_flat[4*8 + 7] <= YELLOW;

    // 第 5 行
    led_matrix_flat[5*8 + 0] <= YELLOW;
    led_matrix_flat[5*8 + 1] <= BLACK;
    led_matrix_flat[5*8 + 2] <= YELLOW;
    led_matrix_flat[5*8 + 3] <= YELLOW;
    led_matrix_flat[5*8 + 4] <= YELLOW;
    led_matrix_flat[5*8 + 5] <= YELLOW;
    led_matrix_flat[5*8 + 6] <= BLACK;
    led_matrix_flat[5*8 + 7] <= YELLOW;

    // 第 6 行
    led_matrix_flat[6*8 + 0] <= YELLOW;
    led_matrix_flat[6*8 + 1] <= YELLOW;
    led_matrix_flat[6*8 + 2] <= BLACK;
    led_matrix_flat[6*8 + 3] <= BLACK;
    led_matrix_flat[6*8 + 4] <= BLACK;
    led_matrix_flat[6*8 + 5] <= BLACK;
    led_matrix_flat[6*8 + 6] <= RED;
    led_matrix_flat[6*8 + 7] <= YELLOW;

    // 第 7 行（嘴巴）
    led_matrix_flat[7*8 + 0] <= WHITE;
    led_matrix_flat[7*8 + 1] <= YELLOW;
    led_matrix_flat[7*8 + 2] <= YELLOW;
    led_matrix_flat[7*8 + 3] <= YELLOW;
    led_matrix_flat[7*8 + 4] <= YELLOW;
    led_matrix_flat[7*8 + 5] <= RED;
    led_matrix_flat[7*8 + 6] <= RED;
    led_matrix_flat[7*8 + 7] <= WHITE;
end

endmodule