OpenCores
URL https://opencores.org/ocsvn/sdram/sdram/trunk

Subversion Repositories sdram

Compare Revisions

  • This comparison shows the changes necessary to convert path
    /
    from Rev 6 to Rev 7
    Reverse comparison

Rev 6 → Rev 7

/tags/sdram_8Mb_2Mx32_020200/inc.h
0,0 → 1,220
//*******************************************************************************
// 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.
//
/*
*/
 
 
// Uncomment below to use the microprocessor bus simulator
// This will turn this IP into a "SDRAM" tester.
// Once you enable this option, choose the test mode in
// the file "tst_inc.h"
// ====================
//`define simulate_mp
 
// Uncomment the below to enable the debug pins
// If you are in an FPGA/CPLD platform be *CAREFULL*. This will
// generate a lot of pins. Use it with causion.
// ====================
//`define show_debug
 
 
// Common definition stuff
`define HI 1'b1
`define LO 1'b0
`define X 1'bx
 
//***********************************************************
// U S E R M O D I F I A B L E S
//***********************************************************
 
// The number of refreshses done at power up. 16 by default
`define power_up_ref_cntr_limit 3
 
// The number of refreshes done during normal refresh cycle.
// Set this to be 2048 for "burst" refreshes, and
// set this to be 1 for "regular" refreshes
`define auto_ref_cntr_limit 1
 
// Refresh Frequency in Hz.
// For burst refresh use 33Hz (30mS)
// For normal refresh use 66666Hz (15uS)
`define Frefresh 66666
 
// Type of Data Bus
// Unididrectiona: the top hierachy module SDRAM.V will have seperate 32 bit
// data buses for reads and writes. This is useful for embedding the
// core in a larger core.
// Birectional: the top hierarchy module SDRAM.V will have a biredirectional 32bit
// data bus. This is useful if the SDRAM controller core is to be a
// stand-alone module.
//
// Comment the below for bidirectional bus, and UNcomment for unidirectional
`define databus_is_unidirectional
 
// SDRAM DATA BUS TYPE
//
//
`define sdram_data_bus_is_unidirectional
 
 
// DATA BUS ALIGNING
// With this option enabled (uncomment below) half-word accesses are aligned to lower
// bus DATA[15:0], and byte accesses are aligned to DATA[7:0]. This is ideal when a
// 8 bit micro or host wants to access all of the space of the 16/32 bit SDRAM.
 
// data bus aligning ON: (uncomment the below define)
// a 16 bit write should have the data to the SDRAM controller on D[15:0].
// a 16 bit read will have the data returned by the SDRAM conroller on D[15:0].
// a 8 bit write should have the data to the SDRAM controller on D[7:0].
// a 8 bit read will have the data returned by the SDRAM controller on D[7:0].
//
// data bus aligning OFF: (comment the below define)
// a 16 bit write should have the data to the SDRAM controller on D[31:16] or
// D[15:0] depending on the state of A[1] (A[1]=1, on D[31:16], A[1]=0 on
// D[15:0].
// a 16 bit read will have the data returned by the SDRAM controller on D[31:16]
// or D[15:0], based on the state of A[1].
// similar thought process for 8 bit write and reads.
//
//`define align_data_bus
 
 
// SDRAM clock frequency in Hz.
// Set this to whatever the clock rate is
`define Fsystem 2000000
//`define Fsystem 100000000
 
 
 
 
// DEFAULT MODE-REGISTER values
// The below is programmed to the mode regsiter at
// powerup
`define default_mode_reg_BURST_LENGHT 3'b000
`define defulat_mode_reg_BURST_TYPE 1'b0
`define default_mode_reg_CAS_LATENCY 3'b010
 
 
//***********************************************************
// D O N O T M O D I F Y
//***********************************************************
// Interval between refreshes in SDRAM clk ticks
`define RC `Fsystem/`Frefresh
 
// Width of the refresh counter. Default 20. log2(`RC)/log2
// use 8 bits for 15uS interval with 12.5MHz clock
//`define BW 8
`define BW 20
 
// The refresh delay counter width
`define RD 3
 
// This sets the number of delay cycles right after the refresh command
`define AUTO_REFRESH_WIDTH 1
 
// MAin SDRAM controller state machine definition
`define TS 4
`define TSn `TS-1
 
`define state_idle `TS'b0001
`define state_set_ras `TS'b0011
`define state_ras_dly `TS'b0010
`define state_set_cas `TS'b0110
`define state_cas_latency1 `TS'b0111
`define state_cas_latency2 `TS'b0101
`define state_write `TS'b0100
`define state_read `TS'b1100
`define state_auto_refresh `TS'b1101
`define state_auto_refresh_dly `TS'b1111
`define state_precharge `TS'b1110
`define state_powerup `TS'b1010
`define state_modeset `TS'b1011
`define state_delay_Trp `TS'b0000
`define state_delay_Tras1 `TS'b1000
`define state_delay_Tras2 `TS'b1001
 
// Fresh timer states
`define state_count 3'b001
`define state_halt 3'b010
`define state_reset 3'b100
 
/tags/sdram_8Mb_2Mx32_020200/sdramcnt.v
0,0 → 1,644
`include "inc.h"
 
 
//*******************************************************************************
// 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 sdramcnt(
// system level stuff
sys_rst_l,
sys_clk,
// SDRAM connections
sd_wr_l,
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,
 
// debug
next_state,
autorefresh_cntr,
autorefresh_cntr_l,
cntr_limit
 
);
 
parameter N1 = 4;
 
// ****************************************
//
// I/O DEFINITION
//
// ****************************************
 
 
// System level stuff
input sys_rst_l;
input sys_clk;
 
