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

📄 hssdrc_decoder_state.v

📁 HSSDRC IP core is the configurable universal SDRAM controller with adaptive bank control and adaptiv
💻 V
📖 第 1 页 / 共 2 页
字号:
  //-------------------------------------------------------------------------------------------------- 

  always_comb begin : fsm_jump_decode 

    next_state = STATE_RESET; 

    unique case (1'b1) 

      state [STATE_RESET_BIT] : begin 
        next_state = STATE_IDLE; 
      end 
    
      state [STATE_IDLE_BIT] : begin 
        if (arb_write | arb_read | arb_refr)
          next_state = STATE_DECODE; 
        else 
          next_state = STATE_IDLE;
      end 
      //
      // decode branch 
      // 
      state [STATE_DECODE_BIT] : begin 
        if (refr_mode) begin : shorten_refresh_decode

          if (ba_map_all_close) 
            next_state = STATE_REFR; 
          else 
            next_state = STATE_PRE_ALL; 

        end 
        else begin : mode_of_rw_decode

          if (ba_map_pre_act_rw) 
            next_state = STATE_PRE; 
          else if (ba_map_rw) 
            next_state = STATE_RW; 
          else // if (ba_map_act_rw) 
            next_state = STATE_ACT;

        end 
      end 
      //
      // pre branch 
      // 
      state [STATE_PRE_BIT] : begin 
        if (dec_pre_enable) 

          if (cTrp_m1 == 0)
            next_state = STATE_ACT; 
          else 
            next_state = STATE_TRP;

        else 
          next_state = STATE_PRE;
      end 

      state [STATE_TRP_BIT] : begin 
        if (trp_cnt_done) 
          next_state = STATE_ACT; 
        else 
          next_state = STATE_TRP;
      end 
      //
      // act branch
      // 
      state [STATE_ACT_BIT] : begin 
        if (dec_act_enable) 

          if (cTrcd_m1 == 0)
            next_state = STATE_RW; 
          else 
            next_state = STATE_TRCD;

        else 
          next_state = STATE_ACT;
      end 

      state [STATE_TRCD_BIT] : begin 
        if (trcd_cnt_done) 
          next_state = STATE_RW;
        else 
          next_state = STATE_TRCD;
      end 
      //
      // data branch 
      // 
      state [STATE_RW_BIT] : begin 
        if ((dec_write_enable & write_mode) | (dec_read_enable & ~write_mode)) begin : burst_done_decode

          if (burst_done)
            next_state = STATE_IDLE; 
          else 
            next_state = STATE_ADDR_INC;

        end 
        else begin 
          next_state = STATE_RW;
        end           
      end 

      state [STATE_ADDR_INC_BIT] : begin 
        next_state = STATE_RW;
      end 
      //
      // refresh breanch 
      //
      state [STATE_PRE_ALL_BIT] : begin 
        if (dec_pre_all_enable)
          next_state = STATE_REFR; 
        else 
          next_state = STATE_PRE_ALL;
      end 

      state [STATE_REFR_BIT] : begin 
        if (dec_refr_enable)
          next_state = STATE_IDLE; 
        else 
          next_state = STATE_REFR;
      end 

    endcase 
  end 

  //---------------------------------------------------------------------------------------------------
  // 
  //---------------------------------------------------------------------------------------------------

  always_ff @(posedge clk or posedge reset) begin : fsm_register_process
    if (reset)      state <= STATE_RESET;
    else if (sclr)  state <= STATE_RESET; 
    else            state <= next_state; 
  end 
                  
  //---------------------------------------------------------------------------------------------------
  // 
  //---------------------------------------------------------------------------------------------------

  assign arb_ready   = state[STATE_IDLE_BIT];

  assign dec_pre_all = state[STATE_PRE_ALL_BIT]; 
  assign dec_refr    = state[STATE_REFR_BIT];
  assign dec_pre     = state[STATE_PRE_BIT];
  assign dec_act     = state[STATE_ACT_BIT];
  assign dec_read    = state[STATE_RW_BIT] & ~write_mode;
  assign dec_write   = state[STATE_RW_BIT] &  write_mode;
  assign dec_last    = state[STATE_RW_BIT] & burst_done ;

  // 
  // instead of decode state_refr_bit & state_pre_all_bit we can use refresh mode register 
  // 
  
  assign dec_locked = refr_mode;   

  //-------------------------------------------------------------------------------------------------- 
  //
  //-------------------------------------------------------------------------------------------------- 

  assign ba_map_update   = state[STATE_DECODE_BIT] & ~refr_mode;
  assign ba_map_clear    = state[STATE_DECODE_BIT] &  refr_mode;

  always_ff @(posedge clk) begin : mode_logic 
    if (state [STATE_IDLE_BIT]) begin 
      refr_mode   <= arb_refr; 
      write_mode  <= arb_write;
    end 
  end 

  //-------------------------------------------------------------------------------------------------- 
  //
  //-------------------------------------------------------------------------------------------------- 

  always_ff @(posedge clk) begin : addr_chid_logic

    if (state[STATE_IDLE_BIT]) begin 
      rowa_latched <= arb_rowa;
      ba_latched   <= arb_ba;
      chid_latched <= arb_chid;
    end 

    if (state[STATE_IDLE_BIT]) 
      cola_latched <= arb_cola; 
    else if (state[STATE_ADDR_INC_BIT])
      cola_latched <= cola_latched + last_used_burst;

  end 

  assign dec_cola  = cola_latched;
  assign dec_rowa  = rowa_latched;
  assign dec_ba    = ba_latched;
  assign dec_chid  = chid_latched;


  //-------------------------------------------------------------------------------------------------- 
  // alligned burst max cycles is 4 
  // burst [3:2] == 0 & burst[1:0] <= available_burst. 1 cycle is burst 
  // burst [3:2] != 0 & burst[1:0] <= available_burst. 1 cycle is burst             shift_cnt burst_done 
  // burst [ 1.. 4] : encoded with [ 4'd0 :  4'd3] : cycle is 1 : burst_shift_cnt =  4'b0000    1
  // burst [ 5.. 8] : encoded with [ 4'd4 :  4'd7] : cycle is 2 : burst_shift_cnt =  4'b0001    0
  // burst [ 9..12] : encoded with [ 4'd8 : 4'd11] : cycle is 3 : burst_shift_cnt =  4'b0010    0
  // burst [13..16] : encoded with [4'd12 : 4'd15] : cycle is 4 : burst_shift_cnt =  4'b0100    0
  // 

  // not alligned burst max cycles is 5                                             shift_cnt burst_done 
  // burst [ 1.. 4] : encoded with [ 4'd0 :  4'd3] : cycle is 2 : burst_shift_cnt =  4'b0001    0
  // burst [ 5.. 8] : encoded with [ 4'd4 :  4'd7] : cycle is 3 : burst_shift_cnt =  4'b0010    0
  // burst [ 9..12] : encoded with [ 4'd8 : 4'd11] : cycle is 4 : burst_shift_cnt =  4'b0100    0
  // burst [13..16] : encoded with [4'd12 : 4'd15] : cycle is 5 : burst_shift_cnt =  4'b1000    0
  //-------------------------------------------------------------------------------------------------- 

  always_ff @(posedge clk) begin : burst_latch_logic 
    if (state[STATE_IDLE_BIT]) 
      burst_latched  = arb_burst;      
  end 

  // remember that burst has -1 offset 
  // available burst has -1 offset too

  assign available_burst      = 4'b0011 - {2'b00, cola_latched[1:0]}; 

  assign remained_burst       = burst_latched - available_burst - 1'b1; 
  assign remained_burst_high  = remained_burst[3:2];
  assign remained_burst_low   = remained_burst[1:0];

  assign early_burst_done     = burst_shift_cnt[0];
  
  always_ff @(posedge clk) begin : burst_logic 
    if (state[STATE_DECODE_BIT]) begin 

      if (burst_latched <= available_burst) begin 

        burst_shift_cnt <= '0;

        burst_done   <= 1'b1;        // only 1 transaction will be 
        dec_burst    <= burst_latched[1:0];

      end 
      else begin 

        burst_shift_cnt   <= '0;
        burst_shift_cnt[remained_burst_high] <= 1'b1;

        remained_burst_low_latched <= remained_burst_low;

        burst_done <= 1'b0; // more then 2 transaction will be  
                
        dec_burst    <= available_burst[1:0]; 
        last_used_burst <= {2'b00, available_burst[1:0]} + 1'b1; // + 1 is compensation of -1 offset 

      end     
    end 
    else if (state[STATE_ADDR_INC_BIT]) begin 

      burst_shift_cnt <= burst_shift_cnt >> 1;      

      burst_done <= early_burst_done;
      //
      if (early_burst_done)
        dec_burst <= remained_burst_low_latched; // no transaction any more 
      else 
        dec_burst <= 2'b11; 
      // 
      last_used_burst <= 4'b0011 + 1'b1;
    end 
  end 

endmodule 

⌨️ 快捷键说明

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