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

📄 mem_interface_top_phy_init_0.v

📁 sata_device_model,对做硬盘控制器的朋友有帮助
💻 V
📖 第 1 页 / 共 2 页
字号:
  //***************************************************************************
  // State logic to write calibration training patterns to write data FIFO
  //***************************************************************************

  always @(posedge clk0) begin
    if (rst0) begin
      init_wdf_cnt_r  <= 4'd0;
      init_wren_r <= 1'b0;
      init_done_r <= 1'b0;
      init_data_r <= {64{1'bx}};
    end else begin
      init_wdf_cnt_r  <= init_wdf_cnt_r + 1;
      init_wren_r <= 1'b1;
      case (init_wdf_cnt_r)
        // First stage calibration. Pattern (rise/fall) = 1(r)->0(f)
        // The rise data and fall data are already interleaved in the manner
        // required for data into the WDF write FIFO
        4'h0, 4'h1, 4'h2, 4'h3:
          init_data_r <= {4{{8{1'b0}},{8{1'b1}}}};
        // Second stage calibration. Pattern = 1(r)->1(f)->0(r)->0(f)
        4'h4: init_data_r <= {64{1'b1}};
        4'h5: init_data_r <= {64{1'b0}};
        4'h6: init_data_r <= {64{1'b1}};
        4'h7: init_data_r <= {64{1'b0}};
        // Third stage calibration. Pattern = FF->FF->AA->AA->55->55->00->00
        // Also make sure that last word is all zeros (because init_data_r is
        // OR'ed with app_wdf_data.
        4'h8: init_data_r <= {64{1'b1}};
        4'h9: init_data_r <= {32{2'b10}};
        4'hA: init_data_r <= {32{2'b01}};
        // finished, stay in this state, and deassert WREN
        4'hB: begin
          init_data_r <= {64{1'b0}};
          init_done_r <= 1'b1;
          init_wdf_cnt_r  <= init_wdf_cnt_r;
          if (init_done_r)
            init_wren_r <= 1'b0;
          else
            init_wren_r <= 1'b1;
        end
        default: begin
          init_data_r <= {(2*DQ_WIDTH){1'bx}};
          init_wren_r <= 1'bx;
          init_done_r <= 1'bx;
          init_wdf_cnt_r  <= 4'bxxxx;
        end
      endcase
    end
  end

  //***************************************************************************

  //***************************************************************************
  // Initialization state machine
  //***************************************************************************

  // synthesis attribute max_fanout of init_cnt_r is 1
  always @(posedge clk0)
    // every time we need to initialize another rank of memory, need to
    // reset init count, and repeat the entire initialization (but not
    // calibration) sequence
    if (rst0 || (init_state_r == INIT_DEEP_MEMORY_ST))
      init_cnt_r <= 4'd0;
    else if (!DDR2_ENABLE && (init_state_r == INIT_PRECHARGE) &&
             (init_cnt_r == 4'h1))
      // skip EMR(2) and EMR(3) register loads
      init_cnt_r <= 4'h4;
    else if (!DDR2_ENABLE && (init_state_r == INIT_LOAD_MODE) &&
             (init_cnt_r == 4'h9))
      // skip OCD calibration for DDR1
      init_cnt_r <= 4'hC;
    else if ((init_state_r == INIT_LOAD_MODE) ||
             (init_state_r == INIT_PRECHARGE) ||
             (init_state_r == INIT_AUTO_REFRESH) ||
             (init_state_r == INIT_CNT_200))
      init_cnt_r <= init_cnt_r + 1;

  always @(posedge clk0) begin
    if ((init_state_r == INIT_IDLE) && (init_cnt_r == 4'hE)) begin
      phy_init_done_r <= 1'b1;
    end else
      phy_init_done_r <= 1'b0;
  end

  //synthesis attribute max_fanout of phy_init_done is 1
  always @(posedge clk0)
    phy_init_done <= phy_init_done_r;

  //synthesis translate_off
  always @(posedge phy_init_done_r)
      $display ("Calibration completed");
  //synthesis translate_on

  //*****************************************************************
   //synthesis attribute max_fanout of init_state_r is 3
   //synthesis attribute max_fanout of init_state_r1 is 3
   //synthesis attribute max_fanout of init_state_r2 is 3
  always @(posedge clk0)
    if (rst0) begin
      init_state_r  <= INIT_IDLE;
      init_state_r1 <= INIT_IDLE;
      init_state_r2 <= INIT_IDLE;
      calib_done_r  <= 4'b0000;
    end else begin
      init_state_r  <= init_next_state;
      init_state_r1 <= init_state_r;
      init_state_r2 <= init_state_r1;
      calib_done_r  <= calib_done; // register for timing
    end

  always @(*) begin
    init_next_state = init_state_r;
    case (init_state_r)
      INIT_IDLE: begin
        if (done_200us_r) begin
          case (init_cnt_r) // synthesis parallel_case full_case
            4'h0:
              init_next_state = INIT_CNT_200;
            4'h1:
              if (cnt_200_cycle_done_r)
                init_next_state = INIT_PRECHARGE;
            4'h2:
              init_next_state = INIT_LOAD_MODE; // EMR(2)
            4'h3:
              init_next_state = INIT_LOAD_MODE; // EMR(3);
            4'h4:
              init_next_state = INIT_LOAD_MODE; // EMR, enable DLL
            4'h5:
              init_next_state = INIT_LOAD_MODE; // MR, reset DLL
            4'h6:
              init_next_state = INIT_PRECHARGE;
            4'h7:
              init_next_state = INIT_AUTO_REFRESH;
            4'h8:
              init_next_state = INIT_AUTO_REFRESH;
            4'h9:
              init_next_state = INIT_LOAD_MODE; // MR, unreset DLL
            4'hA:
              init_next_state = INIT_LOAD_MODE; // EMR, OCD default
            4'hB:
              init_next_state = INIT_LOAD_MODE; // EMR, enable OCD exit
            4'hC: begin
              // Deep memory state/support disabled
              //  if ((chip_cnt_r < CS_NUM-1))
              //  init_next_state = INIT_DEEP_MEMORY_ST;
              //else
              if (cnt_200_cycle_done_r)
                init_next_state = INIT_DUMMY_ACTIVE;
              else
                init_next_state = INIT_IDLE;
            end
            4'hD:
              init_next_state = INIT_PRECHARGE;
            4'hE:
              init_next_state = INIT_IDLE;
            default :
              init_next_state = INIT_IDLE;
          endcase
        end
      end
      INIT_CNT_200:
        init_next_state = INIT_CNT_200_WAIT;
      INIT_CNT_200_WAIT:
        if (cnt_200_cycle_done_r)
          init_next_state = INIT_IDLE;
      INIT_PRECHARGE:
        init_next_state = INIT_PRECHARGE_WAIT;
      INIT_PRECHARGE_WAIT:
        if (cnt6_r == CNTNEXT)
          init_next_state = INIT_IDLE;
      INIT_LOAD_MODE:
        init_next_state = INIT_MODE_REGISTER_WAIT;
      INIT_MODE_REGISTER_WAIT:
        if (cnt6_r == CNTNEXT)
          init_next_state = INIT_IDLE;
      INIT_AUTO_REFRESH:
        init_next_state = INIT_AUTO_REFRESH_WAIT;
      INIT_AUTO_REFRESH_WAIT:
        if (cnt6_r == CNTNEXT)
          init_next_state = INIT_IDLE;
      INIT_DEEP_MEMORY_ST:
        init_next_state = INIT_IDLE;
      // single row activate. All subsequent calibration writes and read will
      // take place in this row
      INIT_DUMMY_ACTIVE:
        init_next_state = INIT_DUMMY_ACTIVE_WAIT;
      INIT_DUMMY_ACTIVE_WAIT:
        if (cnt6_r == CNTNEXT)
          init_next_state = INIT_CAL1_WRITE;
      // Stage 1 calibration (write and continuous read)
      INIT_CAL1_WRITE:
        if (burst_addr_r == 2'b11)
          init_next_state = INIT_CAL1_WRITE_READ;
      INIT_CAL1_WRITE_READ:
        if (cnt6_r == CNTNEXT)
          init_next_state = INIT_CAL1_READ;
      INIT_CAL1_READ:
        if (calib_done_r[0])
          init_next_state = INIT_CAL1_READ_WAIT;
      INIT_CAL1_READ_WAIT:
        if (cnt6_r == CNTNEXT)
          init_next_state = INIT_CAL2_WRITE;
      // Stage 2 calibration (write and continuous read)
      INIT_CAL2_WRITE:
        if (burst_addr_r == 2'b11)
          init_next_state = INIT_CAL2_WRITE_READ;
      INIT_CAL2_WRITE_READ:
        if (cnt6_r == CNTNEXT)
          init_next_state = INIT_CAL2_READ;
      INIT_CAL2_READ:
        if (calib_done_r[1])
          init_next_state = INIT_CAL2_READ_WAIT;
      INIT_CAL2_READ_WAIT:
        if(cnt6_r == CNTNEXT)
          init_next_state = INIT_CAL3_WRITE;
      // Stage 3 calibration (write and continuous read)
      INIT_CAL3_WRITE:
        if (burst_addr_r == 2'b11)
          init_next_state = INIT_CAL3_WRITE_READ;
      INIT_CAL3_WRITE_READ:
        if (cnt6_r == CNTNEXT)
          init_next_state = INIT_CAL3_READ;
      INIT_CAL3_READ:
        if (burst_addr_r == 2'b11)
          init_next_state = INIT_CAL3_READ_WAIT;
      INIT_CAL3_READ_WAIT: begin
        if (cnt6_r == CNTNEXT)
          if (calib_done_r[2]) begin
            if (DQS_GATE_EN)
              init_next_state = INIT_CAL4_READ;
            else
              init_next_state = INIT_PRECHARGE;
          end else
            init_next_state = INIT_CAL3_READ;
      end
      // Stage 4 calibration (continuous read only, same pattern as stage 3)
      // only used if DQS_GATE supported
      INIT_CAL4_READ:
        if (burst_addr_r == 2'b11)
          init_next_state = INIT_CAL4_READ_WAIT;
      INIT_CAL4_READ_WAIT: begin
        if (cnt6_r == CNTNEXT)
          if (calib_done_r[3])
            init_next_state = INIT_PRECHARGE;
          else
            init_next_state = INIT_CAL4_READ;
      end
    endcase
  end

  //***************************************************************************
  // Memory control/address
  //***************************************************************************

  always @(posedge clk0)
    if ((init_state_r == INIT_DUMMY_ACTIVE) ||
        (init_state_r == INIT_PRECHARGE) ||
        (init_state_r == INIT_LOAD_MODE) ||
        (init_state_r == INIT_AUTO_REFRESH))
      ddr_ras_n_r <= 1'b0;
    else
      ddr_ras_n_r <= 1'b1;

  always @(posedge clk0)
    if ((init_state_r == INIT_LOAD_MODE) ||
        (init_state_r == INIT_AUTO_REFRESH) ||
        (cal_write_read && (burst_cnt_r == 2'b00)))
      ddr_cas_n_r <= 1'b0;
    else
      ddr_cas_n_r <= 1'b1;

  always @(posedge clk0)
    if ((init_state_r == INIT_LOAD_MODE) ||
        (init_state_r == INIT_PRECHARGE) ||
        (cal_write && (burst_cnt_r == 2'b00)))
      ddr_we_n_r <= 1'b0;
    else
      ddr_we_n_r <= 1'b1;

  //*****************************************************************
  // memory address during init
  //*****************************************************************

  always @(posedge clk0) begin
    if (init_state_r == INIT_PRECHARGE) begin
      // Precharge all - set A10 = 1
      ddr_addr_r <= {ROW_WIDTH{1'b0}};
      ddr_addr_r[10] <= 1'b1;
    end else if (init_state_r == INIT_LOAD_MODE) begin
      ddr_ba_r <= {BANK_WIDTH{1'b0}};
      ddr_addr_r <= {ROW_WIDTH{1'b0}};
      case (init_cnt_r)
        // EMR (2)
        4'h2: begin
          ddr_ba_r[1:0] <= 2'b10;
          ddr_addr_r    <= {ROW_WIDTH{1'b0}};
        end
        // EMR (3)
        4'h3: begin
          ddr_ba_r[1:0] <= 2'b11;
          ddr_addr_r    <= {ROW_WIDTH{1'b0}};
        end
        // EMR write - A0 = 0 for DLL enable
        4'h4: begin
          ddr_ba_r[1:0] <= 2'b01;
          ddr_addr_r <= ext_mode_reg[ROW_WIDTH-1:0];
        end
        // MR write, reset DLL (A8=1)
        4'h5: begin
          ddr_ba_r[1:0] <= 2'b00;
          ddr_addr_r <= load_mode_reg[ROW_WIDTH-1:0];
          ddr_addr_r[8] <= 1'b1;
        end
        // MR write, unreset DLL (A8=0)
        4'h9: begin
          ddr_ba_r[1:0] <= 2'b00;
          ddr_addr_r <= load_mode_reg[ROW_WIDTH-1:0];
        end
        // EMR write, OCD default state
        4'hA: begin
          ddr_ba_r[1:0] <= 2'b01;
          ddr_addr_r <= ext_mode_reg[ROW_WIDTH-1:0];
          ddr_addr_r[9:7] <= 3'b111;
        end
        // EMR write - OCD exit
        4'hB: begin
          ddr_ba_r[1:0] <= 2'b01;
          ddr_addr_r <= ext_mode_reg[ROW_WIDTH-1:0];
        end
        default: begin
          ddr_ba_r <= {BANK_WIDTH{1'bx}};
          ddr_addr_r <= {ROW_WIDTH{1'bx}};
        end
      endcase
    end else if (cal_write_read) begin
      // when writing or reading for Stages 2-4, since training pattern is
      // either 4 (stage 2) or 8 (stage 3-4) long, if BURST LEN < 8, then
      // need to issue multiple bursts to read entire training pattern
      ddr_addr_r[ROW_WIDTH-1:3] <= {ROW_WIDTH-4{1'b0}};
      ddr_addr_r[2:0]           <= {burst_addr_r, 1'b0};
      ddr_ba_r                  <= {BANK_WIDTH-1{1'b0}};
    end else if (init_state_r == INIT_DUMMY_ACTIVE) begin
      // all calibration writing read takes place in row 0x0 only
      ddr_ba_r   <= {BANK_WIDTH{1'b0}};
      ddr_addr_r <= {ROW_WIDTH{1'b0}};
    end else begin
      // otherwise, cry me a river
      ddr_ba_r   <= {BANK_WIDTH{1'bx}};
      ddr_addr_r <= {ROW_WIDTH{1'bx}};
    end
  end

  // Keep CKE asserted after initial power-on delay
  always @(posedge clk0)
    ddr_cke_r <= {CKE_WIDTH{done_200us_r}};

  // register commands to memory. Two clock cycle delay from state -> output
  always @(posedge clk0) begin
    ddr_addr_r1   <= ddr_addr_r;
    ddr_ba_r1     <= ddr_ba_r;
    ddr_cas_n_r1  <= ddr_cas_n_r;
    ddr_ras_n_r1  <= ddr_ras_n_r;
    ddr_we_n_r1   <= ddr_we_n_r;
  end

  assign phy_init_addr      = ddr_addr_r1;
  assign phy_init_ba        = ddr_ba_r1;
  assign phy_init_cas_n     = ddr_cas_n_r1;
  assign phy_init_cke       = ddr_cke_r;
  assign phy_init_cs_n      = ddr_cs_n_r;
  assign phy_init_ras_n     = ddr_ras_n_r1;
  assign phy_init_we_n      = ddr_we_n_r1;
  assign phy_init_wdf_wren  = init_wren_r;
  assign phy_init_wdf_data  = init_data_r;


endmodule

⌨️ 快捷键说明

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