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 10 to Rev 11
    Reverse comparison

Rev 10 → Rev 11

/tags/sdram_30_nov_1999/inc.h
0,0 → 1,89
// Uncomment below to use the microprocessor bus simulator
// ====================
`define simulate_mp
 
// Uncomment the below to enable the debug pins
// ====================
//`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 16
 
// 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 85000
 
// SDRAM clock frequency in Hz.
// Set this to whatever the clock rate is
//`define Fsystem 12500000
`define Fsystem 6250000
 
 
// Clock divider
// Only choose one of these
//`define divide_by_2
`define divide_by_4
//`define divide_by_8
 
//***********************************************************
// 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_cool_off `TS'b1001
`define state_x1 `TS'b0000
`define state_x2 `TS'b1000
//`define state_x3 `TS'h10
//`define state_x4 `TS'h11
 
 
// Fresh timer states
`define state_count 3'b001
`define state_halt 3'b010
`define state_reset 3'b100
 
/tags/sdram_30_nov_1999/sdramcnt.v
0,0 → 1,451
`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 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 sd_ldqm;
output sd_udqm;
output sd_clke;
 
// 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;
 
// Debug
output [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 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 [12:0] autorefresh_cntr;
reg autorefresh_cntr_l;
 
assign sd_clke = `HI; // clk always enabled
 
// 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;
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 counter
always @(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
 
/tags/sdram_30_nov_1999/hostcont.v
0,0 → 1,352
`include "inc.h"
 
/*
** HOSTCONT.v
**
** This module is the host controller whic sits between the host
** (usually a micro) and the sdramcnt.v
**
**
**
**
*/
 
 
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,
 
// SDRAM side connections
sd_addx,
sd_data,
sd_ba,
sd_wr_l,
 
// SDRAMCNT side
sd_addx10_mux,
sd_addx_mux,
sd_rd_ena,
sd_data_ena,
do_read,
do_write,
doing_refresh,
do_modeset,
next_state,
modereg_cas_latency,
modereg_burst_length,
mp_data_mux,
 
// bus type select
smart_h
 
// debug
// rd_wr_clk
,dumb_busy_out
,dumb_busy_clk,
reg_mp_data_mux
 
);
 
 
// ****************************************
//
// 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 [19:0] mp_addx; // 20 bits for the addx
input [15:0] mp_data_in; // 16 bits of data bus input
output [15:0] mp_data_out; // 16 bits of data bus output
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
 
// SDRAM side connections
output [10:0] sd_addx; // 11 bits of muxed SDRAM addx
inout [15:0] sd_data; // 16 bits of bidirectional SDRAM data bus
output sd_ba; // bank select output to the SDRAM
input sd_wr_l;
 
// SDRAMCNT side
input [1:0] sd_addx10_mux;
input [1:0] sd_addx_mux;
input sd_rd_ena;
input sd_data_ena;
output do_write;
output do_read;
input doing_refresh;
output do_modeset;
input [3:0] next_state;
output [2:0] modereg_cas_latency;
output [2:0] modereg_burst_length;
input mp_data_mux;
 
// other inputs
input smart_h; // If high, indicates that writes are non
// blocking if SDRAM is not busy. Else,
// all IO are blocked
 
//debug
//output rd_wr_clk;
output dumb_busy_clk;
output dumb_busy_out;
output [15:0] reg_mp_data_mux;
 
// ****************************************
//
// Memory Elements
//
// ****************************************
//
reg [19:0] reg_mp_addx;
reg [15:0] reg_mp_data;
reg [15:0] reg_sd_data;
`ifdef simulate_mp
wire [10:0] reg_modeset;
`else
reg [10:0] reg_modeset;
`endif
reg [10:0] sd_addx;
reg do_read;
reg do_write;
reg do_modeset;
reg sd_ba;
reg rst_do_write;
wire [15:0] sd_data;
wire [15:0] sd_data_buff;
wire [15:0] reg_mp_data_mux;
wire [15:0] mp_data_out;
wire mp_data_ena;
wire do_read_clk;
wire do_write_clk;
wire clock_xx;
wire modereg_ena;
wire read_busy;
wire write_busy;
wire refresh_busy;
wire do_write_rst;
wire dumb_busy_clk;
wire dumb_busy_rst;
reg rst_dumb_busy;
reg dumb_busy_out;
wire dumb_busy;
 
assign mp_data_out = reg_sd_data;
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;
assign write_busy = do_write;
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 | dumb_busy | doing_refresh);
 
 
// MP ADDRESS LATCH
// Transparent latch
// Used to hold the addx from the micro. Latch on the falling edge of
// mp_rd_l or mp_wr_l
always @(do_write or sys_rst_l or mp_addx)
if (~sys_rst_l)
reg_mp_addx <= 20'h00000;
else if (~do_write) // hold the addx if do_write==`HI
reg_mp_addx <= mp_addx;
else
reg_mp_addx <= reg_mp_addx;
 
// MP DATA LATCH
// Used to hold the data from the micro. Latch on the rising edge
// of mp_wr_l
always @(posedge mp_wr_l or negedge sys_rst_l)
if (~sys_rst_l)
reg_mp_data <= 16'h0000;
else if (~mp_cs_l)
reg_mp_data <= mp_data_in;
 
 
// MODE REG LATCH
`ifdef simulate_mp
assign reg_modeset = 11'h0020;
`else
assign modereg_ena = ~mp_cs_l & ~sdram_mode_set_l;
always @(posedge mp_wr_l or negedge sys_rst_l)
if (~sys_rst_l)
reg_modeset <= 11'h0020; // default modeset reg value has this settings:
// burst length=1, cas latency=2
else if (modereg_ena)
reg_modeset <= mp_data_in;
`endif
 
 
// SD DATA LATCH
always @(posedge sys_clk or negedge sys_rst_l)
if (~sys_rst_l)
reg_sd_data <= 16'h0000;
else if (sd_rd_ena)
reg_sd_data <= sd_data_buff;
 
 
// SDRAM SIDE ADDX
always @(sd_addx10_mux or reg_mp_data or reg_mp_addx)
case (sd_addx10_mux)
// 2'b00: sd_addx[10] <= 1'b0;
// 2'b01: sd_addx[10] <= reg_mp_addx[10];
2'b00: sd_addx[10] <= reg_mp_addx[18];
2'b01: sd_addx[10] <= 1'b0;
2'b10: sd_addx[10] <= reg_mp_data[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[9:0];
// 2'b01: sd_addx[9:0] <= {2'b00, reg_mp_addx[18:11]};
2'b00: sd_addx[9:0] <= reg_mp_addx[17:8]; // ROW
2'b01: sd_addx[9:0] <= {2'b00, reg_mp_addx[7:0]}; // 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[19];
2'b01: sd_ba <= reg_mp_addx[19];
default: sd_ba <= 1'b0;
endcase
 
 
// SD SIDE DATA BUFFERS
assign sd_data = sd_data_ena ? reg_mp_data_mux : 16'hzzzz;
assign sd_data_buff = sd_data;
 
 
// Micro data mux
assign reg_mp_data_mux = mp_data_mux ? 16'h0000 : reg_mp_data;
 
 
//
// DO_READ signal generation
//
// Set by falling edge of mp_rd_l
// cleared by the falling edge of next_state==`state_read
assign do_read_clk = ( mp_rd_l | (next_state==`state_read) );
always @(negedge do_read_clk or negedge sys_rst_l)
if (~sys_rst_l)
do_read <= `LO;
else
do_read <= ~do_read;
 
 
 
// DO_WRITE signal generation logic
// This signal indicates that the SDRAM is performing a write
// this is a completely asynchronous logic which does the following:
// the do_write is
// set at rising edge of mp_wr_l (at deassertion of micro write bus cycle)
// cleared on the rising edge of sd_wr_l. That is, at the termination of
// current SDRAM write cycle. This excludes the sd_wr_l generated during the
// refresh cycle.
assign do_write_rst = ~sys_rst_l | rst_do_write;
always @(posedge mp_wr_l or posedge do_write_rst)
if (do_write_rst)
do_write <= `LO;
else
do_write <= `HI;
 
always @(posedge sd_wr_l or posedge do_write_rst)
if (do_write_rst)
rst_do_write <= `LO;
else if (~doing_refresh) // reset only is we're not a refresh cycle
rst_do_write <= `HI;
 
 
//
// DO_MODESET signal generation
//
// needs to be triggered by falling edge of
always @(sys_clk or sys_rst_l)
if (sys_rst_l)
do_modeset <= `LO;
else
do_modeset <= `LO;
 
 
 
//
// DUMB BUSY SIGNAL GENERATION
//
// In the "dumb" mode (smart_h == 0), the SDRAM controller will
// not allow the micro to do another I/O until the
// present one is finished. The most notable difference is
// that it will not allow a "dump-&-run" writes.
//
// The busy signal is asserted at the falling edge of mp_cs_l.
// In the case of writes, it is deasserted when mp_rw_l goes low. This
// allows the micro to deassert its wr (i.e. finish the write bus cycle)
// at which point the busy is again asserted (since the SDRAM is now being written)
// until the completion of the write into the SDRAM.
// During reads, the busy is asserted on the falling edge of mp_cs_l, and is not
// deasserted until the completion of the read.
//
// The busy signal is the or of DO_WRITE , DO_READ as before, but
// in the smart_h=0 mode, an extra signal dumb_busy_out is also or'd.
// This signal is set at the falling edge of mp_cs_l. It is cleared
// on the falling edge of mp_wr_l or on the rising edge of do_read.
// (mp_wr_l ^ do_read)
//
// It is set by the falling edge of MP_CS_L
// is is cleared by the rising edge of DO_READ or
// falling edge of mp_WR_L
assign dumb_busy = (dumb_busy_out & ~smart_h);
always @(negedge mp_cs_l or posedge dumb_busy_rst)
if (dumb_busy_rst)
dumb_busy_out <= `LO;
else
dumb_busy_out <= `HI;
 
assign dumb_busy_rst = ~sys_rst_l | rst_dumb_busy;
assign dumb_busy_clk = do_read ^ mp_wr_l;
always @(negedge dumb_busy_clk or posedge dumb_busy_rst)
if (dumb_busy_rst)
rst_dumb_busy <= `LO;
else
rst_dumb_busy <= `HI;
 
endmodule
 
/tags/sdram_30_nov_1999/tst_inc.h
0,0 → 1,65
//
// Common Definition File for the SDRAM TEST
//
//
 
 
//******* Allow showing of debug signals
//`define do_debug
 
//******* Allow the micro bus model to have queues for read and write
//`define allow_queue
 
/*
** SELECT TEST TO PERFORM
** Select only one of the below comment
**
*/
// ***************************************************************
// This test repeats indefinitely, a write followed by a read.
// ***************************************************************
//`define do_read_write_test
 
 
// ***************************************************************
// This test does a burst write, followed by a delay (enough to
// fit a few refresh cycles) then burst read of the same memory
// areas. This pattern of write-read repeats indefinitely
// ***************************************************************
//`define do_burst_write_read_test
 
// ***************************************************************
// 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
 
 
// ***************************************************************
// This test exercises the entire content of the SDRAM.
// A pseudo-random-number-generator is used to generate the data
// patern which is written to the SDRAM. Then, the data is read
// back and compared to the psedo random number.
// ***************************************************************
`define do_full_test
 
// C O M M O N S T U F F
`define HI 1'b1
`define LO 1'b0
 
// B U S C O N T R O L L E R
// This defines the bit width of the bus controller State Machine
`define MN 3
`define MNn `MN-1
// This defines the states of the state machine
`define state_idle `MN'b001
`define state_assert_addx `MN'b010
`define state_wr_l `MN'b011
`define state_wr_h `MN'b110
`define state_rd_l `MN'b111
`define state_rd_h `MN'b101
`define state_deassert_addx `MN'b100
`define xxxx `MN'b000
 
/tags/sdram_30_nov_1999/sdram.v
0,0 → 1,375
`include "inc.h"
 
//
// SDRAM Controller.
//
// Hierarchy:
//
// SDRAM.V Wrapper.
// 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_main_clk,
sys_rst_l,
sys_clk,
 
// SDRAM CONNECTIONS
sd_clke,
sd_clk,
sd_wr_l,
sd_cs_l,
sd_ras_l,
sd_cas_l,
sd_ldqm,
sd_udqm,
sd_addx,
sd_data,
sd_ba,
 
// MICROPORCESSOR CONNECTION
mp_addx,
mp_data,
mp_rd_l,
mp_wr_l,
mp_cs_l,
sdram_mode_set_l,
sdram_busy_l,
smart_h,
 
// DEBUG
`ifdef show_debug
,
next_state,
do_modeset,
do_read,
do_write,
autorefresh_cntr,
autorefresh_cntr_l,
pwrup,
top_state,
wr_cntr,
// mp_data_micro,
reg_mp_data_mux,
// mp_data_mux,
sd_data_ena,
doing_refresh,
mp_data_out,
// sd_addx_mux,
// sd_addx10_mux,
sd_rd_ena,
// dumb_busy_clk,
// dumb_busy_out
// rd_wr_clk
`endif
// simulated micro bus
`ifdef simulate_mp
,
//mp_clk,
`endif
 
 
);
 
 
 
 
 
// ****************************************
//
// I/O DEFINITION
//
// ****************************************
// SYSTEM LEVEL CONNECTIONS
input sys_main_clk;
input sys_rst_l;
output sys_clk;
 
// SDRAM CONNECTIONS
output sd_clke;
output sd_clk;
output sd_wr_l;
output sd_cs_l;
output sd_ras_l;
output sd_cas_l;
output sd_ldqm;
output sd_udqm;
output [10:0] sd_addx;
inout [15:0] sd_data;
output sd_ba;
 
// MICROPORCESSOR CONNECTION
`ifdef simulate_mp
output [19:0] mp_addx;
output mp_rd_l;
output mp_wr_l;
output mp_cs_l;
output [15:0] mp_data;
`else
input [19:0] mp_addx;
input mp_rd_l;
input mp_wr_l;
input mp_cs_l;
inout [15:0] mp_data;
`endif
output sdram_busy_l;
input sdram_mode_set_l;
input smart_h;
 
// DEBUG
`ifdef show_debug
output [3:0] next_state;
output do_modeset;
output do_read;
output do_write;
output [12:0] autorefresh_cntr;
output autorefresh_cntr_l;
output pwrup;
output [2:0] top_state;
output [7:0] wr_cntr;
//output [15:0] mp_data_micro;
output [15:0] reg_mp_data_mux;
output [15:0] mp_data_out;
//output mp_data_mux;
output sd_data_ena;
output doing_refresh;
//output sd_addx_mux;
//output sd_addx10_mux;
output sd_rd_ena;
//output rd_wr_clk;
//output dumb_busy_clk;
//output dumb_busy_out;
`endif
 
// simulated micro bus
`ifdef simulate_mp
//input mp_clk;
`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 [15:0] mp_data_out;
wire [15:0] sd_data;
wire mp_cs_l;
wire mp_wr_l;
wire mp_rd_l;
wire mp_data_mux;
wire [12:0] autorefresh_cntr;
wire autorefresh_cntr_l;
wire pwrup;
wire [2:0] top_state;
 
`ifdef simulate_mp
wire [19:0] mp_addx;
wire [15:0] mp_data_inbus;
wire [15:0] mp_data_micro;
`endif
wire sdram_mode_set_l;
wire sys_clk;
//wire rd_wr_clk;
wire sdram_busy_l;
 
`ifdef simulate_mp
wire mp_clk;
`endif
 
 
`ifdef simulate_mp
assign mp_data = ~(mp_rd_l | mp_cs_l) ? mp_data_out : mp_data_micro;
`else
assign mp_data = ~(mp_rd_l | mp_cs_l) ? mp_data_out : 16'hzzzz;
`endif
 
 
/*
*/
//
// CLOCK GENERATOR
//
//
 
// --divide by 2
//
`ifdef divide_by_2
reg sd_clk;
always @(posedge sys_main_clk)
sd_clk <= ~sd_clk;
 
assign sys_clk = sd_clk;
`endif
 
// --divide by 4
//
`ifdef divide_by_4
reg [1:0] sd_clk;
always @(posedge sys_main_clk)
sd_clk <= sd_clk + 2'b01;
 
assign sys_clk = sd_clk[1];
`endif
 
// --divide by 8
//
`ifdef divide_by_8
reg [2:0] sd_clk;
always @(posedge sys_main_clk)
sd_clk <= sd_clk + 3'b001;
 
assign sys_clk = sd_clk[2];
`endif
 
assign mp_clk = sys_clk;
 
sdramcnt SDRAMCNT(
// system level stuff
.sys_rst_l(sys_rst_l),
.sys_clk(sys_clk),
// SDRAM connections
.sd_clke(sd_clke),
.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_ldqm(sd_udqm),
.sd_udqm(sd_ldqm),
// 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),
 
// debug
.next_state(next_state),
.autorefresh_cntr(autorefresh_cntr),
.autorefresh_cntr_l(autorefresh_cntr_l),
.pwrup(pwrup)
);
 
 
hostcont HOSTCONTTT(
// 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_data_micro),
`else
.mp_data_in(mp_data),
`endif
.mp_data_out(mp_data_out),
.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),
 
// SDRAM side connections
.sd_addx(sd_addx),
.sd_data(sd_data),
.sd_ba(sd_ba),
.sd_wr_l(sd_wr_l),
 
// SDRAMCNT side
.sd_addx10_mux(sd_addx10_mux),
.sd_addx_mux(sd_addx_mux),
.sd_rd_ena(sd_rd_ena),
.sd_data_ena(sd_data_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),
.next_state(next_state),
.mp_data_mux(mp_data_mux),
 
// other inputs
.smart_h(smart_h)
 
// debug
// .rd_wr_clk(rd_wr_clk)
,.dumb_busy_clk(dumb_busy_clk),
.dumb_busy_out(dumb_busy_out),
.reg_mp_data_mux(reg_mp_data_mux)
);
 
 
`ifdef simulate_mp
micro MICRO (
// system connections
.mp_clk(mp_clk),
.sys_rst_l(sys_rst_l),
 
// Connections to the SDRAM CONTROLLER
.sdram_busy_l(sdram_busy_l),
.mp_addx(mp_addx),
.mp_data(mp_data_micro),
.mp_wr_l(mp_wr_l),
.mp_rd_l(mp_rd_l),
.mp_cs_l(mp_cs_l),
.next_state(next_state),
 
// debug
.top_state(top_state),
.wr_cntr(wr_cntr)
);
 
`endif
 
endmodule
 
//
// REVISION LOG
//
// 7/31/99
// Added/tested/debugged support for interfacing to Intel type of
// Microprocessors, where it is required that the device "busy" be asserted
// when the chip_select decoded. That is before it is known whether it is
// a read or a write cycle
// This is called the "non-smart" interface, where all bus request from the
// micro is blocked until it is completed. It is enabled by pulling low
// on the smart_h pin.
//
//
// 8/15/99
// Made the width of the AutoRefresh Command to be 1+ CLKs. By just having it
// to be 1 CLK, the burst reads (back to back 1 word reads, not SDRAM "burst" reads)
// would be all messed up if a refresh happened to coem in the middle. By making
// the refresh command to be more than 1 CLK (2 or more) this problem was
// eliminated.
//
/tags/sdram_30_nov_1999/micro.v
0,0 → 1,366
`include "tst_inc.h"
`include "inc.h"
module micro(
// system connections
mp_clk,
sys_rst_l,
 
// Connections to the HOSTCONT.V
sdram_busy_l,
mp_addx,
mp_data,
mp_wr_l,
mp_rd_l,
mp_cs_l,
 
next_state,
 
// debug
top_state,
wr_cntr
);
 
 
 
// system connections
input mp_clk; // main system clock
input sys_rst_l; // main system reset
 
// connections to the SDRAM CONTROLLER
input sdram_busy_l;
output [19:0] mp_addx;
output mp_wr_l;
output mp_rd_l;
output mp_cs_l;
input [3:0] next_state;
output [15:0] mp_data;
 
// debug
output [2:0] top_state;
output [7:0] wr_cntr;
 
// Intermodule connections
wire [7:0] bus_state;
wire data_ena;
wire [15:0] mp_data;
wire mp_wr_l;
wire mp_rd_l;
wire mp_cs_l;
 
 
// Memory element definitions
reg req_wr_l;
reg req_rd_l;
reg change_addx;
reg data_addx_rst_l;
 
// INSTANTIATE THE MICRO BUS
sim_mp SIM_MP(
// system connections
.mp_clk(mp_clk),
.sys_rst_l(sys_rst_l),
 
// inputs
.req_wr_l(req_wr_l),
.req_rd_l(req_rd_l),
.sdram_busy_l(sdram_busy_l),
.change_addx(change_addx),
.data_addx_rst_l(data_addx_rst_l),
 
// outputs
.mp_addx(mp_addx),
.mp_data(mp_data),
.mp_wr_l(mp_wr_l),
.mp_rd_l(mp_rd_l),
.mp_cs_l(mp_cs_l),
.state(bus_state),
.data_ena(data_ena)
 
);
 
 
/*
** SINGLE WRITE FOLLOWED BY GAP THEN FOLLOWED BY SINGLE READ TEST
**
*/
`ifdef do_read_write_test
`define NN 8
`define NNn `NN-1
`define delay `NN'h20
reg [2:0] top_state;
reg [`NNn:0] cntr;
reg rst_cntr;
`define do_read 3'h0
`define do_write 3'h1
`define do_read_wait 3'h2
`define do_write_wait 3'h3
`define do_wait 3'h4
`define powerup_wait 3'h5
 
// Top level state machie
always @(posedge mp_clk or negedge sys_rst_l)
if (~sys_rst_l) begin
req_wr_l <= `HI; // do not request any writes
req_rd_l <= `HI; // do not request any reads
change_addx <= `LO; // do not change addx
top_state <= `powerup_wait;
rst_cntr <= `HI;
data_addx_rst_l <= `LO; // reset the data and addx counters
cntr <= `NN'h00; // initialize the counter
end
else case (top_state)
`powerup_wait: begin
data_addx_rst_l <= `HI; // allow the data and addx to count up
if (next_state == `state_idle)
top_state <= `do_write;
end
 
`do_write: begin
change_addx <= `HI; // tell bus controller to increment addx/data
req_wr_l <= `LO; // request a micro write
top_state <= `do_write_wait;
end
`do_write_wait: begin
change_addx <= `LO; // done incrementing addx/data
req_wr_l <= `HI; // done requesting the write
if (bus_state == `state_deassert_addx) begin
top_state <= `do_wait;
rst_cntr <= `LO;
end
end
 
`do_wait: begin
if (cntr == `delay) begin
top_state <= `do_read;
rst_cntr <= `HI;
cntr <= `NN'h00; // reset the counter
end
cntr <= cntr + 1; // increment the counter
end
 
`do_read: begin
req_rd_l <= `LO; // request a read from the micro simulator
top_state <= `do_read_wait;
end
 
`do_read_wait: begin
req_rd_l <= `HI; // done requesting the read
if (bus_state == `state_deassert_addx) begin
top_state <= `do_write;
end
end
endcase
 
 
// Counter to count the events
always @(posedge mp_clk or posedge rst_cntr)
if (rst_cntr)
cntr <= 8'h000;
else
cntr <= cntr + 1;
 
`endif
 
 
/*
** BURST WRITE FOLLOWED BY GAP THEN FOLLOWED BY BURST READ TEST
**
*/
`ifdef do_burst_write_read_test
`define MN 8
`define MNn `MN-1
`define RW_COUNT `MN'h20
`define GAP_DELAY `MN'h40
reg [2:0] top_state;
reg rst_cntr;
//reg [`XY-1:0] cntr;
reg [`MNn:0] wr_cntr;
`define powerup_delay 3'h1
`define burst_write 3'h2
`define burst_write_wait 3'h3
`define write_read_delay 3'h4
`define burst_read 3'h5
`define burst_read_wait 3'h6
 
 
always @(posedge mp_clk or negedge sys_rst_l)
if (~sys_rst_l) begin
top_state <= `powerup_delay;
req_wr_l <= `HI; // do not request any writes
req_rd_l <= `HI; // do not request any reads
change_addx <= `LO; // do not change addx
rst_cntr <= `HI; // reset counter
wr_cntr <= `MN'h00;
data_addx_rst_l <= `LO; // reset the data and addx counter
end
else case (top_state)
`powerup_delay: begin
data_addx_rst_l <= `HI; // allow the data and the addx couter to count up
if (next_state == `state_idle) begin
top_state <= `burst_write; // go and do burst write
end
end
`burst_write: begin
req_wr_l <= `LO; // request a write
top_state <= `burst_write_wait;
change_addx <= `LO; // done changing addx
end
 
`burst_write_wait: begin
req_wr_l <= `HI; // done requesting a write
if (bus_state == `state_deassert_addx) begin
if (wr_cntr == `RW_COUNT) begin
top_state <= `write_read_delay; // go and do reads
rst_cntr <= `LO; // allow counter to go up
wr_cntr <= `MN'h00; // clear write counter
end else begin
wr_cntr <= wr_cntr + `MN'h1;
change_addx <= `HI; // increment addx
top_state <= `burst_write;
end
end
end
 
// Wait for a bit to allow several refrehes into the SDRAM
`write_read_delay: begin
if (wr_cntr == `GAP_DELAY) begin
data_addx_rst_l <= `HI; // allow the data and the addx couter to count up
rst_cntr <= `HI; // reset counter
wr_cntr <= `MN'h00; // clear write counter
top_state <= `burst_read;
end else begin
wr_cntr <= wr_cntr + `MN'h1; // count up by one
data_addx_rst_l <= `LO; // reset the data and addx counters
end
end
 
`burst_read: begin
req_rd_l <= `LO; // request read
top_state <= `burst_read_wait;
change_addx <= `LO; // done changing addx
end
 
`burst_read_wait: begin
req_rd_l <= `HI; // done requesting a read
if (bus_state == `state_deassert_addx) begin
if(wr_cntr == `RW_COUNT) begin
data_addx_rst_l <= `LO; // reset the addx and data couters
top_state <= `powerup_delay;
wr_cntr <= 5'h00; // clear write counter
end else begin
top_state <= `burst_read;
change_addx <= `HI; // inc addx
wr_cntr <= wr_cntr + 1;
end
end
end
endcase
 
`endif
 
 
/*
** A ONE-TIME BURST WRITE FOLLOWED BY GAP THEN FOLLOWED BY MANY BURST READ TEST
**
*/
`ifdef do_single_burst_write_read_test
 
`define MN 8
`define RW_COUNT 8'h5
`define GAP_DELAY 8'h10
 
reg [2:0] top_state;
reg rst_cntr;
reg [7:0] wr_cntr;
 
`define powerup_delay 3'h1
`define burst_write 3'h2
`define burst_write_wait 3'h3
`define write_read_delay 3'h4
`define burst_read 3'h5
`define burst_read_wait 3'h6
 
 
always @(posedge mp_clk or negedge sys_rst_l)
if (~sys_rst_l) begin
top_state <= `powerup_delay;
req_wr_l <= `HI; // do not request any writes
req_rd_l <= `HI; // do not request any reads
change_addx <= `LO; // do not change addx
rst_cntr <= `HI; // reset counter
wr_cntr <= 8'h00; // reset the cycle counter
data_addx_rst_l <= `LO; // reset the data and addx counter
end
else case (top_state)
`powerup_delay: begin
if (next_state == `state_idle) begin
top_state <= `burst_write;// go and do burst write
end else
data_addx_rst_l <= `HI; // allow the data and the addx couter to count up
end
`burst_write: begin
req_wr_l <= `LO; // request a write
top_state <= `burst_write_wait;
change_addx <= `LO; // done changing addx
end
 
`burst_write_wait: begin
req_wr_l <= `HI; // done requesting a write
if (bus_state == `state_deassert_addx) begin
if (wr_cntr == `RW_COUNT) begin
top_state <= `write_read_delay; // go and do reads
rst_cntr <= `LO; // allow counter to go up
data_addx_rst_l <= `LO; // reset the data and addx counters
wr_cntr <= 8'h00;
end else begin
wr_cntr <= wr_cntr + 8'h1;
top_state <= `burst_write;
change_addx <= `HI; // increment addx
end
end
end
 
// Wait for a bit to allow several refrehes into the SDRAM
`write_read_delay: begin
if (wr_cntr == `GAP_DELAY) begin
data_addx_rst_l <= `HI; // allow the data and the addx couter to count up
rst_cntr <= `HI; // reset counter
wr_cntr <= 8'h00;
top_state <= `burst_read;
end else
wr_cntr <= wr_cntr + 8'h1;
end
 
`burst_read: begin
req_rd_l <= `LO; // request read
top_state <= `burst_read_wait;
change_addx <= `LO; // done changing addx
end
 
`burst_read_wait: begin
req_rd_l <= `HI; // done requesting a read
if (bus_state == `state_deassert_addx) begin
if(wr_cntr == `RW_COUNT) begin
data_addx_rst_l <= `LO; // reset the addx and data couters
top_state <= `write_read_delay;
wr_cntr <= 8'h00;
end else begin
wr_cntr <= wr_cntr + 1;
top_state <= `burst_read;
change_addx <= `HI; // inc addx
end
end
end
endcase
 
`endif
 
 
endmodule
 

powered by: WebSVN 2.1.0

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