⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mem_interface_top_ctrl_0.v

📁 sata_device_model,对做硬盘控制器的朋友有帮助
💻 V
📖 第 1 页 / 共 3 页
字号:
      end

      CTRL_PRECHARGE_WAIT:
        if (rp_cnt_r == 3'b000)
          if (auto_ref_r)
            // precharge again to make sure we close all the banks
            next_state = CTRL_PRECHARGE;
          else
            next_state = CTRL_ACTIVE;

      CTRL_PRECHARGE_WAIT1:
        if (rp_cnt_r == 3'b000)
          next_state = CTRL_AUTO_REFRESH;

      CTRL_AUTO_REFRESH:
        next_state = CTRL_AUTO_REFRESH_WAIT;

      CTRL_AUTO_REFRESH_WAIT:
        if (rfc_cnt_r == 3'd0)
          next_state = CTRL_ACTIVE;

      CTRL_ACTIVE:
        next_state = CTRL_ACTIVE_WAIT;

      CTRL_ACTIVE_WAIT:
        if (rcd_cnt_r == 3'd0)
          next_state = CTRL_COMMAND_WAIT;

      CTRL_COMMAND_WAIT: begin
        if (auto_ref_r) begin
          if (ras_cnt_r == 4'd0)
            next_state = CTRL_PRECHARGE;
        end else if ((((conflict_detect_r)
         &&(wr_flag_r || rd_flag_r)) && ~MULTI_BANK_EN)
         || (MULTI_BANK_EN && conflict_detect_r))
          next_state = CTRL_COMMAND_WAIT_CONF;
        else if (wr_flag_r)
          next_state = CTRL_BURST_WRITE;
        else if (rd_flag_r)
          next_state = CTRL_BURST_READ;
      end

      // beginning of write burst
      CTRL_BURST_WRITE:
       if (BURST_LEN_DIV2 == 1) begin
          // special case if BL = 2 (i.e. burst lasts only one clk cycle)
          if (wr_flag)
            // if we have another non-conflict write command right after the
            // current write, then stay in this state
            next_state = CTRL_BURST_WRITE;
          else
            // otherwise, if we're done with this burst, and have no write
            // immediately scheduled after this one, wait until write-read
            // delay has passed
            next_state = CTRL_WRITE_WAIT;
        end else
          // otherwise BL > 2, and we  have at least one more write cycle for
          // current burst
          next_state = CTRL_WRITE_WAIT;

      // continuation of write burst (also covers waiting after write burst
      // has completed for write-read delay to pass)
      CTRL_WRITE_WAIT: begin
        if (conflict_detect || auto_ref_r)
          next_state = CTRL_WRITE_BANK_CONF;
        // if current burst is finished, and another non-conflict write is
        // already queued up
        else if (wr_flag && (wrburst_cnt_r <= 3'b010))
          next_state = CTRL_BURST_WRITE;
        // otherwise, if current write has completed, wait for wr-rd delay
        else if ((wrburst_cnt_r <= 3'b010) && (wr_to_rd_cnt_r == 5'b00000))
          next_state = CTRL_COMMAND_WAIT;
      end

      CTRL_BURST_READ:
       if (BURST_LEN_DIV2 == 1) begin
          // special case if BL = 2 (i.e. burst lasts only one clk cycle)
          if (rd_flag)
            next_state = CTRL_BURST_READ;
          else
            next_state = CTRL_READ_WAIT;
        end else
          next_state = CTRL_READ_WAIT;

      CTRL_READ_WAIT: begin
        if (conflict_detect || auto_ref_r)
          next_state = CTRL_READ_BANK_CONF;
        else if (rd_flag && (rdburst_cnt_r <= 3'b010))
          next_state = CTRL_BURST_READ;
        else if ((rdburst_cnt_r <= 3'b010) && (rd_to_wr_cnt_r == 4'b0000))
          next_state = CTRL_COMMAND_WAIT;
      end

      CTRL_WRITE_BANK_CONF: begin
        if (auto_ref_r) begin
          if((wtp_cnt_r == 5'd0) && (ras_cnt_r == 4'b0000))
            next_state = CTRL_PRECHARGE;
        end else if ((bank_conf && MULTI_BANK_EN) ||
                    ((conflict_detect_r && (rd_flag_r || wr_flag_r)
                      && ~MULTI_BANK_EN)))begin
          if (no_precharge_r)
            next_state = CTRL_ACTIVE;
          else if ((wtp_cnt_r == 5'd0) && (ras_cnt_r == 4'b0000))
            next_state = CTRL_PRECHARGE;
        end else if (wr_flag_r && (wrburst_cnt_r < 3'b010)) begin
          next_state = CTRL_BURST_WRITE;
        end else if (wr_flag_r && (wrburst_cnt_r == 3'b010))
          next_state = CTRL_BURST_WRITE;
        else if ((wrburst_cnt_r <= 3'b010) && (wr_to_rd_cnt_r == 5'b00000))
          next_state = CTRL_COMMAND_WAIT;
      end

      CTRL_READ_BANK_CONF: begin
        if (auto_ref_r) begin
          if ((rtp_cnt_r == 5'd0) && (ras_cnt_r == 4'b0000))
            next_state = CTRL_PRECHARGE;
        end else if ((bank_conf && MULTI_BANK_EN) ||
                    ((conflict_detect_r && (rd_flag_r || wr_flag_r)
                      && ~MULTI_BANK_EN)))begin
          if (no_precharge_r)
             next_state = CTRL_ACTIVE;
          else if ((rtp_cnt_r == 5'd0) && (ras_cnt_r == 4'b0000))
            next_state = CTRL_PRECHARGE;
        end else if (rd_flag_r && (rdburst_cnt_r == 3'b010)) begin
          next_state = CTRL_BURST_READ;
        end else if (rd_flag_r && (rdburst_cnt_r < 3'b010))
          next_state = CTRL_BURST_READ;
        else if ((rdburst_cnt_r <= 3'b010) && (rd_to_wr_cnt_r == 4'b0000))
          next_state = CTRL_COMMAND_WAIT;
      end

      CTRL_COMMAND_WAIT_CONF: begin
        if ((bank_conf && MULTI_BANK_EN) ||
            (bank_conf_r && ~MULTI_BANK_EN))begin
          if (no_precharge_r)
            next_state = CTRL_ACTIVE;
          else if (ras_cnt_r == 4'd0)
            next_state = CTRL_PRECHARGE;
        end else if (wr_flag_r)
          next_state = CTRL_BURST_WRITE;
        else if (rd_flag_r)
          next_state = CTRL_BURST_READ;
        else
          next_state = CTRL_COMMAND_WAIT;
      end
    endcase
  end

  //***************************************************************************
  // control signals to memory
  //***************************************************************************

  always @(posedge clk)
    if ((state_r1 == CTRL_AUTO_REFRESH) ||
        (state_r1 == CTRL_ACTIVE) ||
        (state_r1 == CTRL_PRECHARGE))
      ddr_ras_n_r <= 1'b0;
    else
      ddr_ras_n_r <= 1'b1;

  always @(posedge clk)
    if ((state_r1 == CTRL_BURST_WRITE) ||
        (state_r1 == CTRL_BURST_READ) ||
        (state_r1 == CTRL_AUTO_REFRESH))
      ddr_cas_n_r <= 1'b0;
    else
      ddr_cas_n_r <= 1'b1;

  always @(posedge clk)
    if ((state_r1 == CTRL_BURST_WRITE) || (state_r1 == CTRL_PRECHARGE))
      ddr_we_n_r <= 1'b0;
    else
      ddr_we_n_r <= 1'b1;

  // turn off auto-precharge when issuing commands (A10 = 0)
  // mapping the col add for linear addressing.

  generate
    if (COL_WIDTH == ROW_WIDTH-1) begin: gen_ddr_addr_col_0
      assign ddr_addr_col = {af_addr_r1[COL_WIDTH-1:10], 1'b0,
                             af_addr_r1[9:0]};
    end
    if (COL_WIDTH > 10) begin: gen_ddr_addr_col_1
      assign ddr_addr_col = {{(ROW_WIDTH-COL_WIDTH-1){1'b0}},
                             af_addr_r1[COL_WIDTH-1:10], 1'b0,
                             af_addr_r1[9:0]};
    end else begin: gen_ddr_addr_col_2
      assign ddr_addr_col = {{(ROW_WIDTH-COL_WIDTH-1){1'b0}}, 1'b0,
                             af_addr_r1[COL_WIDTH-1:0]};
    end
  endgenerate

  // Assign address during row activate
  assign ddr_addr_row = af_addr_r1[ROW_RANGE_END:ROW_RANGE_START];

  always @(posedge clk)
    if ((state_r1 == CTRL_ACTIVE))
      ddr_addr_r <= ddr_addr_row;
    else if ((state_r1 == CTRL_BURST_WRITE) ||
             (state_r1 == CTRL_BURST_READ))
      ddr_addr_r <= ddr_addr_col;
    else if ((state_r1 == CTRL_PRECHARGE) && auto_ref_r) begin
      // if we're precharging as a result of AUTO-REFRESH, precharge all banks
      ddr_addr_r <= {ROW_WIDTH{1'b0}};
      ddr_addr_r[10] <= 1'b1;
    end else if (state_r1 == CTRL_PRECHARGE)
      // if we're precharging to close a specific bank/row, set A10=0
      ddr_addr_r <= {ROW_WIDTH{1'b0}};
    else
      ddr_addr_r <= {ROW_WIDTH{1'bx}};

  always @(posedge clk)
    // whenever we're precharging, we're either: (1) precharging all banks (in
    // which case banks bits are don't care, (2) precharging the LRU bank,
    // b/c we've exceeded the limit of # of banks open (need to close the LRU
    // bank to make room for a new one), (3) we haven't exceed the maximum #
    // of banks open, but we trying to open a different row in a bank that's
    // already open
    if ((state_r1 == CTRL_PRECHARGE) && bank_conf_r && MULTI_BANK_EN &&
        !bank_hit_any_r)
      // When LRU bank needs to be closed
      ddr_ba_r <= bank_cmp_addr_r[(3*CMP_WIDTH)+CMP_BANK_RANGE_END:
                                  (3*CMP_WIDTH)+CMP_BANK_RANGE_START];
    else
      // Either precharge due to refresh or bank hit case
      ddr_ba_r <= af_addr_r1[BANK_RANGE_END:BANK_RANGE_START];

  // chip enable generation logic
  generate
    // if only one chip select, always assert it after reset
    if (CS_BITS == 0) begin: gen_ddr_cs_0
      always @(posedge clk)
        if (rst)
          ddr_cs_n_r[0] <= 1'b1;
        else
          ddr_cs_n_r[0] <= 1'b0;
    // otherwise if we have multiple chip selects
    end else begin: gen_ddr_cs_1
      always @(posedge clk)
        if (rst)
          ddr_cs_n_r <= {CS_NUM{1'b1}};
        else if (state_r1 == CTRL_AUTO_REFRESH) begin
          // if auto-refreshing, only auto-refresh one CS at any time (avoid
          // beating on the ground plane by refreshing all CS's at same time)
          ddr_cs_n_r <= {CS_NUM{1'b1}};
          ddr_cs_n_r[auto_cnt_r] <= 1'b0;
        end else if ((state_r1 == CTRL_PRECHARGE) && bank_conf_r &&
                     MULTI_BANK_EN && !bank_hit_any_r) begin
          // precharging the LRU bank
          ddr_cs_n_r <= {CS_NUM{1'b1}};
          ddr_cs_n_r[bank_cmp_addr_r[(3*CMP_WIDTH)+CMP_CS_RANGE_END:
                                 (3*CMP_WIDTH)+CMP_CS_RANGE_START]] <= 1'b0;
        end else begin
          // otherwise, check the upper address bits to see which CS to assert
          ddr_cs_n_r <= {CS_NUM{1'b1}};
          ddr_cs_n_r[af_addr_r1[CS_RANGE_END:CS_RANGE_START]] <= 1'b0;
        end
    end
  endgenerate

  assign ctrl_addr  = ddr_addr_r;
  assign ctrl_ba    = ddr_ba_r;
  assign ctrl_ras_n = ddr_ras_n_r;
  assign ctrl_cas_n = ddr_cas_n_r;
  assign ctrl_we_n  = ddr_we_n_r;
  assign ctrl_cs_n  = ddr_cs_n_r;

endmodule

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -