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

📄 sdram_cnt.v

📁 sdram controller.verilog
💻 V
📖 第 1 页 / 共 2 页
字号:
`include "sdram_defines.v"
// synopsys translate_off
`include "timescale.v"
// synopsys translate_on


//*******************************************************************************
//  S Y N T H E S I Z A B L E      S D R A M     C O N T R O L L E R    C O R E
//
//  This core adheres to the GNU Public License
//
//  This is a synthesizable Synchronous DRAM controller Core.  As it stands,
//  it is ready to work with 8Mbyte SDRAMs, organized as 2M x 32 at 100MHz
//  and 125MHz. For example: Samsung KM432S2030CT,  Fujitsu MB81F643242B.
//
//  The core has been carefully coded so as to be "platform-independent".
//  It has been successfully compiled and simulated under three separate
//  FPGA/CPLD platforms:
//      Xilinx Foundation Base Express V2.1i
//      Altera Max+PlusII V9.21
//      Lattice ispExpert V7.0
//
//  The interface to the host (i.e. microprocessor, DSP, etc) is synchronous
//  and supports ony one transfer at a time.  That is, burst-mode transfers
//  are not yet supported.  In may ways, the interface to this core is much
//  like that of a typical SRAM.  The hand-shaking between the host and the
//  SDRAM core is done through the "sdram_busy_l" signal generated by the
//  core.  Whenever this signal is active low, the host must hold the address,
//  data (if doing a write), size and the controls (cs, rd/wr).
//
//  Connection Diagram:
//  SDRAM side:
//  sd_wr_l                     connect to -WR pin of SDRAM
//  sd_cs_l                     connect to -CS pin of SDRAM
//  sd_ras_l                    connect to -RAS pin of SDRAM
//  sd_cas_l                    connect to -CAS pin of SDRAM
//  sd_dqm[3:0]                 connect to the DQM3,DQM2,DQM1,DQM0 pins
//  sd_addx[10:0]               connect to the Address bus [10:0]
//  sd_data[31:0]               connect to the data bus [31:0]
//  sd_ba[1:0]                  connect to BA1, BA0 pins of SDRAM
//
//  HOST side:
//  mp_addx[22:0]               connect to the address bus of the host.
//                              23 bit address bus give access to 8Mbyte
//                              of the SDRAM, as byte, half-word (16bit)
//                              or word (32bit)
//  mp_data_in[31:0]            Unidirectional bus connected to the data out
//                              of the host. To use this, enable
//                              "databus_is_unidirectional" in INC.H
//  mp_data_out[31:0]           Unidirectional bus connected to the data in
//                              of the host.  To use this, enable
//                              "databus_is_unidirectional" in INC.H
//  mp_data[31:0]               Bi-directional bus connected to the host's
//                              data bus.  To use the bi-directionla bus,
//                              disable "databus_is_unidirectional" in INC.H
//  mp_rd_l                     Connect to the -RD output of the host
//  mp_wr_l                     Connect to the -WR output of the host
//  mp_cs_l                     Connect to the -CS of the host
//  mp_size[1:0]                Connect to the size output of the host
//                              if there is one.  When set to 0
//                              all trasnfers are 32 bits, when set to 1
//                              all transfers are 8 bits, and when set to
//                              2 all xfers are 16 bits.  If you want the
//                              data to be lower order aligned, turn on
//                              "align_data_bus" option in INC.H
//  sdram_busy_l                Connect this to the wait or hold equivalent
//                              input of the host.  The host, must hold the
//                              bus if it samples this signal as low.
//  sdram_mode_set_l            When a write occurs with this set low,
//                              the SDRAM's mode set register will be programmed
//                              with the data supplied on the data_bus[10:0].
//
//
//  Author:  Jeung Joon Lee  joon.lee@quantum.com,  cmosexod@ix.netcom.com
//
//*******************************************************************************
//
//  Hierarchy:
//
//  SDRAM.V         Top Level Module
//  HOSTCONT.V      Controls the interfacing between the micro and the SDRAM
//  SDRAMCNT.V      This is the SDRAM controller.  All data passed to and from
//                  is with the HOSTCONT.
//  optional
//  MICRO.V         This is the built in SDRAM tester.  This module generates
//                  a number of test logics which is used to test the SDRAM
//                  It is basically a Micro bus generator.
//
/*
*/