// SDRAM connections
output sd_wr_l;
output sd_cs_l;
output sd_ras_l;
output sd_cas_l;
output [(N1-1):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;
 
// Debug
output [3:0] next_state;
output [3:0] autorefresh_cntr;
output autorefresh_cntr_l;
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 [3:0] sd_dqm;
reg [1:0] sd_addx_mux;
reg [1:0] sd_addx10_mux;
reg sd_data_ena;
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 [2:0] refresh_state;
reg mp_data_mux;
wire 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;
 
wire Trc_expired, Ref_expired;
 
assign Trc_expired = (autorefresh_cntr == 4'h6);
assign Ref_expired = (refresh_cntr == cntr_limit);
 
// State Machine
always @(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; // high indicates we've just power'd up or RESET
sd_wr_l <= `HI;
sd_cs_l <= `HI;
sd_ras_l <= `HI;
sd_cas_l <= `HI;
sd_dqm <= 4'hF;
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;
do_write_ack <= `LO; // do not ack as reset default
do_read_ack <= `LO; // do not ack as reset default
do_modeset_ack <= `LO; // do not ack as reset default
do_refresh_ack <= `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_dqm <= 4'hF;
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 (or all) banks
`state_precharge: begin
sd_wr_l <= `LO;
sd_cs_l <= `LO;
sd_ras_l <= `LO;
sd_cas_l <= `HI;
sd_dqm <= 4'hF;
sd_addx10_mux <= 2'b11; // A10 = 1'b1
next_state <= `state_idle;
if (do_write_ack)
do_write_ack<= `LO; // done acknowledging the write request
if (do_read_ack)
do_read_ack <= `LO; // done acknowledging the read request
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_wr_l <= `HI;
sd_cs_l <= `HI;
sd_ras_l <= `HI;
if ( (refresh_cntr == cntr_limit) & (pwrup == `HI) ) begin
doing_refresh <= `LO; // refresh cycle is done
refresh_cntr_l <= `LO; // ..reset refresh counter
next_state <= `state_modeset; // if this was power-up, then go and set mode reg
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_addx10_mux <= 2'b01; // A10 = 0
next_state <= `state_auto_refresh_dly;
autorefresh_cntr_l <= `HI; //allow refresh delay cntr (Trc) to tick
do_refresh_ack <= `HI; // 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.
`state_auto_refresh_dly: begin
sd_wr_l <= `HI;
sd_cs_l <= `HI;
sd_ras_l <= `HI;
sd_cas_l <= `HI;
sd_addx10_mux <= 2'b00; // select ROW again A10 = A20
/*
casex ( {Trc_expired, Ref_expired, pwrup, (do_write|do_read)} )
// Trc not expired yet
4'b0xxx: begin
next_state <= `state_auto_refresh_dly;
do_refresh_ack <= `LO;
end
// Back-back refreshes not done yet
4'b10xx: begin
autorefresh_cntr_l <= `LO; // reset Trc delay counter
next_state <= `state_auto_refresh;
end
 
// This is powerup run, so go and set modereg
4'b110x: begin
autorefresh_cntr_l <= `LO; // reset Trc delay counter
doing_refresh <= `LO; // refresh cycle is done
refresh_cntr_l <= `LO; // ..reset refresh counter
next_state <= `state_modeset;
end
 
4'b1111: begin
autorefresh_cntr_l <= `LO; // reset Trc delay counter
doing_refresh <= `LO; // refresh cycle is done
refresh_cntr_l <= `LO; // ..reset refresh counter
next_state <= `state_set_ras; // go service a pending read or write if any
end
 
4'b1110: begin
autorefresh_cntr_l <= `LO; // reset Trc delay counter
doing_refresh <= `LO; // refresh cycle is done
refresh_cntr_l <= `LO; // ..reset refresh counter
next_state <= `state_idle; // go service a pending read or write if any
end
endcase
*/
// Wait for Trc
if (autorefresh_cntr == 4'h6) begin
autorefresh_cntr_l <= `LO; // reset Trc delay counter
// Check if the number of specified back-back refreshes are done
if (refresh_cntr == cntr_limit) begin
doing_refresh <= `LO; // refresh cycle is done
refresh_cntr_l <= `LO; // ..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)
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
// if this is part of power-up sequencing, we need to go and
// set mode register.
else
next_state <= `state_modeset;
end
// IF refresh cycles not done yet, keep issuing autorefresh commands
else
next_state <= `state_auto_refresh;
end
// If Trc has not expired
else begin
next_state <= `state_auto_refresh_dly;
do_refresh_ack <= `LO;
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;
sd_addx_mux <= 2'b10;
sd_addx10_mux <= 2'b10;
doing_refresh <= `LO; // deassert
if (pwrup)
pwrup <= `LO; // ..no more in power up mode
if (do_mode_set)
do_modeset_ack <= `LO;
end
 
 
 
// IDLE state
`state_idle: begin
sd_wr_l <= `HI;
sd_cs_l <= `HI;
sd_ras_l <= `HI;
sd_cas_l <= `HI;
sd_data_ena <= `LO; // turn off the data bus drivers
mp_data_mux <= `LO; // drive the SD data bus with normal data
sd_addx_mux <= 2'b00; // select ROW (A[19:10]) of mp_addx to SDRAM
sd_addx10_mux <= 2'b00; // select ROW (A[20]) " "
 
// 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 (do_refresh | pwrup) begin
doing_refresh <= `HI; // indicate that we're doing refresh
refresh_cntr_l <= `HI; // allow refresh cycle counter to count up
next_state <= `state_auto_refresh;
end
 
// if a single word rad or write request is pending, go and service it
else if (do_write | do_read )
next_state <= `state_set_ras;
 
// if a mode register set is requested, go and service it
else if (do_mode_set) begin
do_modeset_ack <= `HI; // acknowledge the mode set request
next_state <= `state_modeset;
doing_refresh <= `HI; // techincally we're not doing refresh, but
end // this signal is used to prevent the do_write be deasserted
// by the mode_set command.
 
end
 
// SET RAS state
`state_set_ras: begin
sd_cs_l <= `LO; // enable SDRAM
sd_ras_l <= `LO; // enable the RAS
next_state <= `state_ras_dly; // wait for a bit
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 <= `HI; // disable SDRAM
sd_ras_l <= `HI; // disble the RAS
sd_addx_mux <= 2'b01; // select COLUMN
sd_addx10_mux <= 2'b01; // select COLUMN
if (do_write) begin
sd_data_ena <= `HI; // turn on the data bus drivers
sd_dqm <= decoded_dqm; // masks the data which is meant to be
next_state <= `state_write; // if write, do the write
end else begin
sd_dqm <= 4'h0;
next_state <= `state_set_cas; // if read, do the read
end
end
 
// WRITE state
`state_write: begin
sd_cs_l <= `LO; // enable SDRAM
sd_cas_l <= `LO; // enable the CAS
sd_wr_l <= `LO; // enable the write
do_write_ack<= `HI; // acknowledge the write request
sd_dqm <= 4'hF;
next_state <= `state_delay_Tras1;
end
 
`state_delay_Tras1: begin
sd_wr_l <= `HI;
sd_cs_l <= `HI;
sd_ras_l <= `HI;
sd_cas_l <= `HI;
sd_dqm <= 4'hF;
sd_addx_mux <= 2'b00; // send ROW (A[19:10]) of mp_addx to SDRAM
sd_addx10_mux <= 2'b00; // send ROW (A[20]) " "
mp_data_mux <= `HI; // drive the SD data bus with all zeros
next_state <= `state_delay_Tras2;
end
 
`state_delay_Tras2: begin
next_state <= `state_precharge;
end
 
 
// SET CAS state
`state_set_cas: begin
sd_cs_l <= `LO;
sd_cas_l <= `LO;
sd_dqm <= 4'hF;
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
do_read_ack <= `HI; // acknowledge the read request (do it here due to the latency)
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
do_read_ack <= `HI; // acknowledge the read request (do it here due to the latency)
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_precharge;
 
sd_wr_l <= `HI;
sd_cs_l <= `HI;
sd_ras_l <= `HI;
sd_cas_l <= `HI;
sd_addx_mux <= 2'b00; // send ROW (A[19:10]) of mp_addx to SDRAM
sd_addx10_mux <= 2'b00; // send ROW (A[20]) " "
mp_data_mux <= `HI; // drive the SD data bus with all zeros
 
end else begin
sd_rd_ena <= `HI; // enable the read latch on the next state
next_state <= `state_read;
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 autorefresh_cntr_l)
if (~autorefresh_cntr_l)
autorefresh_cntr <= 4'h0;
else
autorefresh_cntr <= autorefresh_cntr + 1;
 
 
 
// This mux selects the cycle limit value for the
// auto refresh counter.
// During power-up sequencing, we need to do `power_up_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)
`HI: cntr_limit <= `power_up_ref_cntr_limit;
default: cntr_limit <= `auto_ref_cntr_limit;
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
//
// 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 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) begin
refresh_timer <= refresh_timer + 1;
refresh_state <= `state_count;
end else begin
refresh_state <= `state_halt;
refresh_timer <= 0;
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:
/* if (next_state==`state_auto_refresh |
next_state==`state_auto_refresh_dly |
next_state==`state_precharge )
refresh_state <= `state_reset;
*/
if (do_refresh_ack)
refresh_state <= `state_count;
 
