/* Copyright 2009 DJ Delorie Released under the terms of the GNU General Public License, either version 2 or, at your choice, any later version. http://www.delorie.com/electronics/sdram/ */ `timescale 1ns / 1ps /* The Rules No signal shall be assigned in more than one always block, without a really good reason. Edge-triggered always blocks use nonblocking assignment <= Level-triggered always blocks use blocking assignment = IFs must always have ELSEs when level-triggered. There are two clocks - the external clock, and the internal clock. The internal clock is delayed relative to the external clock, to position the eye in the right spot (prop delay vs setup/hold times). Setup and hold times: tCMS= 1.5 nS tCMH= 0.8 nS tAS = 1.5 nS tAH = 0.8 nS tDS = 1.5 nS tDS = 0.8 nS So, we have a 2.3 nS eye window in a 7.5 nS cycle, or about 33% of the cycle. All SDRAM signals are sampled on the rising edge of the clock. We make changes to the signals on the rising edge of the internal clock, as well as sample then. Propogation delay will ensure hold times are met (somehow ;). Input signals clock-latched on any MCU signal end in _c; signals registered on the RAM clock end in _r. Combinatorial logic for setting up the next state is named "new_*". */ module djsdram_simple1 ( reset, mcu_cs, mcu_nwrl, mcu_nwrh, mcu_nrd, mcu_ready, mcu_addr, mcu_data, ram_wclock, ram_rclock, ram_clock_enable, ram_ncs, ram_nwe, ram_ncas, ram_nras, ram_dqm, ram_bank, ram_addr, ram_data, state, newstate, rstate ); localparam /* sdram timing */ ram_clock_period_ps = 7700, /* 130 MHz */ tRCD = 15000 / ram_clock_period_ps - 1, tRAS = 37000 / ram_clock_period_ps - 1, tWR = 14500 / ram_clock_period_ps - 1, tRP = 15000 / ram_clock_period_ps - 1, tRFC = 66000 / ram_clock_period_ps, /* 4096 refreshes per 64 mS = 15,625 nS per refresh */ //tREF = 15625000 / ram_clock_period_ps - 1, tREF = 5625000 / ram_clock_period_ps - 1, tMRD = 2, cas_latency = 3, /* This is the MCU time from data ready to asserting READY. This should account for the time between sensing ready and reading the data, and the setup time for the data. */ /* 35 (data setup) - 15 (ready setup) */ tsu_DB_BCLK = 20000 / ram_clock_period_ps - 1; input reset; input mcu_cs; input mcu_nwrl; input mcu_nwrh; input mcu_nrd; output mcu_ready; input [23:0] mcu_addr; inout [15:0] mcu_data; /* This clock is for our state machine, and is sent out to the chip along with most of the signals. We change signals on the falling edge. */ input ram_wclock; /* This clock is delayed according to the IOB and trace propagation delays. We sample the data on the rising edge. */ input ram_rclock; output ram_clock_enable; output ram_ncs; output ram_nwe; output ram_ncas; output ram_nras; output [1:0] ram_dqm; output [1:0] ram_bank; output [11:0] ram_addr; inout [15:0] ram_data; output [4:0] state; output [4:0] rstate; output [4:0] newstate; reg mcu_nwrl_r; reg mcu_nwrh_r; reg mcu_nrd_r; /*------------------------------------------------------------------*/ localparam s_reset = 0, s_reset2 = 1, s_stabilize = 2, s_precharge_all = 3, s_precharge_wait = 4, s_autorefresh1 = 5, s_autorefresh1_wait = 6, s_autorefresh2 = 7, s_autorefresh2_wait = 8, s_load_mode = 9, s_wait_mode = 10, /* This is where we wait for something to happen. */ s_idle = 16, /* These states are run when we see nRD active. */ s_read_activate = 17, s_read_activated = 18, s_read_cas = 19, s_read_delay = 20, s_read_data = 21, s_read_hold = 22, s_read_wait = 23, /* These states are run when we see nWRL/nWRH active. */ s_write_activate = 24, s_write_postactivate = 25, s_write_data = 26, s_write_wait = 27, /* refresh states. */ s_refresh = 28, s_refresh_wait = 29, s_max = 31; /*------------------------------------------------------------------*/ reg mcu_ready; reg ram_nras; reg ram_ncas; reg ram_nwe; reg ram_ncs; reg ram_clock_enable; reg [11:0] ram_addr; reg [1:0] ram_dqm; reg auto_precharge; reg [11:0] new_ram_addr; reg new_ram_nras; reg new_ram_ncas; reg new_ram_nwe; wire mcu_nwr = mcu_nwrl_r & mcu_nwrh_r; wire mcu_any = mcu_nrd_r & mcu_nwrl_r & mcu_nwrh_r; reg [1:0] mcu_dqm_c; reg [23:0] mcu_addr_c; reg [15:0] mcu_data_c; wire [11:0] ram_row_addr = mcu_addr_c[22:11]; wire [11:0] ram_col_addr = {1'b0, auto_precharge, 1'b0, mcu_addr_c[23], mcu_addr_c[8:1]}; wire [1:0] ram_bank_addr = mcu_addr_c[10:9]; reg mcu_data_write; reg ram_data_write; reg [15:0] ram_rdata_r; assign mcu_data = mcu_data_write ? ram_rdata_r : 16'bz; assign ram_data = ram_data_write ? mcu_data_c : 16'bz; assign ram_bank = ram_bank_addr; reg [4:0] new_state; reg [4:0] state; reg [4:0] rstate; reg [15:0] timer_count; reg [15:0] new_timer_count; wire timer_done = (timer_count == 16'b0); reg [14:0] refresh_timeout; reg refresh_needed; reg refresh_running; reg new_mcu_ready; assign newstate = new_state; //assign ram_data[3:0] = state[3:0]; //assign ram_data[10] = state[4]; //assign ram_data[11] = ram_data_write; //assign ram_data[12] = mcu_data_write; //assign ram_data[13] = mcu_dqm_c[0]; //assign ram_data[14] = mcu_dqm_c[1]; /*------------------------------------------------------------------*/ wire any_wait = (state == s_write_wait) | (state == s_read_wait); always @(negedge ram_wclock) begin mcu_nwrl_r <= mcu_nwrl; mcu_nwrh_r <= mcu_nwrh; mcu_nrd_r <= mcu_nrd; //if (state == s_idle) //begin mcu_dqm_c <= { mcu_nrd_r & mcu_nwrh_r, mcu_nrd_r & mcu_nwrl_r }; mcu_addr_c <= mcu_addr; //end end always @(negedge mcu_nwr) begin mcu_data_c <= mcu_data; end always @(posedge ram_wclock) begin rstate <= state; end //always @(posedge ram_rclock) begin // if (rstate == s_read_data) // ram_rdata_r <= ram_data; //end always @(negedge ram_wclock) begin if (rstate == s_read_data) ram_rdata_r <= ram_data; end always @(negedge ram_wclock) begin if (reset) begin refresh_running <= 0; refresh_needed <= 0; refresh_timeout <= tREF; end else if (refresh_timeout == 0) begin refresh_timeout <= tREF; refresh_needed <= 1; end else if (refresh_running) refresh_timeout <= refresh_timeout - 1; case (new_state) s_load_mode: refresh_running <= 1; s_refresh: refresh_needed <= 0; endcase // case (new_state) end //always @(negedge mcu_any or posedge mcu_ready_done) begin // if (mcu_ready_done) // mcu_ready <= 1; // else // mcu_ready <= 0; //end always @(timer_count) begin if (timer_count == 0) new_timer_count = 0; else new_timer_count = timer_count - 1; end always @(negedge ram_wclock) begin case (new_state) s_reset: timer_count <= 100000000 / ram_clock_period_ps - 1; s_reset2: timer_count <= 100000000 / ram_clock_period_ps - 1; s_precharge_all: timer_count <= tRP; s_autorefresh1: timer_count <= tRFC; s_autorefresh2: timer_count <= tRFC; s_load_mode: timer_count <= tMRD; s_read_activate: timer_count <= tRCD; s_write_activate: timer_count <= tRCD; s_read_cas: timer_count <= cas_latency - 1; s_read_data: timer_count <= tsu_DB_BCLK; s_refresh: timer_count <= tRFC; default: timer_count <= new_timer_count; endcase // case (state) end always @(negedge ram_wclock) begin if (reset) state <= s_reset; else state <= new_state; ram_addr <= new_ram_addr; ram_nras <= new_ram_nras; ram_ncas <= new_ram_ncas; ram_nwe <= new_ram_nwe; mcu_ready <= new_mcu_ready; end always @( state or reset or timer_done or mcu_cs or mcu_nrd_r or mcu_nwr or mcu_nwrh_r or mcu_nwrl_r or mcu_dqm_c or ram_col_addr or ram_row_addr or mcu_any or refresh_needed ) begin new_state = s_reset; ram_clock_enable = 1; ram_ncs = 0; new_ram_nwe = 1; new_ram_ncas = 1; new_ram_nras = 1; ram_dqm = 2'b00; new_ram_addr = 16'bX; ram_data_write = 0; mcu_data_write = 0; new_mcu_ready = 0; auto_precharge = 1; if (reset) new_state = s_reset; else begin case (state) /*----------------------------------------*/ s_reset: begin if (~reset) new_state = s_reset2; else new_state = s_reset; end s_reset2: begin ram_ncs = 1; new_state = s_stabilize; end s_stabilize: begin new_state = s_stabilize; if (timer_done) new_state = s_precharge_all; end s_precharge_all: begin new_ram_nras = 0; new_ram_nwe = 0; new_ram_addr = 16'hfff; /* all banks */ new_state = s_precharge_wait; end s_precharge_wait: begin new_state = s_precharge_wait; if (timer_done) new_state = s_autorefresh1; end s_autorefresh1: begin new_ram_nras = 0; new_ram_ncas = 0; new_state = s_autorefresh1_wait; end s_autorefresh1_wait: begin new_state = s_autorefresh1_wait; if (timer_done) new_state = s_autorefresh2; end s_autorefresh2: begin new_ram_nras = 0; new_ram_ncas = 0; new_state = s_autorefresh2_wait; end s_autorefresh2_wait: begin new_state = s_autorefresh2_wait; if (timer_done) new_state = s_load_mode; end s_load_mode: begin new_ram_nras = 0; new_ram_ncas = 0; new_ram_nwe = 0; //new_ram_addr = 12'b001000100000; // resv wb=1 mode cas=2 seq burst=1 new_ram_addr = {2'b00, 1'b1, 2'b00, 3'b010, 1'b0, 3'b001}; new_state = s_wait_mode; end s_wait_mode: begin new_state = s_wait_mode; if (timer_done) new_state = s_idle; end /*----------------------------------------*/ // We don't always set mcy_ready here because the m32c has huge // setup requirements, and if we pick the refresh state here, // we'll miss the write. s_idle: begin new_ram_addr = ram_row_addr; new_state = s_idle; if (refresh_needed) begin new_state = s_refresh; end else if (mcu_cs) new_state = s_idle; else if (~mcu_nrd_r) begin // The mcu_nrd signal is asyncronous, so don't use it here // to set RAS as the setup times might not be met. new_state = s_read_activate; end else if (~mcu_nwr) begin ram_data_write = 1; new_state = s_write_activate; end end /*----------------------------------------*/ s_read_activate: begin new_ram_nras = 0; new_ram_addr = ram_row_addr; mcu_data_write = 1; new_state = s_read_activated; end s_read_activated: begin new_ram_addr = ram_col_addr; mcu_data_write = 1; new_state = s_read_activated; ram_dqm = 2'b00; if (timer_done) new_state = s_read_cas; end s_read_cas: begin new_ram_ncas = 0; new_ram_addr = ram_col_addr; ram_dqm = 2'b00; mcu_data_write = 1; new_state = s_read_delay; end s_read_delay: begin new_ram_addr = ram_col_addr; ram_dqm = 2'b00; mcu_data_write = 1; new_state = s_read_delay; if (timer_done) new_state = s_read_data; end s_read_data: begin new_ram_addr = ram_col_addr; ram_dqm = 2'b00; mcu_data_write = 1; new_state = s_read_hold; end s_read_hold: begin new_ram_addr = ram_row_addr; ram_dqm = 2'b00; mcu_data_write = 1; new_state = s_read_hold; if (timer_done) begin new_state = s_read_wait; end end s_read_wait: begin new_ram_addr = ram_row_addr; new_mcu_ready = 1; mcu_data_write = 1; new_state = s_read_wait; if (mcu_any) begin ram_clock_enable = 1; new_state = s_idle; end end /*----------------------------------------*/ s_write_activate: begin new_ram_nras = 0; new_ram_addr = ram_row_addr; ram_data_write = 1; ram_dqm = mcu_dqm_c; new_state = s_write_postactivate; end s_write_postactivate: begin new_ram_addr = ram_col_addr; ram_dqm = mcu_dqm_c; ram_data_write = 1; new_state = s_write_data; end s_write_data: begin new_ram_ncas = 0; new_ram_nwe = 0; new_ram_addr = ram_col_addr; ram_dqm = mcu_dqm_c; ram_data_write = 1; new_state = s_write_wait; end s_write_wait: begin new_ram_addr = ram_col_addr; ram_data_write = 1; ram_dqm = mcu_dqm_c; new_mcu_ready = 1; new_state = s_write_wait; if (mcu_any) begin new_state = s_idle; end end /*----------------------------------------*/ s_refresh: begin new_ram_nras = 0; new_ram_ncas = 0; new_state = s_refresh_wait; end s_refresh_wait: begin new_state = s_refresh_wait; if (timer_done) begin new_state = s_idle; end end /*----------------------------------------*/ endcase // case (state) end // else: !if(reset) end endmodule // msi_simple1