module sdram_cnt(
		// system level stuff
			sys_rst_l,
			sys_clk,

		// SDRAM connections
		    sd_cs_l,
			sd_ras_l,
			sd_cas_l,
			sd_dqm,

			// 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,
			decoded_dqm,
            do_write_ack,
            do_read_ack,
            do_modeset_ack,
            pwrup,
            go,
            busy,
            refresh_timer_val,
            ras2cas_delay_val,
            refresh2anything_delay_val,
            row_active_time_val,
            last_data_in_to_row_precharge_val,
            precharge_to_ras_val,
            do_refresh,
            load_address,
            load_data,
            load_dqm,
            assert_we,

			// debug
            next_state,
			autorefresh_cntr,
			autorefresh_cntr_l,
			cntr_limit

		);

parameter state_idle             = 'b0000000000000001 ;
parameter state_set_ras          = 'b0000000000000010 ;
parameter state_ras_dly          = 'b0000000000000100 ;
parameter state_set_cas          = 'b0000000000001000 ;
parameter state_cas_latency1     = 'b0000000000010000 ;
parameter state_cas_latency2     = 'b0000000000100000 ;
parameter state_write            = 'b0000000001000000 ;
parameter state_read             = 'b0000000010000000 ;
parameter state_auto_refresh     = 'b0000000100000000 ;
parameter state_auto_refresh_dly = 'b0000001000000000 ;
parameter state_precharge        = 'b0000010000000000 ;
parameter state_powerup          = 'b0000100000000000 ;
parameter state_modeset          = 'b0001000000000000 ;
parameter state_delay_Trp        = 'b0010000000000000 ;
parameter state_delay_Tras1      = 'b0100000000000000 ;
parameter state_delay_Tras2      = 'b1000000000000000 ;

// Refresh timer states
parameter   state_count          = 'b0 ;
parameter   state_halt           = 'b1 ;

// ****************************************
//
//   I/O  DEFINITION
//
// ****************************************


// System level stuff
input	        sys_rst_l;
input	        sys_clk;

// SDRAM connections
output	        sd_cs_l;
output	        sd_ras_l;
output	        sd_cas_l;
output	 [3:0]  sd_dqm;

// Host Controller connections
input           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;
input	[3:0]	decoded_dqm;
output          do_write_ack;
output          do_read_ack;
output          do_modeset_ack;
output			pwrup;
input           go ;
output          busy ;
reg             busy ;

input   [15:0]  refresh_timer_val ;
input   [1:0]   ras2cas_delay_val ;
input   [3:0]   refresh2anything_delay_val ;
input   [3:0]   row_active_time_val ;
input   [1:0]   last_data_in_to_row_precharge_val ;
input   [1:0]   precharge_to_ras_val ;
output          do_refresh ;

output          load_address,
                load_data,
                load_dqm,
                assert_we ;

reg load_address,
    load_data,
    load_dqm,
    assert_we ;

assign sd_data_ena = load_data ;

// Debug
output  [15:0]   next_state;
output	[3:0]	autorefresh_cntr;
output			autorefresh_cntr_l;
output	[12:0]	cntr_limit;