// 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
 
/tags/sdram_8Mb_2Mx32_020200/hostcont.v
0,0 → 1,532
`include "inc.h"
 
//*******************************************************************************
// 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 hostcont (
// system connections
sys_rst_l,
sys_clk,
 
// microprocessor side connections
mp_addx,
mp_data_in,
mp_data_out,
mp_rd_l,
mp_wr_l,
mp_cs_l,
sdram_mode_set_l,
sdram_busy_l,
mp_size,
 
// SDRAM side connections
sd_addx,
sd_data_out,
sd_data_in,
sd_ba,
 
// SDRAMCNT side
sd_addx10_mux,
sd_addx_mux,
sd_rd_ena,
do_read,
do_write,
doing_refresh,
do_modeset,
modereg_cas_latency,
modereg_burst_length,
mp_data_mux,
decoded_dqm,
do_write_ack,
do_read_ack,
do_modeset_ack,
pwrup,
 
 
// debug
// rd_wr_clk
reg_mp_data_mux,
reg_mp_addx,
reg_sd_data,
reg_modeset
 
);
 
 
// ****************************************
//
// I/O DEFINITION
//
// ****************************************
 
// system connections
input sys_rst_l; // asynch active low reset
input sys_clk; // clock source to the SDRAM
 
// microprocessor side connections
input [22:0] mp_addx; // ABW bits for the addx
input [31:0] mp_data_in; // DBW bits of data bus input (see INC.H)
output [31:0] mp_data_out; // DBW bits of data bus output (see INC.H)
input mp_rd_l; // micro bus read , active low
input mp_wr_l; // micro bus write, active low
input mp_cs_l;
input sdram_mode_set_l; // acive low request for SDRAM mode set
output sdram_busy_l; // active low busy output
input [1:0] mp_size;
 
// SDRAM side connections
output [10:0] sd_addx; // 11 bits of muxed SDRAM addx
input [31:0] sd_data_in;
output [31:0] sd_data_out;
output [1:0] sd_ba; // bank select output to the SDRAM
input pwrup;
 
// SDRAMCNT side
input [1:0] sd_addx10_mux;
input [1:0] sd_addx_mux;
input sd_rd_ena;
output do_write;
output do_read;
input doing_refresh;
output do_modeset;
output [2:0] modereg_cas_latency;
output [2:0] modereg_burst_length;
input mp_data_mux;
output [3:0] decoded_dqm; // this is the decoded DQM according to the size. Used during writes
input do_write_ack; // acknowledge signal from sdramcont state machine
// saying that it is now ok to clear 'do_write' signal
input do_read_ack; // acknowledge signal from sdramcont state machine
// saying that is is now ok to clear 'do_read' signal
input do_modeset_ack;
 
 
//debug
//output rd_wr_clk;
output [31:0] reg_mp_data_mux;
output [22:0] reg_mp_addx;
output [31:0] reg_sd_data;
output [10:0] reg_modeset;
 
// ****************************************
//
// Memory Elements
//
// ****************************************
//
wire [22:0] reg_mp_addx;
reg [31:0] reg_mp_data;
reg [31:0] reg_sd_data;
reg [3:0] decoded_dqm;
reg [10:0] reg_modeset;
reg [10:0] sd_addx;
reg do_read;
reg do_write;
reg [2:0] do_state;
reg do_modeset;
reg [1:0] sd_ba;
reg busy_a_ena;
 
//wire [31:0] sd_data;
wire [31:0] sd_data_buff;
wire [31:0] reg_mp_data_mux;
reg [31:0] mp_data_out;
wire busy_a;
wire mp_data_ena;
wire do_read_clk;
wire do_read_rst_clk;
wire do_write_clk;
wire do_modeset_clk;
wire do_modeset_rst_clk;
wire clock_xx;
wire modereg_ena;
wire read_busy;
wire write_busy;
wire refresh_busy;
wire modeset_busy;
wire do_write_rst;
wire do_read_rst;
wire do_modeset_rst;
 
assign mp_data_ena = ~mp_rd_l;
assign modereg_cas_latency = reg_modeset[6:4];
assign modereg_burst_length = reg_modeset[2:0];
 
assign read_busy = do_read | (~mp_rd_l & busy_a_ena);
assign write_busy = do_write | (~mp_wr_l & busy_a_ena);
assign modeset_busy = do_modeset;
assign refresh_busy = `LO;
 
