data/full_repos/permissive/484553918/rtl/ip/sdram_pnru.v
data/verilator_xmls/4f937db7-3b41-4cf6-93be-b996d4b977de.xml
module sdram_pnru (

    input  wire        sys_clk,
    input  wire        sys_rd,
    input  wire        sys_wr,
    output reg         sys_rdy = 1'b0,
    input  wire        sys_ack,
    input  wire [23:0] sys_ab,
    input  wire [15:0] sys_di,
    output reg  [15:0] sys_do,
    input  wire  [1:0] sys_wmask,
    input              burst_i,


    output wire  [3:0] sdr_n_CS_WE_RAS_CAS,
    output wire  [1:0] sdr_ba,
    output reg  [12:0] sdr_ab,
    input  wire [15:0] sdr_q,
    output wire [15:0] sdr_d,
    output reg         sdr_dq_oe,
    output reg   [1:0] sdr_dqm = 2'b11
  );





  localparam tRP = 3, tMRD = 2, tRCD = 3, tRC = 9, CL = 3;
  `ifdef SYNTHESIS
  localparam INITLEN = 12500 / 5;
  `else
  localparam INITLEN = 3;
  `endif
  localparam RFTIME  =   975 / 5;


  reg [15:0] di;
  reg [23:0] ab;
  reg rd, wr, ack;
  always @(posedge sys_clk) begin
    di <= sys_di;
    ab <= sys_ab;
    rd <= sys_rd;
    wr <= sys_wr;
    ack <= sys_ack;
  end

  

  assign sdr_n_CS_WE_RAS_CAS = sdr_cmd;
  assign sdr_ba = (state==CONFIG) ? 2'b00 : ab[10:9];
  assign sdr_d = di;
  assign sdr_dq_oe = (state==RWRDY && wr);


  localparam IDLE = 0, RFRSH1 = 1, RFRSH2 = 2, CONFIG = 3, RDWR = 4, RWRDY = 5, ACKWT = 6, WAIT = 7;

  reg  [3:0] sdr_cmd;
  reg  [2:0] state   = IDLE;
  reg  [2:0] next;
  reg [15:0] ctr     = 0;
  reg  [6:0] dly;
  reg  [3:0] open;
  reg [12:0] opnrow[0:3];
  reg bursting;
  reg  [7:0] burst_count;
  

  reg         init = 1'b1;
  wire  [8:0] col  = ab[8:0];
  wire [12:0] row  = ab[23:11];
  wire  [1:0] ba   = ab[10:9];
  

  localparam NOP  = 4'b1000, PRECHRG = 4'b0001, AUTORFRSH = 4'b0100, MODESET = 4'b0000,
             READ = 4'b0110, WRITE   = 4'b0010, ACTIVATE  = 4'b0101, BURST_STOP = 4'b0011;


  localparam MODE = 13'b000_1_00_011_0_111;
  
  always @(posedge sys_clk)
  begin
    ctr <= ctr + 1;
    dly <= dly - 1;
    

    sdr_cmd <= NOP;
    state   <= WAIT;

    case (state)
    
      IDLE:   if (init) state <= (ctr==INITLEN) ? RFRSH1 : IDLE;
              else begin
                sys_rdy <= 1'b0;
                if (ctr>=RFTIME) state <= RFRSH1;
                else if (rd|wr) begin
                  state <= RDWR;
                  sdr_dqm <= rd ? 2'b00 : ~sys_wmask;
                  bursting <= burst_i;
                end else begin
                  sys_rdy <= 1'b1;
                  state <= IDLE;
                end
                burst_count <= 0;
              end

      RFRSH1: begin
                sdr_cmd    <= PRECHRG;
                sdr_ab[10] <= 1'b1;
                open       <= 4'b000;
                dly <= tRP-2; next <= (init) ? CONFIG : RFRSH2;
              end

      RFRSH2: begin
                sdr_cmd <= AUTORFRSH;
                init <= 1'b0;
                ctr     <= 0;
                dly <= tRC-2; next <= (init) ? RFRSH2 : IDLE;
              end

      CONFIG: begin
                sdr_cmd <= MODESET;
                sdr_ab  <= MODE;
                dly <= tMRD-2; next <= RFRSH2;
              end

      RDWR:   begin
                if (!open[ba]) begin
                  sdr_cmd <= ACTIVATE;
                  sdr_ab  <= row;
                  open[ba]   <= 1'b1;
                  opnrow[ba] <= row;
                  dly <= tRCD-2; next <= RDWR;
                  end
                else if (opnrow[ba]!=row) begin
                  sdr_cmd      <= PRECHRG;
                  sdr_ab[10]   <= 1'b0;
                  open[ba] <= 1'b0;
                  dly <= tRP-2; next <= RDWR;
                  end
                else begin
                  sdr_cmd <= (rd) ? READ : WRITE;
                  sdr_ab  <= {4'b0000, col};
                  dly <= CL-1; next <= RWRDY;
                  if (wr) state <= RWRDY;
                  end
              end
      
      RWRDY:  begin
                sys_rdy <= 1'b1;
                if (rd) sys_do  <= sdr_q;
                if (wr) sdr_cmd <= BURST_STOP;
                if (bursting) begin

                  if (burst_count == 64 - CL) begin
                    sdr_cmd <= BURST_STOP;
                  end

                  if (burst_count < 63) begin
                    state <= RWRDY;
                  end else begin

                    state <= ACKWT;
                  end
                end else begin
                  state <= ACKWT;
                end

                burst_count <= burst_count + 1'b1;
              end
              
      ACKWT:
              state <= (ack) ? IDLE : ACKWT;
      
      WAIT:
              begin
                state <= (|dly) ? WAIT : next;
                if (next == RWRDY && dly == CL - 1 && !bursting)
                  sdr_cmd <= BURST_STOP;
              end
              
    endcase
  end

endmodule
module sdram_pnru (

    input  wire        sys_clk,
    input  wire        sys_rd,
    input  wire        sys_wr,
    output reg         sys_rdy = 1'b0,
    input  wire        sys_ack,
    input  wire [23:0] sys_ab,
    input  wire [15:0] sys_di,
    output reg  [15:0] sys_do,
    input  wire  [1:0] sys_wmask,
    input              burst_i,


    output wire  [3:0] sdr_n_CS_WE_RAS_CAS,
    output wire  [1:0] sdr_ba,
    output reg  [12:0] sdr_ab,
    input  wire [15:0] sdr_q,
    output wire [15:0] sdr_d,
    output reg         sdr_dq_oe,
    output reg   [1:0] sdr_dqm = 2'b11
  );






  localparam tRP = 3, tMRD = 2, tRCD = 3, tRC = 9, CL = 3;
  `ifdef SYNTHESIS
  localparam INITLEN = 12500 / 5;
  `else
  localparam INITLEN = 3;
  `endif
  localparam RFTIME  =   975 / 5;


  reg [15:0] di;
  reg [23:0] ab;
  reg rd, wr, ack;
  always @(posedge sys_clk) begin
    di <= sys_di;
    ab <= sys_ab;
    rd <= sys_rd;
    wr <= sys_wr;
    ack <= sys_ack;
  end

  

  assign sdr_n_CS_WE_RAS_CAS = sdr_cmd;
  assign sdr_ba = (state==CONFIG) ? 2'b00 : ab[10:9];
  assign sdr_d = di;
  assign sdr_dq_oe = (state==RWRDY && wr);


  localparam IDLE = 0, RFRSH1 = 1, RFRSH2 = 2, CONFIG = 3, RDWR = 4, RWRDY = 5, ACKWT = 6, WAIT = 7;

  reg  [3:0] sdr_cmd;
  reg  [2:0] state   = IDLE;
  reg  [2:0] next;
  reg [15:0] ctr     = 0;
  reg  [6:0] dly;
  reg  [3:0] open;
  reg [12:0] opnrow[0:3];
  reg bursting;
  reg  [7:0] burst_count;
  

  reg         init = 1'b1;
  wire  [8:0] col  = ab[8:0];
  wire [12:0] row  = ab[23:11];
  wire  [1:0] ba   = ab[10:9];
  

  localparam NOP  = 4'b1000, PRECHRG = 4'b0001, AUTORFRSH = 4'b0100, MODESET = 4'b0000,
             READ = 4'b0110, WRITE   = 4'b0010, ACTIVATE  = 4'b0101, BURST_STOP = 4'b0011;


  localparam MODE = 13'b000_1_00_011_0_111;
  
  always @(posedge sys_clk)
  begin
    ctr <= ctr + 1;
    dly <= dly - 1;
    

    sdr_cmd <= NOP;
    state   <= WAIT;

    case (state)
    
      IDLE:   if (init) state <= (ctr==INITLEN) ? RFRSH1 : IDLE;
              else begin
                sys_rdy <= 1'b0;
                if (ctr>=RFTIME) state <= RFRSH1;
                else if (rd|wr) begin
                  state <= RDWR;
                  sdr_dqm <= rd ? 2'b00 : ~sys_wmask;
                  bursting <= burst_i;
                end else begin
                  sys_rdy <= 1'b1;
                  state <= IDLE;
                end
                burst_count <= 0;
              end

      RFRSH1: begin
                sdr_cmd    <= PRECHRG;
                sdr_ab[10] <= 1'b1;
                open       <= 4'b000;
                dly <= tRP-2; next <= (init) ? CONFIG : RFRSH2;
              end

      RFRSH2: begin
                sdr_cmd <= AUTORFRSH;
                init <= 1'b0;
                ctr     <= 0;
                dly <= tRC-2; next <= (init) ? RFRSH2 : IDLE;
              end

      CONFIG: begin
                sdr_cmd <= MODESET;
                sdr_ab  <= MODE;
                dly <= tMRD-2; next <= RFRSH2;
              end

      RDWR:   begin
                if (!open[ba]) begin
                  sdr_cmd <= ACTIVATE;
                  sdr_ab  <= row;
                  open[ba]   <= 1'b1;
                  opnrow[ba] <= row;
                  dly <= tRCD-2; next <= RDWR;
                  end
                else if (opnrow[ba]!=row) begin
                  sdr_cmd      <= PRECHRG;
                  sdr_ab[10]   <= 1'b0;
                  open[ba] <= 1'b0;
                  dly <= tRP-2; next <= RDWR;
                  end
                else begin
                  sdr_cmd <= (rd) ? READ : WRITE;
                  sdr_ab  <= {4'b0000, col};
                  dly <= CL-1; next <= RWRDY;
                  if (wr) state <= RWRDY;
                  end
              end
      
      RWRDY:  begin
                sys_rdy <= 1'b1;
                if (rd) sys_do  <= sdr_q;
                if (wr) sdr_cmd <= BURST_STOP;
                if (bursting) begin

                  if (burst_count == 64 - CL) begin
                    sdr_cmd <= BURST_STOP;
                  end

                  if (burst_count < 63) begin
                    state <= RWRDY;
                  end else begin

                    state <= ACKWT;
                  end
                end else begin
                  state <= ACKWT;
                end

                burst_count <= burst_count + 1'b1;
              end
              
      ACKWT:
              state <= (ack) ? IDLE : ACKWT;
      
      WAIT:
              begin
                state <= (|dly) ? WAIT : next;
                if (next == RWRDY && dly == CL - 1 && !bursting)
                  sdr_cmd <= BURST_STOP;
              end
              
    endcase
  end

endmodule