// ****************************************
//
// Memory Elements
//
// ****************************************
//
reg     [15:0]	next_state;
reg     [15:0]  refresh_timer;
reg		        sd_cs_l;
reg		        sd_ras_l;
reg		        sd_cas_l;
reg     [3:0]   sd_dqm;
reg     [1:0]   sd_addx_mux;
reg     [1:0]   sd_addx10_mux;
reg		        pwrup;			// this variable holds the power up condition
reg     [12:0]  refresh_cntr;   // this is the refresh counter
reg				refresh_cntr_l;	// this is the refresh counter reset signal
reg     [3:0]   burst_length_cntr;
reg             burst_cntr_ena;
reg             sd_rd_ena;      // read latch gate, active high
reg     [12:0]  cntr_limit;
reg     [3:0]   modereg_burst_count;
reg             refresh_state;
reg             mp_data_mux;
reg             do_refresh;     // this bit indicates autorefresh is due
reg             doing_refresh;  // this bit indicates that the state machine is
                                // doing refresh.
reg     [3:0]   autorefresh_cntr;
reg             autorefresh_cntr_l;
reg             do_write_ack;
reg             do_read_ack;
reg             do_modeset_ack;
reg             do_refresh_ack;

reg     [1:0]   ras2cas_delay_count ;
reg             ras2cas_delay_count_enable ;  

reg     [3:0]   row_active_time_count ;
reg             row_active_time_count_enable ;

reg     [1:0]   last_data_in_to_row_precharge_count ;
reg             last_data_in_to_row_precharge_count_enable ;

reg     [1:0]   precharge_to_ras_count ;
reg             precharge_to_ras_count_enable ;

always@(posedge sys_clk or negedge sys_rst_l)
begin
    if (~sys_rst_l)
        precharge_to_ras_count <= #1 2'h0 ;
    else if ( !precharge_to_ras_count_enable )
        precharge_to_ras_count <= #1 precharge_to_ras_val ;
    else if (precharge_to_ras_count != 1)
        precharge_to_ras_count <= #1 precharge_to_ras_count - 1'b1 ;
end

wire precharge_time_expired = (precharge_to_ras_count == 2) || (precharge_to_ras_count == 1) ;

always@(posedge sys_clk or negedge sys_rst_l)
begin
    if (~sys_rst_l)
        last_data_in_to_row_precharge_count <= #1 0 ;
    else if ( !last_data_in_to_row_precharge_count_enable )
        last_data_in_to_row_precharge_count <= #1 last_data_in_to_row_precharge_val ;
    else if ( last_data_in_to_row_precharge_count != 1  )
        last_data_in_to_row_precharge_count <= #1 last_data_in_to_row_precharge_count - 1'b1 ;
end