// SDRAM BUSY SIGNAL GENERATION
//
// The BUSY signal is NOR'd of READ_BUSY, WRITE_BUSY and DUMB_BUSY.
// READ_BUSY is generated while the SDRAM is performing a read. This
// does not necessarily have to he synchronous to the micro's read.
// The WRITE_BUSY is generated while the SDRAM is performing WRITE.
// Again, due to the "dump-n-run" mode (only in SMART_H=1) the micro's
// write bus cycle does not necessarily align with SDRAM's write cycle.
// DUMB_BUSY is a signal which generates the BUSY at the falling edge of
// micro's SDRAM_CS. This is used for those microprocessors which
// require a device BUSY as soon as the address is placed on its bus. For
// example, most Intel microcontrollers and small processors do have this
// requirement. This means that one will fofeit on the dump-n-go feature.
//
assign sdram_busy_l = ~( read_busy |
write_busy |
(doing_refresh & ~mp_cs_l)|
(modeset_busy & ~mp_cs_l)
);
 
 
// MP ADDRESS LATCH
// Transparent latch
// Used to hold the addx from the micro. Latch on the falling edge of
// do_write.
// BAsed on the way "do_write" is generated, we only need to latch on the writes
// since the write can be queued, but since all reads are blocked, the latch
// will not latch the addx on reads.
assign reg_mp_addx = mp_addx;
 
 
//
// DECODED DQM LATCH
// generate the proper DQM[3:0] masks based on the address and on the mp_size
//
always @(do_write or sys_rst_l or mp_addx or mp_size)
// 32 bit masks
// all masks are enabled (LOW)
if (mp_size==2'b00)
decoded_dqm <= 4'h0;
// 16 bit masks
// enable the masks accorsing to the half-word selected
else if (mp_size==2'b10)
case (mp_addx[1])
`LO: decoded_dqm <= 4'b1100; // lower half-word enabled
default: decoded_dqm <= 4'b0011; // upper half-word enabled
endcase
// 8 bit masks
// enablethe masks according to the byte specified.
else if (mp_size==2'b01)
case (mp_addx[1:0])
2'b00: decoded_dqm <= 4'b1110;
2'b01: decoded_dqm <= 4'b1101;
2'b10: decoded_dqm <= 4'b1011;
default: decoded_dqm <= 4'b0111;
endcase
else
decoded_dqm <= 4'bxxxx;
 
 
// MP DATA LATCH
// Used to hold the data from the micro. Latch on the rising edge
// of mp_wr_l
//
`ifdef align_data_bus
always @(mp_data_in or reg_mp_addx)
// 32 bit writes
if (mp_size==2'b00)
reg_mp_data <= mp_data_in;
// 16 bit writes
else if (mp_size==2'b10)
case(reg_mp_addx[1])
`LO: reg_mp_data[15:0] <= mp_data_in[15:0];
default: reg_mp_data[31:16] <= mp_data_in[15:0];
endcase
// 8 bit writes
else if (mp_size==2'b01)
case(reg_mp_addx[1:0])
2'b00: reg_mp_data[7:0] <= mp_data_in[7:0];
2'b01: reg_mp_data[15:8] <= mp_data_in[7:0];
2'b10: reg_mp_data[23:16] <= mp_data_in[7:0];
default: reg_mp_data[31:24] <= mp_data_in[7:0];
endcase
//---------------------------------- if data aligning is not desired -------------------
`else
always @(mp_data_in)
reg_mp_data <= mp_data_in;
`endif
 
 
//
// MODE REG REG
//
`define default_mode_reg {4'b0000,`default_mode_reg_CAS_LATENCY,`defulat_mode_reg_BURST_TYPE,`default_mode_reg_BURST_LENGHT}
always @(posedge sys_clk or negedge sys_rst_l)
if (~sys_rst_l)
reg_modeset <= 10'h000;
else
if (pwrup)
reg_modeset <= `default_mode_reg;
else
if (~sdram_mode_set_l & ~mp_cs_l & ~mp_wr_l)
reg_modeset <= mp_data_in[10:0];
 
// SD DATA REGISTER
// This register holds in the data from the SDRAM
//
always @(posedge sys_clk or negedge sys_rst_l)
if (~sys_rst_l)
reg_sd_data <= 32'h00000000;
else if (sd_rd_ena)
reg_sd_data <= sd_data_buff;
 
 
//
// SD DATA BUS BUFFERS
//
assign sd_data_out = reg_mp_data;
assign sd_data_buff = sd_data_in;
 
 
 
// SDRAM SIDE ADDX
always @(sd_addx10_mux or reg_mp_data or reg_mp_addx or reg_modeset)
case (sd_addx10_mux)
2'b00: sd_addx[10] <= reg_mp_addx[20];
2'b01: sd_addx[10] <= 1'b0;
2'b10: sd_addx[10] <= reg_modeset[10];
default: sd_addx[10] <= 1'b1;
endcase
 
always @(sd_addx_mux or reg_modeset or reg_mp_addx)
case (sd_addx_mux)
2'b00: sd_addx[9:0] <= reg_mp_addx[19:10]; // ROW
2'b01: sd_addx[9:0] <= {2'b00, reg_mp_addx[9:2]}; // COLUMN
2'b10: sd_addx[9:0] <= reg_modeset[9:0];
default: sd_addx[9:0] <= 10'h000;
endcase
 
 
// SD_BA
always @(sd_addx_mux or reg_mp_addx)
case (sd_addx_mux)
2'b00: sd_ba <= reg_mp_addx[22:21];
2'b01: sd_ba <= reg_mp_addx[22:21];
default: sd_ba <= 2'b00;
endcase
 
 
 
// Micro data mux
assign reg_mp_data_mux = mp_data_mux ? 32'h00000000 : reg_mp_data;
 
// MP_DATA_OUT mux
// ------------------------------- do this only if the DATA aligning is desired -------
`ifdef align_data_bus
always @(mp_size or reg_sd_data or mp_addx)
case (mp_size)
// 32 bit reads
2'b00:
mp_data_out <= reg_sd_data;
// 16 bit reads
2'b10:
if (mp_addx[1])
mp_data_out[15:0] <= reg_sd_data[31:16];
else
mp_data_out[15:0] <= reg_sd_data[15:0];
// 8 bit reads
default:
case (mp_addx[1:0])
2'b00: mp_data_out[7:0] <= reg_sd_data[7:0];
2'b01: mp_data_out[7:0] <= reg_sd_data[15:0];
2'b10: mp_data_out[7:0] <= reg_sd_data[23:16];
default: mp_data_out[7:0] <= reg_sd_data[31:24];
endcase
endcase
`else
//---------------------------------- if data aligning is not desired -------------------
always @(reg_sd_data)
mp_data_out <= reg_sd_data;
`endif
 
//
// DO_READ DO_WRITE DO_MODESET
// signal generation
//
 
always @(posedge sys_clk or negedge sys_rst_l)
if (~sys_rst_l) begin
do_read <= `LO;
do_write <= `LO;
do_modeset <= `LO;
do_state <= 3'b000;
busy_a_ena <= `HI;
end
else
case (do_state)
// hang in here until a read or write is requested
// (mp_rd_l = 1'b0) or (mp_wr_l = 1'b0)
3'b000: begin
// a read request
if (~mp_rd_l & ~mp_cs_l) begin
do_read <= `HI;
do_state <= 3'b001;
end
// a write request
else if (~mp_wr_l & ~mp_cs_l & sdram_mode_set_l) begin
do_write <= `HI;
do_state <= 3'b001;
end
// a mode set request
else if (~mp_wr_l & ~mp_cs_l & ~sdram_mode_set_l) begin
do_modeset <= `HI;
do_state <= 3'b001;
end
else
do_state <= 3'b000;
end
// This cycle is dummy cycle. Just to extend 'busy_ena_a'
// to a total of 2 cycles
3'b001:
begin
busy_a_ena <= `LO; // disable busy_a generation
if (do_write)
do_state <= 3'b011;
else if (do_read)
do_state <= 3'b010;
else if (do_modeset)
do_state <= 3'b110;
else
do_state <= 3'b001;
end
 
// hang in here until the sdramcnt has acknowledged the
// read
3'b010:
if (do_read_ack) begin
do_read <= `LO;
do_state <= 3'b100;
end
else
do_state <= 3'b010;
 
// hang in here until the sdramcnt has acknowledged the
// write
3'b011:
if (do_write_ack) begin
do_write <= `LO;
do_state <= 3'b101;
end
else
do_state <= 3'b011;
 
// wait in here until the host has read the data
// (i.e. has raised its mp_rd_l high)
3'b100:
if (mp_rd_l) begin
busy_a_ena <= `HI; // re-enable busy_a generation
do_state <= 3'b000;
end
else
do_state <= 3'b100;
// wait in here until the host has relinquieshed the write bus
// (i.e. has raised its mp_wr_l high)
3'b101:
if (mp_wr_l) begin
busy_a_ena <= `HI; // re-enable busy_a generation
do_state <= 3'b000;
end
else
do_state <= 3'b101;
 
// hang in here until the sdramcnt has acknowledged the
// mode set
3'b110:
if (do_modeset_ack) begin
do_modeset <= `LO;
do_state <= 3'b101;
end else
do_state <= 3'b110;
 
 
endcase
 
 
 
endmodule
 
/tags/sdram_8Mb_2Mx32_020200/micro.v
0,0 → 1,327
`include "tst_inc.h"
`include "inc.h"
 
 
//*******************************************************************************
// 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 micro(
// system connections
sys_clk,
sys_rst_l,
 
// Connections to the HOSTCONT.V
sdram_busy_l,
mp_addx,
mp_data_out,
mp_data_in,
mp_wr_l,
mp_rd_l,
mp_cs_l,
mp_size,
next_state,
data_is_correct,
sdram_mode_set_l,
 
// debug
top_state
);
 
 
// ****************************************
//
// I/O DEFINITION
//
// ****************************************
// system connections
input sys_clk; // main system clock
input sys_rst_l; // main system reset
 
// connections to the SDRAM CONTROLLER
input sdram_busy_l;
output [22:0] mp_addx;
output mp_wr_l;
output mp_rd_l;
output mp_cs_l;
output [1:0] mp_size;
input [3:0] next_state;
output [31:0] mp_data_out; // data bus to the SDRAM controller
input [31:0] mp_data_in; // data bus from the SDRAM controller
output data_is_correct;
output sdram_mode_set_l;
 
// debug
output [3:0] top_state;
 
// Intermodule connections
wire [7:0] bus_state;
wire data_ena;
wire [31:0] mp_data_out;
wire [31:0] mp_data_in;
wire [1:0] mp_size;
 
// Memory element definitions
reg [3:0] top_state;
reg mp_cs_l;
reg mp_wr_l;
reg mp_rd_l;
reg [31:0] reg_mp_data_out;
reg [22:0] reg_mp_addx;
reg [22:0] reg_byte_counter;
reg data_is_correct;
reg sdram_mode_set_l;
 
 
/*
** SINGLE WRITE FOLLOWED BY GAP THEN FOLLOWED BY SINGLE READ TEST
**
*/
`ifdef do_read_write_test
`endif
 
 
/*
** BURST WRITE FOLLOWED BY GAP THEN FOLLOWED BY BURST READ TEST
**
*/
`ifdef do_burst_write_read_test
 
`endif
 
 
/*
** A ONE-TIME BURST WRITE FOLLOWED BY GAP THEN FOLLOWED BY MANY BURST READ TEST
**
*/
`ifdef do_single_burst_write_read_test
 
// the number of write/read in the test
`define RW_COUNT 23'h000015
// number of clock ticks between the reads.
`define GAP_DELAY 23'h000030
// define the amount of address delta
`define MP_ADDX_DELTA 23'h000001
// define the amount of data delta
`define MP_DATA_DELTA 32'h01010101
 
 
// Micro Simulator State Machine State Definitions
`define powerup_delay 4'h0
`define burst_write_cs 4'h1
`define burst_write_assert_wr 4'h2
`define burst_write_wait_4_busy 4'h3
`define burst_write_deassert_wr 4'h4
`define burst_wr_rd_delay 4'h5
`define burst_read_cs 4'h6
`define burst_read_assert_rd 4'h7
`define burst_read_wait_4_busy 4'h8
`define burst_read_deassert_rd 4'h9
`define request_modereg 4'ha
 
`define SIZE_IS_BYTE 2'b01
`define SIZE_IS_HALF_WORD 2'b10
`define SIZE_IS_WORD 2'b00
 
 
assign mp_size = `SIZE_IS_BYTE;
assign mp_addx = reg_mp_addx;
assign mp_data_out = reg_mp_data_out;
 
always @(posedge sys_clk or negedge sys_rst_l)
if (~sys_rst_l) begin
top_state <= `powerup_delay; // initialze state
mp_cs_l <= `HI;
mp_wr_l <= `HI;
mp_rd_l <= `HI;
reg_mp_addx <= 23'h000000; // reset address counter
reg_mp_data_out <= 32'h00000000; // reset data counter
reg_byte_counter <= 23'h000000; // clear byte counter
data_is_correct <= `HI; // correct by default
sdram_mode_set_l <= `HI; // do not issue mode reg change by default
end
else case (top_state)
 
// Wait until the SDRAM has completed its power-up sequences
`powerup_delay: begin
sdram_mode_set_l <= `HI;
if (next_state==`state_idle)
top_state <= `burst_write_cs;// go and do burst write
else
top_state <= `powerup_delay;
end
// Assert MP CS to begin the write
`burst_write_cs: begin
mp_cs_l <= `LO;
top_state <= `burst_write_assert_wr;
end
 
// Assert MP WR
`burst_write_assert_wr: begin
mp_wr_l <= `LO;
top_state <= `burst_write_wait_4_busy;
end
// Wait until the SDRAM controller is no longer busy
`burst_write_wait_4_busy:
if (~sdram_busy_l)
top_state <= `burst_write_wait_4_busy;
else
top_state <= `burst_write_deassert_wr;
 
// Deassert the WR, and check to see if it has completed all writes
`burst_write_deassert_wr: begin
mp_wr_l <= `HI; // deassert WR
if (reg_byte_counter == `RW_COUNT) begin
reg_mp_addx <= 0;
reg_mp_data_out <= 0;
reg_byte_counter <= 0; // reset the counter
mp_cs_l <= `HI;
top_state <= `burst_wr_rd_delay;
end else begin
reg_mp_addx <= reg_mp_addx + `MP_ADDX_DELTA;
reg_mp_data_out <= reg_mp_data_out + `MP_DATA_DELTA;
reg_byte_counter <= reg_byte_counter + 1; // one IO done
top_state <= `burst_write_assert_wr;
end
end
// Wait here and kill GAP_DELAY number of cycles
`burst_wr_rd_delay:
if (reg_byte_counter != `GAP_DELAY) begin
reg_byte_counter <= reg_byte_counter + 1;
top_state <= `burst_wr_rd_delay;
end else begin
reg_byte_counter <= 23'h000000;
top_state <= `burst_read_cs;
end
 
// Assert MP CS to prepare for reads
`burst_read_cs: begin
mp_cs_l <= `LO; // assert CS
top_state <= `burst_read_assert_rd;
end
// Assert MP RD
`burst_read_assert_rd: begin
mp_rd_l <= `LO;
top_state <= `burst_read_wait_4_busy;
end
 
// Wait until the SDRAM Controller is no longer busy
`burst_read_wait_4_busy:
if (~sdram_busy_l)
top_state <= `burst_read_wait_4_busy;
else
top_state <= `burst_read_deassert_rd;
 
// Deassert MP RD and Prepare for the next resd,
`burst_read_deassert_rd: begin
if (mp_data_in != reg_mp_data_out) begin
data_is_correct <= `LO;
end
mp_rd_l <= `HI; // deassert RD
if (reg_byte_counter == `RW_COUNT) begin
reg_mp_addx <= 0;
reg_mp_data_out <= 0;
reg_byte_counter <= 0; // reset the counter
mp_cs_l <= `HI;
top_state <= `burst_wr_rd_delay;
end else begin
reg_mp_addx <= reg_mp_addx + `MP_ADDX_DELTA; // increment addx
reg_mp_data_out <= reg_mp_data_out + `MP_DATA_DELTA; // increment data expected
reg_byte_counter <= reg_byte_counter + 1; // one IO done
top_state <= `burst_read_assert_rd;
end
end
 
endcase
 
`endif
 
 
endmodule
 
/tags/sdram_8Mb_2Mx32_020200/tst_inc.h
0,0 → 1,106
//*******************************************************************************
// S Y N T H E Z I 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.
//
/*
*/
 
 
/*
** SELECT TEST TO PERFORM
** Select only one of the below comment
**
*/
 
// ***************************************************************
// This test does a one time burst write, followed by a delay (enough to
// fit a few refresh cycles) then burst read of the same memory
// areas. The burst reads are repeating.
// ***************************************************************
`define do_single_burst_write_read_test
 
 
 
// C O M M O N S T U F F
`define HI 1'b1
`define LO 1'b0
 
 
/tags/sdram_8Mb_2Mx32_020200/sdram.v
0,0 → 1,483
`include "inc.h"
 
//*******************************************************************************
// S Y N T H E Z I 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(
// SYSTEM LEVEL CONNECTIONS
sys_rst_l,
sys_clk,
// SDRAM CONNECTIONS
sd_wr_l,
sd_cs_l,
sd_ras_l,
sd_cas_l,
sd_dqm,
sd_addx,
sd_data,
sd_ba,
// MICROPORCESSOR CONNECTION
mp_addx
`ifdef databus_is_unidirectional
,
mp_data_in,
mp_data_out,
`else
,
mp_data,
`endif
mp_rd_l,
mp_wr_l,
mp_cs_l,
sdram_mode_set_l,
sdram_busy_l,
mp_size,
next_state
// DEBUG
`ifdef show_debug
,
next_state,
mp_data_out_sd,
mp_data_gate
do_write,
reg_mp_addx,
reg_mp_data_mux,
sd_addx_mux,
sd_addx10_mux,
next_state,
doing_refresh,
do_modeset,
do_read,
sd_addx_mux,
sd_addx10_mux,
autorefresh_cntr,
autorefresh_cntr_l,
pwrup,
top_state,
wr_cntr,
mp_data_micro,
mp_data_mux,
sd_data_ena,
mp_data_out,
sd_addx_mux,
sd_addx10_mux,
sd_rd_ena
`endif
);
 
 
 
 
 
// ****************************************
//
// I/O DEFINITION
//
// ****************************************
// SYSTEM LEVEL CONNECTIONS
input sys_clk; // global system clock. Runs the sdram state machine
input sys_rst_l; // global active low asynchronous system reset
// SDRAM CONNECTIONS
output sd_wr_l; // SDRAM active low WRITE signal
output sd_cs_l; // SDRAM active low chip select signal
output sd_ras_l; // SDRAM active low RAS
output sd_cas_l; // SDRAM active low CAS
output [3:0] sd_dqm; // SDRAM data masks
output [10:0] sd_addx; // SDRAM multiplexed address bus
inout [31:0] sd_data; // SDRAM birectional data bus 32 bit
output [1:0] sd_ba; // SDRAM bank address , aka A11
// MICROPROCESSOR CONNECTION
`ifdef databus_is_unidirectional
input [31:0] mp_data_in;
output [31:0] mp_data_out;
`else
`ifdef simulate_mp
inout [31:0] mp_data;
`else
output [31:0] mp_data;
`endif
`endif
`ifdef simulate_mp
output [22:0] mp_addx; // HOST address bus. 23 bits for 8Mb
output mp_rd_l; // HOST active low READ
output mp_wr_l; // HOST active low WRITE
output mp_cs_l; // HOST active low chip select
output sdram_mode_set_l;
output [1:0] mp_size; // 00=32bits, 10=16bits, 01=8bits
`else
input [22:0] mp_addx; // HOST address bus. 23 bits for 8Mb
input mp_rd_l; // HOST active low READ
input mp_wr_l; // HOST active low WRITE
input mp_cs_l; // HOST active low chip select
input sdram_mode_set_l;
input [1:0] mp_size; // 00=32bits, 10=16bits, 01=8bits
`endif
output sdram_busy_l;
output [3:0] next_state;
// DEBUG
`ifdef show_debug
output [31:0] mp_data_out_sd;
output mp_data_gate;
output do_write;
output [22:0] reg_mp_addx;
output [31:0] reg_mp_data_mux;
output sd_addx_mux;
output sd_addx10_mux;
output do_modeset;
output do_read;
output doing_refresh;
output [3:0] next_state;
output [12:0] autorefresh_cntr;
output autorefresh_cntr_l;
output pwrup;
output [3:0] top_state;
output [7:0] wr_cntr;
//output[31:0] mp_data_micro;
output [31:0] mp_data_out;
//output mp_data_mux;
output sd_data_ena;
output sd_rd_ena;
`endif
 
 
// INTER-MODULE CONNECTIONS
wire do_modeset;
wire do_read;
wire do_write;
wire doing_refresh;
wire sd_addx_ena;
wire [1:0] sd_addx_mux;
wire [1:0] sd_addx10_mux;
wire sd_rd_ena;
wire sd_data_ena;
wire [2:0] modereg_cas_latency;
wire [2:0] modereg_burst_length;
wire [3:0] next_state;
wire [31:0] mp_data_out_sd;
wire [31:0] mp_data_in;
//wire [31:0] sd_data;
wire mp_cs_l;
wire mp_wr_l;
wire mp_rd_l;
wire mp_data_mux;
wire [3:0] autorefresh_cntr;
wire autorefresh_cntr_l;
wire pwrup;
wire [3:0] top_state;
wire [22:0] reg_mp_addx;
wire [3:0] decoded_dqm;
wire do_write_ack;
wire do_read_ack;
wire do_modeset_ack;
wire [31:0] reg_mp_data_mux;
wire [31:0] sd_data_in;
wire [31:0] sd_data_out;
wire [31:0] reg_sd_data;
wire sdram_mode_set_l;
wire sys_clk;
wire sdram_busy_l;
wire mp_data_gate;
wire [31:0] mp_simulator_data;
 
//
// HOST sie DATA BUS DRISVERS
//
//
//
assign mp_data_gate = (~mp_rd_l & ~mp_cs_l);
// --- Unidirectional Data bus Mos
`ifdef databus_is_unidirectional
`ifdef simulate_mp
assign mp_data_out = mp_data_gate ? mp_data_out_sd : mp_simulator_data;
`else
assign mp_data_out = mp_data_gate ? mp_data_out_sd : 32'h00000000;
`endif
// --- Bi-Directional Data bus Mode
`else
`ifdef simulate_mp
assign mp_data = mp_data_gate ? mp_data_out_sd : mp_simulator_data;
`else
bufif1 m0 (mp_data[0], mp_data_out_sd[0], mp_data_gate);
bufif1 m1 (mp_data[1], mp_data_out_sd[1], mp_data_gate);
bufif1 m2 (mp_data[2], mp_data_out_sd[2], mp_data_gate);
bufif1 m3 (mp_data[3], mp_data_out_sd[3], mp_data_gate);
bufif1 m4 (mp_data[4], mp_data_out_sd[4], mp_data_gate);
bufif1 m5 (mp_data[5], mp_data_out_sd[5], mp_data_gate);
bufif1 m6 (mp_data[6], mp_data_out_sd[6], mp_data_gate);
bufif1 m7 (mp_data[7], mp_data_out_sd[7], mp_data_gate);
bufif1 m8 (mp_data[8], mp_data_out_sd[8], mp_data_gate);
bufif1 m9 (mp_data[9], mp_data_out_sd[9], mp_data_gate);
bufif1 m10 (mp_data[10], mp_data_out_sd[10], mp_data_gate);
bufif1 m11 (mp_data[11], mp_data_out_sd[11], mp_data_gate);
bufif1 m12 (mp_data[12], mp_data_out_sd[12], mp_data_gate);
bufif1 m13 (mp_data[13], mp_data_out_sd[13], mp_data_gate);
bufif1 m14 (mp_data[14], mp_data_out_sd[14], mp_data_gate);
bufif1 m15 (mp_data[15], mp_data_out_sd[15], mp_data_gate);
bufif1 m16 (mp_data[16], mp_data_out_sd[16], mp_data_gate);
bufif1 m17 (mp_data[17], mp_data_out_sd[17], mp_data_gate);
bufif1 m18 (mp_data[18], mp_data_out_sd[18], mp_data_gate);
bufif1 m19 (mp_data[19], mp_data_out_sd[19], mp_data_gate);
bufif1 m20 (mp_data[20], mp_data_out_sd[20], mp_data_gate);
bufif1 m21 (mp_data[21], mp_data_out_sd[21], mp_data_gate);
bufif1 m22 (mp_data[22], mp_data_out_sd[22], mp_data_gate);
bufif1 m23 (mp_data[23], mp_data_out_sd[23], mp_data_gate);
bufif1 m24 (mp_data[24], mp_data_out_sd[24], mp_data_gate);
bufif1 m25 (mp_data[25], mp_data_out_sd[25], mp_data_gate);
bufif1 m26 (mp_data[26], mp_data_out_sd[26], mp_data_gate);
bufif1 m27 (mp_data[27], mp_data_out_sd[27], mp_data_gate);
bufif1 m28 (mp_data[28], mp_data_out_sd[28], mp_data_gate);
bufif1 m29 (mp_data[29], mp_data_out_sd[29], mp_data_gate);
bufif1 m30 (mp_data[30], mp_data_out_sd[30], mp_data_gate);
bufif1 m31 (mp_data[31], mp_data_out_sd[31], mp_data_gate);
assign mp_data_in = mp_data;
`endif
`endif
 
 
//
// SDRAM side bidirectional data bus drivers
//assign sd_data = sd_data_ena ? sd_data_out : 32'hzzzzzzzz;
//
bufif1 b0 (sd_data[0], sd_data_out[0], sd_data_ena);
bufif1 b1 (sd_data[1], sd_data_out[1], sd_data_ena);
bufif1 b2 (sd_data[2], sd_data_out[2], sd_data_ena);
bufif1 b3 (sd_data[3], sd_data_out[3], sd_data_ena);
bufif1 b4 (sd_data[4], sd_data_out[4], sd_data_ena);
bufif1 b5 (sd_data[5], sd_data_out[5], sd_data_ena);
bufif1 b6 (sd_data[6], sd_data_out[6], sd_data_ena);
bufif1 b7 (sd_data[7], sd_data_out[7], sd_data_ena);
bufif1 b8 (sd_data[8], sd_data_out[8], sd_data_ena);
bufif1 b9 (sd_data[9], sd_data_out[9], sd_data_ena);
bufif1 b10 (sd_data[10], sd_data_out[10], sd_data_ena);
bufif1 b11 (sd_data[11], sd_data_out[11], sd_data_ena);
bufif1 b12 (sd_data[12], sd_data_out[12], sd_data_ena);
bufif1 b13 (sd_data[13], sd_data_out[13], sd_data_ena);
bufif1 b14 (sd_data[14], sd_data_out[14], sd_data_ena);
bufif1 b15 (sd_data[15], sd_data_out[15], sd_data_ena);
bufif1 b16 (sd_data[16], sd_data_out[16], sd_data_ena);
bufif1 b17 (sd_data[17], sd_data_out[17], sd_data_ena);
bufif1 b18 (sd_data[18], sd_data_out[18], sd_data_ena);
bufif1 b19 (sd_data[19], sd_data_out[19], sd_data_ena);
bufif1 b20 (sd_data[20], sd_data_out[20], sd_data_ena);
bufif1 b21 (sd_data[21], sd_data_out[21], sd_data_ena);
bufif1 b22 (sd_data[22], sd_data_out[22], sd_data_ena);
bufif1 b23 (sd_data[23], sd_data_out[23], sd_data_ena);
bufif1 b24 (sd_data[24], sd_data_out[24], sd_data_ena);
bufif1 b25 (sd_data[25], sd_data_out[25], sd_data_ena);
bufif1 b26 (sd_data[26], sd_data_out[26], sd_data_ena);
bufif1 b27 (sd_data[27], sd_data_out[27], sd_data_ena);
bufif1 b28 (sd_data[28], sd_data_out[28], sd_data_ena);
bufif1 b29 (sd_data[29], sd_data_out[29], sd_data_ena);
bufif1 b30 (sd_data[30], sd_data_out[30], sd_data_ena);
bufif1 b31 (sd_data[31], sd_data_out[31], sd_data_ena);
assign sd_data_in = sd_data;
 
 
 
 
//
// INSTANTIATE THE SDRAM STATE MACHINE
//
sdramcnt MYSDRAMCNT(
// system level stuff
.sys_rst_l(sys_rst_l),
.sys_clk(sys_clk),
// SDRAM connections
.sd_wr_l(sd_wr_l),
.sd_cs_l(sd_cs_l),
.sd_ras_l(sd_ras_l),
.sd_cas_l(sd_cas_l),
.sd_dqm(sd_dqm),
// Host Controller connections
.do_mode_set(do_modeset),
.do_read(do_read),
.do_write(do_write),
.doing_refresh(doing_refresh),
.sd_addx_mux(sd_addx_mux),
.sd_addx10_mux(sd_addx10_mux),
.sd_rd_ena(sd_rd_ena),
.sd_data_ena(sd_data_ena),
.modereg_cas_latency(modereg_cas_latency),
.modereg_burst_length(modereg_burst_length),
.mp_data_mux(mp_data_mux),
.decoded_dqm(decoded_dqm),
.do_write_ack(do_write_ack),
.do_read_ack(do_read_ack),
.do_modeset_ack(do_modeset_ack),
.pwrup(pwrup),
 
// debug
.next_state(next_state),
.autorefresh_cntr(autorefresh_cntr),
.autorefresh_cntr_l(autorefresh_cntr_l)
);
 
 
 
//
// INSTANTIATE THE HOST INTERFACE LOGIC
//
hostcont MYHOSTCONT(
// system connections
.sys_rst_l(sys_rst_l),
.sys_clk(sys_clk),
 
// microprocessor side connections
.mp_addx(mp_addx),
`ifdef simulate_mp
.mp_data_in(mp_simulator_data),
`else
.mp_data_in(mp_data_in),
`endif
.mp_data_out(mp_data_out_sd),
.mp_rd_l(mp_rd_l),
.mp_wr_l(mp_wr_l),
.mp_cs_l(mp_cs_l),
.sdram_mode_set_l(sdram_mode_set_l),
.sdram_busy_l(sdram_busy_l),
.mp_size(mp_size),
 
// SDRAM side connections
.sd_addx(sd_addx),
.sd_data_in(sd_data),
.sd_data_out(sd_data_out),
.sd_ba(sd_ba),
 
// SDRAMCNT side
.sd_addx10_mux(sd_addx10_mux),
.sd_addx_mux(sd_addx_mux),
.sd_rd_ena(sd_rd_ena),
.do_read(do_read),
.do_write(do_write),
.doing_refresh(doing_refresh),
.do_modeset(do_modeset),
.modereg_cas_latency(modereg_cas_latency),
.modereg_burst_length(modereg_burst_length),
.mp_data_mux(mp_data_mux),
.decoded_dqm(decoded_dqm),
.do_write_ack(do_write_ack),
.do_read_ack(do_read_ack),
.do_modeset_ack(do_modeset_ack),
.pwrup(pwrup),
 
// debug
.reg_mp_data_mux(reg_mp_data_mux),
.reg_mp_addx(reg_mp_addx),
.reg_sd_data(reg_sd_data)
);
 
 
`ifdef simulate_mp
micro SDRAM_TESTER(
// system connections
.sys_clk(sys_clk),
.sys_rst_l(sys_rst_l),
 
// Connections to the HOSTCONT.V
.sdram_busy_l(sdram_busy_l),
.mp_addx(mp_addx),
.mp_data_out(mp_simulator_data),
.mp_data_in(mp_data_out_sd),
.mp_wr_l(mp_wr_l),
.mp_rd_l(mp_rd_l),
.mp_cs_l(mp_cs_l),
.mp_size(mp_size),
.next_state(next_state),
.data_is_correct(data_is_correct),
.sdram_mode_set_l(sdram_mode_set_l),
 
// debug
.top_state(top_state)
);
`endif
 
endmodule
 
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.