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

📄 sdram_cnt.v

📁 sdram controller.verilog
💻 V
📖 第 1 页 / 共 2 页
字号:
    state_auto_refresh_dly:  begin
        sd_cs_l        <= #1 1'b1;
        sd_ras_l       <= #1 1'b1;
        sd_cas_l       <= #1 1'b1;
        do_refresh_ack <= #1 1'b0;
        
        // Wait for Trc
        if (autorefresh_cntr == refresh2anything_delay_val) begin
            autorefresh_cntr_l <= #1 1'b0;  // reset Trc delay counter
            // Check if the number of specified back-back refreshes are done
            if (refresh_cntr == cntr_limit)   begin
                 doing_refresh <= #1 1'b0;             // refresh cycle is done
                 refresh_cntr_l  <= #1 1'b0;           // ..reset refresh counter
                 // if this is not a power-up sequence, and there are pending
                 // requests, then service it.
                 if (~pwrup)
                    if (do_write | do_read)
                    begin
                        next_state <= #1 state_set_ras; // go service a pending read or write if any
                        sd_addx_mux   <= #1 2'b00;   // select ROW (A[19:10]) of mp_addx to SDRAM
                        sd_addx10_mux <= #1 2'b00; // select ROW (A[20])    "      "
                        load_address  <= #1 1'b1 ;
                    end
                    else
                        next_state <= #1 state_idle;    // if there are no peding RD or WR, then go to idle state
                 // if this is part of power-up sequencing, we need to go and
                 // set mode register.
                 else
                 begin
                    next_state <= #1 state_modeset;
                    assert_we <= #1 1'b1 ;
                    sd_addx_mux <= #1 2'b10;   // modeset[9:0]
                    sd_addx10_mux <= #1 2'b10; // modeset[10]
                    load_address <= #1 1'b1 ;
                 end
            end
            // IF refresh cycles not done yet, keep issuing autorefresh commands
            else
                 next_state <= #1 state_auto_refresh;

        end
        // If Trc has not expired
        else 
        begin
            next_state <= #1 state_auto_refresh_dly;
        end
    end


    // MODE SET state
    state_modeset:  begin
        next_state  <= #1 state_idle;
        sd_cs_l     <= #1 1'b0;
        sd_ras_l    <= #1 1'b0;
        sd_cas_l    <= #1 1'b0;
        load_address <= #1 1'b0 ;
        assert_we   <= #1 1'b0 ;
        doing_refresh <= #1 1'b0;   // deassert
        if (pwrup)
           pwrup    <= #1 1'b0;                 // ..no more in power up mode
        if (do_mode_set)
            do_modeset_ack <= #1 1'b0;
    end



    // IDLE state
    state_idle:  begin
        sd_dqm      <= #1 4'hF ;
        load_dqm    <= #1 1'b0;
        sd_cs_l     <= #1 1'b1;
        sd_ras_l	<= #1 1'b1;
        sd_cas_l	<= #1 1'b1;
        mp_data_mux <= #1 1'b0;         // drive the SD data bus with normal data
        do_read_ack  <= #1 1'b0 ;
        do_write_ack <= #1 1'b0 ;
        row_active_time_count_enable <= #1 1'b0 ;
        precharge_to_ras_count_enable <= #1 1'b0 ;
        sd_rd_ena      <= #1 1'b0;     // done with the reading

        // if we've just come out of system reset (or powerup)
        // then we need to go and do initialization sequence.
        // Or, if a refresh is requested, go and service it.
        if ( go )
        begin
            if (do_refresh | pwrup) 
            begin
                doing_refresh <= #1 1'b1;        // indicate that we're doing refresh
                refresh_cntr_l <= #1 1'b1;		// allow refresh cycle counter to count up
                next_state <= #1 state_auto_refresh;
                busy       <= #1 1'b1 ;
	        end

            // if a single word rad or write request is pending, go and service it
 		    else if (do_write | do_read )
            begin
                next_state <= #1 state_set_ras;
                busy <= #1 1'b1 ;
                sd_addx_mux   <= #1 2'b00;   // select ROW (A[19:10]) of mp_addx to SDRAM
                sd_addx10_mux <= #1 2'b00; // select ROW (A[20])    "      "
                load_address  <= #1 1'b1 ;
            end

            // if a mode register set is requested, go and service it
            else if (do_mode_set) 
            begin
                do_modeset_ack <= #1 1'b1;  // acknowledge the mode set request
                next_state <= #1 state_modeset;
                busy <= #1 1'b1 ;
                doing_refresh <= #1 1'b1;		// techincally we're not doing refresh, but
                                            // this signal is used to prevent the do_write be deasserted
                							// by the mode_set command.
                sd_addx_mux <= #1 2'b10;   // modeset[9:0]
                sd_addx10_mux <= #1 2'b10; // modeset[10]
                load_address <= #1 1'b1 ;
                assert_we   <= #1 1'b1 ;
            end
            else
                busy <= #1 1'b0 ;
        end
        else
            busy <= #1 1'b0 ;
    end

    // SET RAS state
    state_set_ras:  begin
        sd_cs_l       <= #1 1'b0;     // enable SDRAM
        sd_ras_l      <= #1 1'b0;     // enable the RAS
        row_active_time_count_enable <= #1 1'b1 ;
        
        sd_addx_mux <= #1 2'b01;   // select COLUMN
        
        if ( ras2cas_delay_val == 1 )
        begin
            if ( do_write )
            begin
                next_state <= #1 state_write ;
                assert_we  <= #1 1'b1 ;
                sd_dqm      <= #1 decoded_dqm;  // masks the data which is meant to be
                load_dqm   <= #1 1'b1 ;
                load_data  <= #1 1'b1 ;
                do_write_ack <= #1 1'b1 ;
                sd_addx10_mux <= #1 2'b01; // A10 = 0 
                last_data_in_to_row_precharge_count_enable <= #1 1'b1 ;
            end
            else
            begin
                next_state    <= #1 state_set_cas;   // wait for a bit
                sd_dqm       <= #1 4'h0;
                load_dqm     <= #1 1'b1 ;
                sd_addx10_mux <= #1 2'b11; // select AUTO_PRECHARGE_ENABLE
            end
        end
        else
        begin
            next_state                 <= #1 state_ras_dly ;
            ras2cas_delay_count_enable <= #1 1'b1 ;
            load_address               <= #1 1'b0 ;
        end
    end

    // RAS delay state.
    // This delay is needed to meet Trcd delay.  This is the RAS to CAS delay.
    // for most parts this is 20nS.  So for 100MHz operation, there needs to be
    // at least 1 NOP cycle.
    state_ras_dly:  begin
        sd_cs_l     <= #1 1'b1;     // disable SDRAM
        sd_ras_l    <= #1 1'b1;     // disble the RAS
        if ( ras2cas_delay_count == ras2cas_delay_val )
        begin
            load_address <= #1 1'b1 ;
            ras2cas_delay_count_enable <= #1 1'b0 ;
            if (do_write)  
            begin
                next_state   <= #1 state_write;      // if write, do the write
                assert_we    <= #1 1'b1 ;
                load_dqm     <= #1 1'b1 ;
                sd_dqm      <= #1 decoded_dqm;  // masks the data which is meant to be
                load_data    <= #1 1'b1 ;
                do_write_ack <= #1 1'b1 ;
                sd_addx10_mux <= #1 2'b01; // A10 = 0
                last_data_in_to_row_precharge_count_enable <= #1 1'b1 ;
            end 
            else 
            begin
                next_state  <= #1 state_set_cas;    // if read, do the read
                load_dqm    <= #1 1'b1 ;
                sd_dqm       <= #1 4'h0;
                sd_addx10_mux <= #1 2'b11; // select AUTO_PRECHARGE_ENABLE
            end
        end
        else
            next_state <= #1 state_ras_dly ;
    end

    // WRITE state
    state_write:  begin
        sd_cs_l     <= #1 1'b0;     // enable SDRAM
        sd_cas_l    <= #1 1'b0;     // enable the CAS
        do_write_ack<= #1 1'b0;

        sd_ras_l    <= #1 1'b1;     // disble the RAS
        load_address <= #1 1'b0 ;
        load_data    <= #1 1'b0 ;

        sd_dqm      <= #1 4'hF ;
        assert_we   <= #1 1'b0 ;
        if ( (last_data_in_to_row_precharge_count == 1) && row_can_be_precharged )
        begin
            next_state  <= #1 state_precharge;
            assert_we   <= #1 1'b1 ;
            sd_addx10_mux <= #1 2'b11;      // A10 = 1'b1
            load_address <= #1 1'b1 ;
            precharge_to_ras_count_enable <= #1 1'b1 ;
            last_data_in_to_row_precharge_count_enable <= #1 1'b0 ;
        end
        else
        begin
            next_state  <= #1 state_delay_Tras1;
        end
    end

    state_delay_Tras1:  begin
        sd_cs_l     <= #1 1'b1;
        sd_ras_l	<= #1 1'b1;
        sd_cas_l	<= #1 1'b1;
        mp_data_mux <= #1 1'b1;         // drive the SD data bus with all zeros
        load_dqm    <= #1 1'b0;

        if ((last_data_in_to_row_precharge_count == 1) && row_can_be_precharged)
        begin
            next_state  <= #1 state_precharge;
            assert_we   <= #1 1'b1 ;
            sd_addx10_mux <= #1 2'b11;      // A10 = 1'b1
            load_address <= #1 1'b1 ;
            precharge_to_ras_count_enable <= #1 1'b1 ;
            last_data_in_to_row_precharge_count_enable <= #1 1'b0 ;
        end
    end

    state_delay_Tras2:  
    begin
        sd_rd_ena      <= #1 1'b0;     // done with the reading
        do_read_ack    <= #1 1'b0;
        load_dqm       <= #1 1'b0;
        if ( row_can_be_precharged )
            precharge_to_ras_count_enable <= #1 1'b1 ;

        if ( precharge_time_expired && (row_active_time_count == 1) )
            next_state  <= #1 state_idle ;
    end


    // SET CAS state
    state_set_cas:  begin
        sd_cs_l      <= #1 1'b0;
        sd_cas_l     <= #1 1'b0;
        sd_ras_l     <= #1 1'b1 ;
        next_state   <= #1 state_cas_latency1;
        load_address <= #1 1'b0 ;
    end

    state_cas_latency1: begin
        sd_cs_l     <= #1 1'b1;     // disable CS
        sd_cas_l    <= #1 1'b1;     // disable CAS
        if (modereg_cas_latency==3'b010)  
        begin
            do_read_ack    <= #1 1'b1;  // acknowledge the read request (do it here due to the latency)
            next_state <= #1 state_read;            // 2 cycles of lantency done.
            burst_cntr_ena <= #1 1'b1;                // enable he burst lenght counter
        end 
        else
           next_state <= #1 state_cas_latency2;    // 3 cycles of latency
    end

    state_cas_latency2:  begin
        next_state <= #1 state_read;
        burst_cntr_ena <= #1 1'b1;      // enable the burst lenght counter
        do_read_ack    <= #1 1'b1;  // acknowledge the read request (do it here due to the latency)
    end

    state_read:  begin
        sd_cs_l     <= #1 1'b1;
        sd_ras_l	<= #1 1'b1;
        sd_cas_l	<= #1 1'b1;
        mp_data_mux <= #1 1'b1;         // drive the SD data bus with all zeros
        sd_rd_ena  <= #1 1'b1;          // enable the read latch on the next state

        if (row_can_be_precharged)
        begin
            if (modereg_cas_latency == 3'b011)
                precharge_to_ras_count_enable <= #1 1'b1 ;
            else
            begin
                if (burst_length_cntr != 4)
                begin
                    precharge_to_ras_count_enable <= #1 1'b1 ;
                end
            end
        end

        if (burst_length_cntr == 1) 
        begin
            burst_cntr_ena <= #1 1'b0;  // done counting;
            sd_dqm <= #1 4'hF ;

            if ( precharge_time_expired && row_active_time_count == 1)
                next_state <= #1 state_idle; // because of auto precharge
            else
                next_state <= #1 state_delay_Tras2 ;
        end 
    end

  endcase


// This counter is used to generate a delay right after the
// auto-refresh command is issued to the SDRAM
always @(posedge sys_clk or negedge sys_rst_l)
  if ( !sys_rst_l )
    autorefresh_cntr <= #1 4'h2;
  else if ( !autorefresh_cntr_l )
    autorefresh_cntr <= #1 4'h2;
  else
    autorefresh_cntr <= #1 autorefresh_cntr + 1;



// This mux selects the cycle limit value for the
// auto refresh counter.
// During power-up sequencing, we need to do `SDRAM_IF_REF_CNTR_LIMIT
//   number of back=back refreshes.
// During regular operation, we need to do `auto_ref_cntr_limit number of
//   back-back refreshes.  This, for most cases is just 1, but if we're doing
//   "burst" type of refreshes, it could be more than 1.
always @(pwrup)
  case (pwrup)
      1'b1:      cntr_limit = `SDRAM_IF_PWRUP_REF_CNTR_LIMIT;
      default:   cntr_limit = `SDRAM_IF_AUTO_REF_CNTR_LIMIT;
  endcase


//
// BURST LENGHT COUNTER
//
// This is the burst length counter.
always @(posedge sys_clk or negedge sys_rst_l)
  if ( !sys_rst_l )
     burst_length_cntr <= #1 4'b0001;
  else if ( !burst_cntr_ena )
     burst_length_cntr <= #1 modereg_burst_count;   // reset whenever 'burst_cntr_ena' is low
  else
     burst_length_cntr <= #1 burst_length_cntr - 1'b1 ;

//
// REFRESH_CNTR
//
// This counter keeps track of the number of back-back refreshes we're
// doing.  For most cases this would just be 1, but it allows "burst"
// refresh, where all refrehses are done back to back.
always @(posedge sys_clk or negedge sys_rst_l)
  if ( !sys_rst_l )
     refresh_cntr <= #1 13'h0000;
  else if ( !refresh_cntr_l )
     refresh_cntr <= #1 13'h0000;
  else if ( next_state  == state_auto_refresh )
	 refresh_cntr <= #1 refresh_cntr + 1;

//
// BURST LENGTH SELECTOR
//
always @(modereg_burst_length)
   case (modereg_burst_length)
      3'b000:  modereg_burst_count = 4'h1;
      3'b001:  modereg_burst_count = 4'h2;
      3'b010:  modereg_burst_count = 4'h4;
      default  modereg_burst_count = 4'h8;
   endcase


//
// REFRESH Request generator
//
always @(posedge sys_clk or negedge sys_rst_l)
  if (~sys_rst_l) begin
     refresh_state <= #1 state_count;
     refresh_timer <= #1 0;
     do_refresh    <= #1 1'b0 ;
  end
  else case (refresh_state)
     // COUNT
     // count up the refresh interval counter. If the
     // timer reaches the refresh-expire time, then go next state
     state_count:
        if (refresh_timer < refresh_timer_val) begin
           refresh_timer <= #1 refresh_timer + 1;
           refresh_state <= #1 state_count;
        end else begin
           refresh_state <= #1 state_halt;
           do_refresh    <= #1 1'b1 ;
		end

     // HALT
     // wait for the SDRAM to complete any ongoing reads or
     // writes.  If the SDRAM has acknowledged the do_refresh,
     // (i.e. it is now doing the refresh)
     // then go to next state
     state_halt:begin
          refresh_timer <= #1 0;
          if (do_refresh_ack)
          begin
            refresh_state <= #1 state_count;
            do_refresh    <= #1 1'b0 ;
          end
     end
  endcase

endmodule

⌨️ 快捷键说明

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