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

📄 sdramcnt.v

📁 sdram.rar
💻 V
字号:
`include "inc.h"////  SDRAMCNT.v////  SDRAM controller.//  This module can control Synchronous DRAMS such as//  Samsumg's  KM416S1020/KM416S1120   1MB X 16//  NEC's      uPD451616               1MB X 16//  Oki's      MSM56V16160////  The SDRAM's internal MODE REGISTER is also programmable.////  module sdramcnt(	            // system level stuff			sys_rst_l,			sys_clk,					// SDRAM connections			sd_clke,			sd_wr_l,            sd_cs_l,			sd_ras_l,			sd_cas_l,			sd_ldqm,			sd_udqm,						// Host Controller connections	    	do_mode_set,	  		do_read,            do_write,            doing_refresh,            sd_addx_mux,            sd_addx10_mux,            sd_rd_ena,            sd_data_ena,            modereg_cas_latency,            modereg_burst_length,            mp_data_mux,			// debug            next_state,			autorefresh_cntr,			autorefresh_cntr_l,			pwrup,			cntr_limit		);// ****************************************////   I/O  DEFINITION//// ****************************************// System level stuffinput	        sys_rst_l;input	        sys_clk;// SDRAM connectionsoutput	        sd_wr_l;output	        sd_cs_l;output	        sd_ras_l;output	        sd_cas_l;output	        sd_ldqm;output	        sd_udqm;output	        sd_clke;// Host Controller connectionsinput           do_mode_set;input           do_read;input           do_write;output          doing_refresh;output  [1:0]   sd_addx_mux;output  [1:0]   sd_addx10_mux;output          sd_rd_ena;output          sd_data_ena;input   [2:0]   modereg_cas_latency;input   [2:0]   modereg_burst_length;output          mp_data_mux;// Debugoutput  [3:0]  next_state;output	[12:0]	autorefresh_cntr;output			autorefresh_cntr_l;output			pwrup;output	[12:0]	cntr_limit;// ****************************************//// Memory Elements //// ****************************************//reg     [3:0]	next_state;reg     [7:0]   refresh_timer;reg 	            sd_wr_l;reg		            sd_cs_l;reg		            sd_ras_l;reg		            sd_cas_l;reg                 sd_ldqm;reg                 sd_udqm;reg     [1:0]       sd_addx_mux;reg     [1:0]       sd_addx10_mux;reg                 sd_data_ena;reg		            pwrup;			// this variable holds the power up conditionreg     [12:0]      refresh_cntr;   // this is the refresh counterreg					refresh_cntr_l;	// this is the refresh counter reset signalreg     [3:0]       burst_length_cntr;reg                 burst_cntr_ena;reg                 sd_rd_ena;      // read latch gate, active highreg     [12:0]      cntr_limit;reg     [3:0]       modereg_burst_count;reg     [2:0]       refresh_state;reg                 mp_data_mux;wire                do_refresh;     // this bit indicates autorefresh is duereg                 doing_refresh;  // this bit indicates that the state machine is                                     // doing refresh.reg     [12:0]   autorefresh_cntr;reg                 autorefresh_cntr_l;assign sd_clke = `HI;		// clk always enabled// State Machinealways @(posedge sys_clk or negedge sys_rst_l)  if (~sys_rst_l) begin    next_state	<= `state_powerup;    autorefresh_cntr_l <= `LO;	refresh_cntr_l  <= `LO;    pwrup       <= `HI;    sd_wr_l     <= `HI;    sd_cs_l     <= `HI;    sd_ras_l    <= `HI;    sd_cas_l    <= `HI;    sd_ldqm     <= `HI;    sd_udqm     <= `HI;    sd_data_ena <= `LO;    sd_addx_mux <= 2'b10;           // select the mode reg default value    sd_addx10_mux <= 2'b11;         // select 1 as default    sd_rd_ena   <= `LO;    mp_data_mux <= `LO;//    refresh_cntr<= 13'h0000;    burst_cntr_ena <= `LO;          // do not enable the burst counter    doing_refresh  <= `LO;  end   else case (next_state)    // Power Up state    `state_powerup:  begin        next_state  <= `state_precharge;        sd_wr_l     <= `HI;        sd_cs_l     <= `HI;    	sd_ras_l    <= `HI;    	sd_cas_l    <= `HI;    	sd_ldqm	    <= `HI;    	sd_udqm     <= `HI;        sd_data_ena <= `LO;        sd_addx_mux <= 2'b10;        sd_rd_ena   <= `LO;        pwrup       <= `HI;         // this is the power up run        burst_cntr_ena <= `LO;      // do not enable the burst counter		refresh_cntr_l <= `HI;		// allow the refresh cycle counter to count     end    // PRECHARGE both banks        	    `state_precharge:  begin//        refresh_cntr<= refresh_cntr + 1;         // one less ref cycle to do           sd_wr_l     <= `LO;        sd_cs_l     <= `LO;    	sd_ras_l    <= `LO;    	sd_cas_l    <= `HI;    	sd_ldqm     <= `HI;    	sd_udqm     <= `HI;        sd_addx10_mux <= 2'b11;      // A10 = 1'b1            if ( (refresh_cntr == cntr_limit) & (pwrup == `HI) ) begin             doing_refresh <= `LO;                // refresh cycle is done//             refresh_cntr  <= 13'h000;             // ..reset refresh counter             refresh_cntr_l  <= `LO;             // ..reset refresh counter             next_state <= `state_modeset;      // if this was power-up, then go and set mode reg             pwrup      <= `LO;                 // ..no more in power up mode         end else begin           doing_refresh <= `HI;        // indicate that we're doing refresh           next_state	 <= `state_auto_refresh;		 end    end      // Autorefresh    `state_auto_refresh: begin        sd_wr_l     <= `HI;        sd_cs_l     <= `LO;    	sd_ras_l    <= `LO;    	sd_cas_l    <= `LO;    	sd_ldqm     <= `HI;    	sd_udqm     <= `HI;        sd_addx10_mux <= 2'b01;      // A10 = 0           next_state  <= `state_auto_refresh_dly;        autorefresh_cntr_l  <= `HI;  //allow delay cntr to tick     end        // Autor Refresh Delay -- extends the AutoRefresh CMD by       // AUTO_REFRESH_WIDTH counts    `state_auto_refresh_dly:  begin        if (autorefresh_cntr == `AUTO_REFRESH_WIDTH) begin            autorefresh_cntr_l <= `LO;          sd_wr_l     <= `HI;          sd_cs_l     <= `HI;          sd_ras_l    <= `HI;          sd_cas_l    <= `HI;          sd_ldqm     <= `HI;          sd_udqm     <= `HI;          // If all refresh is done          if ((refresh_cntr == cntr_limit) & (pwrup == `LO))   begin               doing_refresh <= `LO;                // refresh cycle is done//             refresh_cntr  <= 13'h000;            // ..reset refresh counter             refresh_cntr_l  <= `LO;            // ..reset refresh counter             if (do_write | do_read)                 next_state <= `state_set_ras;    // go service a pending read or write if any             else                 next_state <= `state_idle;       // if there are no peding RD or WR, then go to idle state           end                   // IF refresh cycles not done yet..          else             next_state <= `state_precharge;        end   end    // MODE SET state    `state_modeset:  begin        next_state  <= `state_idle;        sd_wr_l     <= `LO;        sd_cs_l     <= `LO;        sd_ras_l    <= `LO;        sd_cas_l    <= `LO;        if (~pwrup) begin       // select a10-a0 to be the data from mode set reg          sd_addx_mux <= 2'b10;          sd_addx10_mux <= 2'b10;        end    end    // IDLE state    `state_idle:  begin        sd_wr_l     <= `HI;        sd_cs_l     <= `HI;        sd_ras_l	<= `HI;        sd_cas_l	<= `HI;        sd_ldqm     <= `HI;        sd_udqm     <= `HI;        sd_data_ena <= `LO;         // turn off the data bus drivers        sd_addx10_mux <= 2'b01;     // select low        mp_data_mux <= `LO;         // drive the SD data bus with normal data        if (do_write | do_read )                    next_state <= `state_set_ras;        else if (do_mode_set)            next_state <= `state_modeset;        else if (do_refresh) begin            next_state <= `state_precharge;			refresh_cntr_l <= `HI;		// allow refresh cycle counter to count up		end    end        // SET RAS state    `state_set_ras:  begin        sd_cs_l     <= `LO;     // enable SDRAM         sd_ras_l    <= `LO;     // enable the RAS        sd_addx_mux <= 2'b00;   // send the low 10 bits of mp_addx to SDRAM        next_state  <= `state_ras_dly;   // wait for a bit    end    // RAS delay state.  This state may not be necessary for most    // cases.  Fow now, it is here to kill 1-cycle time    `state_ras_dly:  begin        sd_cs_l     <= `HI;     // disable SDRAM         sd_ras_l    <= `HI;     // disble the RAS        if (do_write)            next_state <= `state_write;      // if write, do the write              else             next_state <= `state_set_cas;    // if read, do the read    end    // WRITE state    `state_write:  begin        sd_cs_l     <= `LO;     // enable SDRAM         sd_cas_l    <= `LO;     // enable the CAS        sd_addx_mux <= 2'b01;   // send the lower 8 bits of mp_addx to SDRAM (CAS addx)                                // remember that the mp_addr[19] is the sd_ba        sd_addx10_mux <= 2'b00; // set A10/AP = mp_addx[18]         sd_data_ena <= `HI;     // turn on  the data bus drivers        sd_wr_l     <= `LO;     // enable the write        sd_ldqm     <= `LO;     // do not mask        sd_udqm     <= `LO;     // do not mask        next_state  <= `state_cool_off;    end    // SET CAS state    `state_set_cas:  begin        sd_cs_l     <= `LO;        sd_cas_l    <= `LO;        sd_addx_mux <= 2'b01;        sd_addx10_mux <= 2'b00;        sd_ldqm     <= `LO;     // do not mask        sd_udqm     <= `LO;     // do not mask        next_state  <= `state_cas_latency1;            end    `state_cas_latency1: begin        sd_cs_l     <= `HI;     // disable CS        sd_cas_l    <= `HI;     // disable CAS        if (modereg_cas_latency==3'b010)  begin           next_state <= `state_read;            // 2 cycles of lantency done.           burst_cntr_ena <= `HI;                // enable he burst lenght counter        end else           next_state <= `state_cas_latency2;    // 3 cycles of latency          end    `state_cas_latency2:  begin        next_state <= `state_read;        burst_cntr_ena <= `HI;      // enable the burst lenght counter    end    `state_read:  begin        if (burst_length_cntr == modereg_burst_count) begin            burst_cntr_ena <= `LO;  // done counting;            sd_rd_ena      <= `LO;     // done with the reading            next_state     <= `state_cool_off;        end else           sd_rd_ena  <= `HI;          // enable the read latch on the next state		    end    `state_cool_off:  begin        sd_wr_l     <= `HI;        sd_cs_l     <= `HI;        sd_ras_l	<= `HI;        sd_cas_l	<= `HI;        sd_ldqm     <= `HI;        sd_udqm     <= `HI;        sd_addx10_mux <= 2'b01;     // select the mp_addx[10]        mp_data_mux <= `HI;         // drive the SD data bus with all zeros        next_state  <= `state_idle;    end  endcase  // This counter is used to extend the width of the Auto Refresh// command.  It was found that if the AutoRefresh CMD set to be the default of // 1 SDRAM_CLK cycle, then an AutoRefresh CMD in the middle of a burst read// would mess-up the remining burst reads.  By extending the Auto Refresh cycle// to 2 or more, this burst read problem was solved.  As to why this happens// I did not investigate further.always @(posedge sys_clk or negedge autorefresh_cntr_l)  if (~autorefresh_cntr_l)    autorefresh_cntr <= 13'h0000;  else    autorefresh_cntr <= autorefresh_cntr + 1;// This mux selects the cycle limit value for the // auto refresh counteralways @(pwrup)  case (pwrup)/*    `HI:      cntr_limit <= `power_up_ref_cntr_limit;    default:  cntr_limit <= `auto_ref_cntr_limit;*/    1'b1:      cntr_limit <= 13'h000F;    default:  cntr_limit <= 13'h0001;  endcase//// BURST LENGHT COUNTER//// This is the burst length counter.  always @(posedge sys_clk or negedge burst_cntr_ena)  if (~burst_cntr_ena)     burst_length_cntr <= 3'b000;   // reset whenever 'burst_cntr_ena' is low  else     burst_length_cntr <= burst_length_cntr + 1;//// REFRESH_CNTR//always @(posedge sys_clk or negedge refresh_cntr_l)  if (~refresh_cntr_l)     refresh_cntr <= 13'h0000;  else if (next_state  == `state_auto_refresh)	 refresh_cntr <= 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//assign do_refresh = (refresh_state == `state_halt);always @(posedge sys_clk or negedge sys_rst_l)  if (~sys_rst_l) begin     refresh_state <= `state_count;     refresh_timer <= 8'h00;  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 != `RC)           refresh_timer <= refresh_timer + 1;        else            refresh_state <= `state_halt;         // 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:         if (next_state==`state_auto_refresh     |             next_state==`state_auto_refresh_dly |            next_state==`state_precharge )             refresh_state <= `state_reset;             // RESET     // if the SDRAM refresh is completed, then reset the counter     // and start counting up again.     `state_reset:        if (next_state==`state_idle) begin           refresh_state <= `state_count;           refresh_timer <= 8'h00;        end  endcase           endmodule

⌨️ 快捷键说明

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