data/full_repos/permissive/46276558/fpga/nexys4/rtl/psramcon.v
data/verilator_xmls/ee04fa52-e315-4e2e-a0b7-c89c6ba628f0.xml
module psramcon (

                     az_addr,
                     az_be_n,
                     az_cs,
                     az_data,
                     az_rd_n,
                     az_wr_n,
                     clk,
                     reset,


                     za_data,
                     za_valid,
                     za_waitrequest,

                     PSRAM_CLK,
                     PSRAM_ADV_N,
                     PSRAM_CE_N,
                     PSRAM_OE_N,
                     PSRAM_WE_N,
                     PSRAM_LB_N,
                     PSRAM_UB_N,
                     PSRAM_DATA,
                     PSRAM_ADDR
                     );

    output  [ 31: 0] za_data;
    output           za_valid;
    output           za_waitrequest;

    input [ 24: 0]   az_addr;
    input [  3: 0]   az_be_n;
    input            az_cs;
    input [ 31: 0]   az_data;
    input            az_rd_n;
    input            az_wr_n;
    input            clk;
    input            reset;

    output wire      PSRAM_CLK;
    output wire      PSRAM_ADV_N;
    output wire      PSRAM_CE_N;
    output wire      PSRAM_OE_N;
    output wire      PSRAM_WE_N;
    output wire      PSRAM_LB_N;
    output wire      PSRAM_UB_N;
    inout wire [15:0] PSRAM_DATA;
    output wire [22:0] PSRAM_ADDR;

    reg [21:0]         addr_buf;
    reg [31:0]         din_buf;
    reg [3:0]          be_buf;

    reg [22:0]         addr_16;
    reg [15:0]         din_16;
    reg [1:0]          be_16;
    reg                we_16, re_16;
    wire [15:0]        dout_16;
    wire               d_valid_16;
    wire               busy_16;


    wire               CLK = clk;
    wire               RST_X = ~reset;
    wire [21:0]        ADDR = az_addr[21:0];
    wire [31:0]        DIN = az_data;
    wire               WE = ~az_wr_n;
    wire               RE = ~az_rd_n;
    wire [3:0]         BE = ~az_be_n;
    wire               WAITREQUEST;
    reg [31:0]         DOUT;
    reg                DVALID;
    assign za_waitrequest = WAITREQUEST;
    assign za_data = DOUT;
    assign za_valid = DVALID;


    psramcon_16 psramcon_16(CLK, RST_X, addr_16, addr_16, din_16, we_16, re_16, 2'b11, busy_16, dout_16, d_valid_16,
                         PSRAM_CLK, PSRAM_ADV_N, PSRAM_CE_N, PSRAM_OE_N, PSRAM_WE_N, PSRAM_LB_N, PSRAM_UB_N, PSRAM_DATA, PSRAM_ADDR);

    reg [3:0]          state;
    parameter IDLE      = 0;
    parameter W_PHASE0  = 1;
    parameter W_PHASE01 = 2;
    parameter W_PHASE1  = 3;
    parameter W_PHASE11 = 4;
    parameter W_PHASE2  = 5;
    parameter R_PHASE0  = 6;
    parameter R_PHASE1  = 7;
    parameter R_PHASE2  = 8;

    assign WAITREQUEST = (state != IDLE);

    always @(posedge CLK) begin
        if(!RST_X) begin
            state   <= IDLE;
            addr_16 <= 0;
            din_16  <= 0;
            be_16   <= 2'b11;
            we_16   <= 0;
            re_16   <= 0;
        end else begin
            case(state)
              IDLE: begin
                  DOUT    <= 0;
                  DVALID  <= 0;

                  state    <= (WE) ? W_PHASE0 : (RE) ? R_PHASE0 : IDLE;
                  addr_buf <= ADDR;
                  din_buf  <= DIN;
                  be_buf   <= BE;
              end
              W_PHASE0: begin
                  if(be_buf[1:0] == 2'b11) begin
                      state   <= W_PHASE1;
                      addr_16 <= {addr_buf, 1'b0};
                      din_16  <= din_buf[15:0];
                      we_16   <= 1;
                  end else begin
                      state   <= W_PHASE01;
                      addr_16 <= {addr_buf, 1'b0};
                      re_16   <= 1;
                  end
              end
              W_PHASE01: begin
                  if(busy_16) begin re_16 <= 0; end
                  else if(d_valid_16) begin
                      state <= W_PHASE1;
                      addr_16 <= {addr_buf, 1'b0};
                      din_16[7:0]  <= (be_buf[0]) ? din_buf[7:0] : dout_16[7:0];
                      din_16[15:8] <= (be_buf[1]) ? din_buf[15:8] : dout_16[15:8];
                      we_16 <= 1;
                  end
              end
              W_PHASE1: begin
                  if(busy_16) begin we_16 <= 0; end
                  else if(be_buf[3:2] == 2'b11) begin
                      state   <= W_PHASE2;
                      addr_16 <= {addr_buf, 1'b1};
                      din_16  <= din_buf[31:16];
                      we_16   <= 1;
                  end else begin
                      state   <= W_PHASE11;
                      addr_16 <= {addr_buf, 1'b1};
                      re_16   <= 1;
                  end
              end
              W_PHASE11: begin
                  if(busy_16) begin re_16 <= 0; end
                  else if(d_valid_16) begin
                      state <= W_PHASE2;
                      addr_16 <= {addr_buf, 1'b1};
                      din_16[7:0]  <= (be_buf[2]) ? din_buf[23:16] : dout_16[7:0];
                      din_16[15:8] <= (be_buf[3]) ? din_buf[31:24] : dout_16[15:8];
                      we_16 <= 1;
                  end
              end
              W_PHASE2: begin
                  if(busy_16) begin we_16 <= 0; end
                  else begin
                      state   <= IDLE;
                      addr_16 <= 0;
                      din_16  <= 0;
                      we_16   <= 0;
                  end
              end
              R_PHASE0: begin
                  state   <= R_PHASE1;
                  addr_16 <= {addr_buf, 1'b0};
                  re_16   <= 1;
              end
              R_PHASE1: begin
                  if(busy_16) begin re_16 <= 0; end
                  else if(d_valid_16) begin
                      state       <= R_PHASE2;
                      addr_16     <= {addr_buf, 1'b1};
                      re_16       <= 1;
                      DOUT[15:0] <= dout_16;
                  end
              end
              R_PHASE2: begin
                  if(busy_16) begin we_16 <= 0; end
                  else if(d_valid_16) begin
                      state        <= IDLE;
                      addr_16      <= 0;
                      re_16        <= 0;
                      DOUT[31:16] <= dout_16;
                      DVALID      <= 1;
                  end
              end
            endcase
        end
    end

endmodule
module psramcon (

                     az_addr,
                     az_be_n,
                     az_cs,
                     az_data,
                     az_rd_n,
                     az_wr_n,
                     clk,
                     reset,


                     za_data,
                     za_valid,
                     za_waitrequest,

                     PSRAM_CLK,
                     PSRAM_ADV_N,
                     PSRAM_CE_N,
                     PSRAM_OE_N,
                     PSRAM_WE_N,
                     PSRAM_LB_N,
                     PSRAM_UB_N,
                     PSRAM_DATA,
                     PSRAM_ADDR
                     );


    output  [ 31: 0] za_data;
    output           za_valid;
    output           za_waitrequest;

    input [ 24: 0]   az_addr;
    input [  3: 0]   az_be_n;
    input            az_cs;
    input [ 31: 0]   az_data;
    input            az_rd_n;
    input            az_wr_n;
    input            clk;
    input            reset;

    output wire      PSRAM_CLK;
    output wire      PSRAM_ADV_N;
    output wire      PSRAM_CE_N;
    output wire      PSRAM_OE_N;
    output wire      PSRAM_WE_N;
    output wire      PSRAM_LB_N;
    output wire      PSRAM_UB_N;
    inout wire [15:0] PSRAM_DATA;
    output wire [22:0] PSRAM_ADDR;

    reg [21:0]         addr_buf;
    reg [31:0]         din_buf;
    reg [3:0]          be_buf;

    reg [22:0]         addr_16;
    reg [15:0]         din_16;
    reg [1:0]          be_16;
    reg                we_16, re_16;
    wire [15:0]        dout_16;
    wire               d_valid_16;
    wire               busy_16;


    wire               CLK = clk;
    wire               RST_X = ~reset;
    wire [21:0]        ADDR = az_addr[21:0];
    wire [31:0]        DIN = az_data;
    wire               WE = ~az_wr_n;
    wire               RE = ~az_rd_n;
    wire [3:0]         BE = ~az_be_n;
    wire               WAITREQUEST;
    reg [31:0]         DOUT;
    reg                DVALID;
    assign za_waitrequest = WAITREQUEST;
    assign za_data = DOUT;
    assign za_valid = DVALID;


    psramcon_16 psramcon_16(CLK, RST_X, addr_16, addr_16, din_16, we_16, re_16, 2'b11, busy_16, dout_16, d_valid_16,
                         PSRAM_CLK, PSRAM_ADV_N, PSRAM_CE_N, PSRAM_OE_N, PSRAM_WE_N, PSRAM_LB_N, PSRAM_UB_N, PSRAM_DATA, PSRAM_ADDR);

    reg [3:0]          state;
    parameter IDLE      = 0;
    parameter W_PHASE0  = 1;
    parameter W_PHASE01 = 2;
    parameter W_PHASE1  = 3;
    parameter W_PHASE11 = 4;
    parameter W_PHASE2  = 5;
    parameter R_PHASE0  = 6;
    parameter R_PHASE1  = 7;
    parameter R_PHASE2  = 8;

    assign WAITREQUEST = (state != IDLE);

    always @(posedge CLK) begin
        if(!RST_X) begin
            state   <= IDLE;
            addr_16 <= 0;
            din_16  <= 0;
            be_16   <= 2'b11;
            we_16   <= 0;
            re_16   <= 0;
        end else begin
            case(state)
              IDLE: begin
                  DOUT    <= 0;
                  DVALID  <= 0;

                  state    <= (WE) ? W_PHASE0 : (RE) ? R_PHASE0 : IDLE;
                  addr_buf <= ADDR;
                  din_buf  <= DIN;
                  be_buf   <= BE;
              end
              W_PHASE0: begin
                  if(be_buf[1:0] == 2'b11) begin
                      state   <= W_PHASE1;
                      addr_16 <= {addr_buf, 1'b0};
                      din_16  <= din_buf[15:0];
                      we_16   <= 1;
                  end else begin
                      state   <= W_PHASE01;
                      addr_16 <= {addr_buf, 1'b0};
                      re_16   <= 1;
                  end
              end
              W_PHASE01: begin
                  if(busy_16) begin re_16 <= 0; end
                  else if(d_valid_16) begin
                      state <= W_PHASE1;
                      addr_16 <= {addr_buf, 1'b0};
                      din_16[7:0]  <= (be_buf[0]) ? din_buf[7:0] : dout_16[7:0];
                      din_16[15:8] <= (be_buf[1]) ? din_buf[15:8] : dout_16[15:8];
                      we_16 <= 1;
                  end
              end
              W_PHASE1: begin
                  if(busy_16) begin we_16 <= 0; end
                  else if(be_buf[3:2] == 2'b11) begin
                      state   <= W_PHASE2;
                      addr_16 <= {addr_buf, 1'b1};
                      din_16  <= din_buf[31:16];
                      we_16   <= 1;
                  end else begin
                      state   <= W_PHASE11;
                      addr_16 <= {addr_buf, 1'b1};
                      re_16   <= 1;
                  end
              end
              W_PHASE11: begin
                  if(busy_16) begin re_16 <= 0; end
                  else if(d_valid_16) begin
                      state <= W_PHASE2;
                      addr_16 <= {addr_buf, 1'b1};
                      din_16[7:0]  <= (be_buf[2]) ? din_buf[23:16] : dout_16[7:0];
                      din_16[15:8] <= (be_buf[3]) ? din_buf[31:24] : dout_16[15:8];
                      we_16 <= 1;
                  end
              end
              W_PHASE2: begin
                  if(busy_16) begin we_16 <= 0; end
                  else begin
                      state   <= IDLE;
                      addr_16 <= 0;
                      din_16  <= 0;
                      we_16   <= 0;
                  end
              end
              R_PHASE0: begin
                  state   <= R_PHASE1;
                  addr_16 <= {addr_buf, 1'b0};
                  re_16   <= 1;
              end
              R_PHASE1: begin
                  if(busy_16) begin re_16 <= 0; end
                  else if(d_valid_16) begin
                      state       <= R_PHASE2;
                      addr_16     <= {addr_buf, 1'b1};
                      re_16       <= 1;
                      DOUT[15:0] <= dout_16;
                  end
              end
              R_PHASE2: begin
                  if(busy_16) begin we_16 <= 0; end
                  else if(d_valid_16) begin
                      state        <= IDLE;
                      addr_16      <= 0;
                      re_16        <= 0;
                      DOUT[31:16] <= dout_16;
                      DVALID      <= 1;
                  end
              end
            endcase
        end
    end

endmodule