// ============================================================================
// universal_constructor.v - 通用构造器框架
// von Neumann式自复制：构造器+复制器+描述带+控制器
// ============================================================================
module universal_constructor #(
    parameter TAPE_W    = 256,      // 描述带位宽
    parameter GRID_W    = 32,       // 构造空间宽度
    parameter GRID_H    = 32,       // 构造空间高度
    parameter STATE_W   = 3         // 每元胞状态位宽
)(
    input  wire                  clk,
    input  wire                  rst_n,
    input  wire                  start,
    input  wire [TAPE_W-1:0]     tape_in,      // 初始描述带
    output wire [TAPE_W-1:0]     tape_out,     // 复制后的描述带
    output wire [GRID_W*GRID_H*STATE_W-1:0] grid, // 构造结果
    output wire [2:0]            phase,        // 当前阶段
    output wire                  done
);

    // ---- 阶段定义 ----
    localparam PH_COPY    = 3'd0;   // 复制描述带
    localparam PH_CONSTR  = 3'd1;   // 根据描述带构造
    localparam PH_ASSEMBLE = 3'd2;  // 组装新机器
    localparam PH_DONE    = 3'd3;   // 完成

    reg [2:0] phase_reg;
    reg [TAPE_W-1:0] tape_reg;
    reg [8:0] tape_ptr;
    reg [GRID_W*GRID_H*STATE_W-1:0] grid_reg;
    reg done_reg;

    // ---- 构造空间 ----
    reg [7:0] cursor_x, cursor_y;

    // ---- 描述带解码 ----
    wire [7:0] instruction = tape_reg[7:0];

    always @(posedge clk or negedge rst_n) begin
        if (!rst_n) begin
            phase_reg <= PH_DONE;
            tape_reg  <= {TAPE_W{1'b0}};
            grid_reg  <= {GRID_W*GRID_H*STATE_W{1'b0}};
            done_reg  <= 1'b0;
            tape_ptr  <= 9'd0;
        end else if (start) begin
            phase_reg <= PH_COPY;
            tape_reg  <= tape_in;
            tape_ptr  <= 9'd0;
            done_reg  <= 1'b0;
        end else begin
            case (phase_reg)
                PH_COPY: begin
                    // 复制描述带（移位寄存器复制）
                    if (tape_ptr < TAPE_W / 8) begin
                        tape_ptr <= tape_ptr + 9'd1;
                    end else begin
                        phase_reg <= PH_CONSTR;
                        tape_ptr  <= 9'd0;
                    end
                end
                PH_CONSTR: begin
                    // 逐指令构造
                    case (instruction[7:6])
                        2'b00: begin  // PLACE: 在当前光标位置放置状态
                            grid_reg[cursor_y * GRID_W * STATE_W + cursor_x * STATE_W +: STATE_W]
                                <= instruction[5:3];
                            cursor_x <= cursor_x + 8'd1;
                        end
                        2'b01: begin  // MOVE: 移动光标
                            cursor_x <= cursor_x + instruction[5:3];
                            cursor_y <= cursor_y + instruction[2:0];
                        end
                        2'b10: begin  // NEXT: 下一条指令
                            tape_reg <= tape_reg >> 8;
                        end
                        2'b11: begin  // HALT: 构造完成
                            phase_reg <= PH_DONE;
                            done_reg  <= 1'b1;
                        end
                    endcase
                end
                default: phase_reg <= PH_DONE;
            endcase
        end
    end

    assign tape_out = tape_reg;
    assign grid     = grid_reg;
    assign phase    = phase_reg;
    assign done     = done_reg;

endmodule