Untitled

 avatar
unknown
plain_text
10 months ago
3.3 kB
18
Indexable
`timescale 1ns / 1ps
module padding_16x16_top#(
    parameter IN_W  = 16,
    parameter IN_H  = 16,
    parameter OUT_W = IN_W + 2,  // 18
    parameter OUT_H = IN_H + 2   // 18
)(
    input  wire clk,
    input  wire rst,
    output reg  done,
    output wire [8:0] data_out_mon
);

    // ========= Input RAM =========
    reg  [9:0] addr_in;
    wire [8:0] data_in;
    reg        ena_in;

    bram_take bram_take_inst (
        .clka(clk),
        .ena(ena_in),
        .wea(1'b0),   // always read
        .addra(addr_in),
        .dina(8'd0),
        .douta(data_in)
    );

    // ========= Output RAM =========
    reg  [9:0] addr_out;
    reg  [8:0] data_out;
    reg        ena_out, wea_out;
    wire [8:0] dout_out;

    bram_padding_18x18 bram_padding_inst (
        .clka(clk),
        .ena(ena_out),
        .wea(wea_out),
        .addra(addr_out),
        .dina(data_out),
        .douta(dout_out)
    );

    assign data_out_mon = dout_out;

    // ========= 控制信號 =========
    reg [5:0] x, y;
    reg [9:0] in_cnt;

    reg [1:0] state;
    localparam S_SETADDR = 2'd0,
               S_WAIT    = 2'd1,
               S_WRITE   = 2'd2;

    always @(posedge clk or posedge rst) begin
        if (rst) begin
            x <= 0; 
            y <= 0;
            in_cnt <= 0;
            addr_in <= 0;
            addr_out <= 0;
            ena_in <= 0;
            ena_out <= 0; 
            wea_out <= 0;
            state <= S_SETADDR;
            done <= 0;
        end else if (!done) begin
            case (state)
                // =======================
                S_SETADDR: begin
                    ena_out <= 0;
                    wea_out <= 0;
                    ena_in  <= 1;

                    // **關鍵:每次進來都直接用 in_cnt 設定 addr_in**
                    if (x != 0 && x != OUT_W-1 && y != 0 && y != OUT_H-1)
                        addr_in <= in_cnt;

                    state <= S_WAIT;
                end

                // =======================
                S_WAIT: begin
                    // 讓 data_in 穩定一拍
                    state <= S_WRITE;
                end

                // =======================
                S_WRITE: begin
                    ena_out <= 1;
                    wea_out <= 1;
                    addr_out <= y * OUT_W + x;

                    if (x == 0 || x == OUT_W-1 || y == 0 || y == OUT_H-1) begin
                        data_out <= 8'd0;
                    end else begin
                        data_out <= data_in;
                        // 寫完才加 in_cnt,避免讀兩次同一筆
                        if (in_cnt < IN_W*IN_H-1)
                            in_cnt <= in_cnt + 1;
                    end

                    // 更新座標
                    if (x == OUT_W-1) begin
                        x <= 0;
                        if (y == OUT_H-1)
                            done <= 1;
                        else
                            y <= y + 1;
                    end else begin
                        x <= x + 1;
                    end

                    state <= S_SETADDR;
                end
            endcase
        end
    end

endmodule
Editor is loading...
Leave a Comment