always@(posedge sys_clk or negedge sys_rst_l)
begin
    if (~sys_rst_l)
        row_active_time_count <= #1 4'hF ;
    else if ( !row_active_time_count_enable )
        row_active_time_count <= #1 row_active_time_val ;
    else if ( row_active_time_count != 4'h1 )
        row_active_time_count <= #1 row_active_time_count - 1'b1 ;
end

//wire row_can_be_precharged = (row_active_time_count == 4'h0) || (row_active_time_count == 4'h1) || (row_active_time_count == 4'h2);
wire row_can_be_precharged = ((row_active_time_count == 2) || (row_active_time_count == 1)) ;

always@(posedge sys_clk or negedge sys_rst_l)
begin
    if (~sys_rst_l)
        ras2cas_delay_count <= #1 2 ;
    else if (!ras2cas_delay_count_enable)
        ras2cas_delay_count <= #1 2 ;
    else
        ras2cas_delay_count <= #1 ras2cas_delay_count + 1'b1 ;
end

// State Machine
always @(posedge sys_clk or negedge sys_rst_l)
  if (~sys_rst_l) begin
    next_state	<=state_powerup;
    autorefresh_cntr_l <= #1 1'b0;
	refresh_cntr_l  <= #1 1'b0;
    pwrup       <= #1 1'b1 ;		// high indicates we've just power'd up or RESET
    sd_cs_l     <= #1 1'b1 ;
    sd_ras_l    <= #1 1'b1 ;
    sd_cas_l    <= #1 1'b1 ;
    sd_dqm      <= #1 4'hF;
    sd_addx_mux <= #1 2'b10;           // select the mode reg default value
    sd_addx10_mux <= #1 2'b11;         // select 1 as default
    sd_rd_ena   <= #1 1'b0;
    mp_data_mux <= #1 1'b0;
//    refresh_cntr<= 13'h0000;
    burst_cntr_ena <= #1 1'b0;          // do not enable the burst counter
    doing_refresh  <= #1 1'b0;
    do_write_ack <= #1 1'b0;            // do not ack as reset default
    do_read_ack  <= #1 1'b0;            // do not ack as reset default
    do_modeset_ack <= #1 1'b0;          // do not ack as reset default
    do_refresh_ack <= #1 1'b0;
    busy           <= #1 1'b1 ;
    ras2cas_delay_count_enable <= #1 1'b0 ;
    row_active_time_count_enable <= #1 1'b0 ;
    last_data_in_to_row_precharge_count_enable <= #1 1'b0 ;
    precharge_to_ras_count_enable <= #1 1'b0 ;

    load_address <= #1 1'b0 ;
    load_data    <= #1 1'b0 ;
    load_dqm     <= #1 1'b0 ;
    assert_we    <= #1 1'b0 ;
  end
  else case (next_state)
    // Power Up state
    state_powerup:  begin
        next_state  <= #1 state_precharge;
        sd_addx10_mux <= #1 2'b11;      // A10 = 1'b1
        load_address <= #1 1'b1 ;
        assert_we    <= #1 1'b1 ;

        precharge_to_ras_count_enable <= #1 1'b1 ;
        sd_cs_l     <= #1 1'b1;
    	sd_ras_l    <= #1 1'b1;
    	sd_cas_l    <= #1 1'b1;
        sd_dqm      <= #1 4'hF;
        sd_rd_ena   <= #1 1'b0;
        pwrup       <= #1 1'b1;         // this is the power up run
        burst_cntr_ena <= #1 1'b0;      // do not enable the burst counter
		refresh_cntr_l <= #1 1'b1;		// allow the refresh cycle counter to count
     end

    // PRECHARGE both (or all) banks
    state_precharge:  begin
        assert_we    <= #1 1'b0;
        sd_cs_l      <= #1 1'b0;
    	sd_ras_l     <= #1 1'b0;
    	sd_cas_l     <= #1 1'b1;
        sd_dqm       <= #1 4'hF;
        load_address <= #1 1'b0 ;
        load_dqm     <= #1 1'b0 ;

        if (precharge_time_expired)
        begin
		    next_state  <= #1 state_idle;
            precharge_to_ras_count_enable <= #1 1'b0 ;
        end
        else
        begin
            next_state <= #1 state_delay_Trp;
        end
    end

    // Delay Trp
    // this delay is needed to meet the minimum precharge to new command
    // delay.  For most parts, this is 20nS, which means you need 1 clock cycle
    // of NOP at 100MHz
    state_delay_Trp:  begin
        sd_cs_l     <= #1 1'b1;
      	sd_ras_l    <= #1 1'b1;
        if (precharge_time_expired)
        begin
            next_state <= #1 state_idle ;
            precharge_to_ras_count_enable <= #1 1'b0 ;
        end
    end


    // Autorefresh
    state_auto_refresh: begin
        sd_cs_l     <= #1 1'b0;
    	sd_ras_l    <= #1 1'b0;
    	sd_cas_l    <= #1 1'b0;
        next_state  <= #1 state_auto_refresh_dly;
        autorefresh_cntr_l  <= #1 1'b1;  //allow refresh delay cntr (Trc) to tick
        do_refresh_ack <= #1 1'b1;      // acknowledge refresh request
     end

    // This state generates the Trc delay.
    // this delay is the delay from the refresh command to the next valid command
    // most parts require this to be 60 to 70nS.  So at 100MHz, we need at least
    // 6 NOPs.

⌨️ 快捷键说明

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