|
//`include "arg_defs.vh"
|
|
|
|
module sdram_ctrl /* verilator tracing_off */
|
|
(
|
|
//--------------------
|
|
// Clocks and reset --
|
|
//--------------------
|
|
// Global reset
|
|
input rst,
|
|
// Controller clock
|
|
input clk,
|
|
// Sequencer cycles
|
|
input [11:0] seq_cyc,
|
|
// Sequencer phase
|
|
input seq_ph,
|
|
// Refresh cycle
|
|
input refr_cyc,
|
|
//------------------------
|
|
// Access port #1 (CPU) --
|
|
//------------------------
|
|
// RAM select
|
|
input ap1_ram_sel,
|
|
// Address bus
|
|
input [23:1] ap1_address,
|
|
// Read enable
|
|
input ap1_rden,
|
|
// Write enable
|
|
input ap1_wren,
|
|
// Byte enable
|
|
input [1:0] ap1_bena,
|
|
// Data bus (read)
|
|
output [15:0] ap1_rddata,
|
|
// Data bus (write)
|
|
input [15:0] ap1_wrdata,
|
|
// Burst size
|
|
input [2:0] ap1_bst_siz,
|
|
// Read burst active
|
|
output reg ap1_rd_bst_act,
|
|
// Write burst active
|
|
output ap1_wr_bst_act,
|
|
//------------------------
|
|
// Access port #2 (GPU) --
|
|
//------------------------
|
|
// RAM select
|
|
input ap2_ram_sel,
|
|
// Address bus
|
|
input [23:1] ap2_address,
|
|
// Read enable
|
|
input ap2_rden,
|
|
// Write enable
|
|
input ap2_wren,
|
|
// Byte enable
|
|
input [1:0] ap2_bena,
|
|
// Data bus (read)
|
|
output [15:0] ap2_rddata,
|
|
// Data bus (write)
|
|
input [15:0] ap2_wrdata,
|
|
// Burst size
|
|
input [2:0] ap2_bst_siz,
|
|
// Read burst active
|
|
output reg ap2_rd_bst_act,
|
|
// Write burst active
|
|
output ap2_wr_bst_act,
|
|
//------------------------
|
|
// Access port #3 (CTL) --
|
|
//------------------------
|
|
// RAM select
|
|
input ap3_ram_sel,
|
|
// Address bus
|
|
input [23:1] ap3_address,
|
|
// Read enable
|
|
input ap3_rden,
|
|
// Write enable
|
|
input ap3_wren,
|
|
// Byte enable
|
|
input [1:0] ap3_bena,
|
|
// Data bus (read)
|
|
output [15:0] ap3_rddata,
|
|
// Data bus (write)
|
|
input [15:0] ap3_wrdata,
|
|
// Burst size
|
|
input [2:0] ap3_bst_siz,
|
|
// Read burst active
|
|
output reg ap3_rd_bst_act,
|
|
// Write burst active
|
|
output ap3_wr_bst_act,
|
|
//------------------------
|
|
// SDRAM memory signals --
|
|
//------------------------
|
|
// SDRAM controller ready
|
|
output reg sdram_rdy,
|
|
// SDRAM chip select
|
|
output reg sdram_cs_n,
|
|
// SDRAM row address strobe
|
|
output reg sdram_ras_n,
|
|
// SDRAM column address strobe
|
|
output reg sdram_cas_n,
|
|
// SDRAM write enable
|
|
output reg sdram_we_n,
|
|
// SDRAM DQ masks
|
|
output reg [1:0] sdram_dqm_n,
|
|
// SDRAM bank address
|
|
output reg [1:0] sdram_ba,
|
|
// SDRAM address
|
|
output reg [11:0] sdram_addr,
|
|
// SDRAM data
|
|
output reg sdram_dq_oe,
|
|
output reg [15:0] sdram_dq_o,
|
|
input [15:0] sdram_dq_i
|
|
);
|
|
|
|
// SDRAM memory size
|
|
parameter SDRAM_SIZE = 8;
|
|
// SDRAM operational frequency
|
|
parameter SDRAM_FREQ = 85909090;
|
|
// Hidden refresh mode
|
|
parameter HIDDEN_REFRESH = 0;
|
|
// MODE REGISTER SET value (RS = 00, WB = 0, OP = 00, CL = 010, BT = 0, BL = 011)
|
|
parameter MRS_VALUE = 12'b000000100011;
|
|
// Refresh period
|
|
parameter REF_COUNT = ((SDRAM_FREQ / ((12 * 64000)))) - 1;
|
|
// Clock-to-output delay
|
|
parameter Tco_dly = 4.5;
|
|
|
|
// Port select signals
|
|
reg [2:0] r_psel; // Port select (one hot)
|
|
reg [2:0] r_psel_dly; // Port select delayed
|
|
|
|
// Refresh signals
|
|
reg r_refr_req; // Refresh requested
|
|
reg r_refr_act; // Refresh active
|
|
reg r_refr_ack; // Refresh acknowledged
|
|
reg [31:0] r_refr_ctr; // Refresh counter
|
|
|
|
// Port multiplexer signals
|
|
wire w_rden; // Read enable
|
|
reg r_rd_reg; // Registered read enable
|
|
reg r_rd_act; // Read active
|
|
wire w_wren; // Write enable
|
|
reg r_wr_reg; // Registered write enable
|
|
reg r_wr_act; // Write active
|
|
wire w_ram_sel; // RAM select
|
|
reg [2:0] r_rd_bctr; // Read burst counter
|
|
reg [2:0] r_wr_bctr; // Write burst counter
|
|
wire [2:0] w_bst_siz; // Burst size (load value of burst counters)
|
|
reg [2:0] r_bst_stp; // Burst stop
|
|
wire [1:0] w_dqm; // Bytes masks
|
|
wire [23:1] w_addr; // Address
|
|
reg [15:0] r_rddata; // Data read
|
|
wire [15:0] w_wrdata; // Data written
|
|
|
|
// SDRAM speed adjustment
|
|
wire w_rd_start; // Read start condition
|
|
wire w_wr_start; // Write start condition
|
|
wire [3:0] w_rd_cycle; // First read cycle number
|
|
|
|
// Initialization signals
|
|
reg [2:0] r_init_fsm; // SDRAM initialization state machine
|
|
reg [10:0] r_init_tmr; // SDRAM initialization timer
|
|
|
|
// Output registers
|
|
reg r_sdram_cs_n; // SDRAM chip select
|
|
reg r_sdram_ras_n; // SDRAM row address strobe
|
|
reg r_sdram_cas_n; // SDRAM column address strobe
|
|
reg r_sdram_we_n; // SDRAM write enable
|
|
reg [1:0] r_sdram_dqm_n; // SDRAM DQ masks
|
|
reg [1:0] r_sdram_ba; // SDRAM bank address
|
|
reg [11:0] r_sdram_addr; // SDRAM address
|
|
reg [15:0] r_sdram_dq_o; // SDRAM DQ output
|
|
reg r_sdram_dq_oe; // SDRAM DQ output enable
|
|
|
|
// Signal multiplexing based on the port select
|
|
assign w_wren = (ap1_wren & r_psel[0])
|
|
| (ap2_wren & r_psel[1])
|
|
| (ap3_wren & r_psel[2]);
|
|
assign w_rden = (ap1_rden & r_psel[0])
|
|
| (ap2_rden & r_psel[1])
|
|
| (ap3_rden & r_psel[2]);
|
|
assign w_ram_sel = (HIDDEN_REFRESH == 1)
|
|
? (r_psel[0] | r_psel[1] | r_psel[2])
|
|
: (r_psel[0] | r_psel[1] | r_psel[2]) & ~r_refr_req;
|
|
assign w_dqm[0] = (ap1_bena[0] & r_psel[0])
|
|
| (ap2_bena[0] & r_psel[1])
|
|
| (ap3_bena[0] & r_psel[2]);
|
|
assign w_dqm[1] = (ap1_bena[1] & r_psel[0])
|
|
| (ap2_bena[1] & r_psel[1])
|
|
| (ap3_bena[1] & r_psel[2]);
|
|
assign w_bst_siz[2] = (ap1_bst_siz[2] & r_psel[0])
|
|
| (ap2_bst_siz[2] & r_psel[1])
|
|
| (ap3_bst_siz[2] & r_psel[2]);
|
|
assign w_bst_siz[1] = (ap1_bst_siz[1] & r_psel[0])
|
|
| (ap2_bst_siz[1] & r_psel[1])
|
|
| (ap3_bst_siz[1] & r_psel[2]);
|
|
assign w_bst_siz[0] = (ap1_bst_siz[0] & r_psel[0])
|
|
| (ap2_bst_siz[0] & r_psel[1])
|
|
| (ap3_bst_siz[0] & r_psel[2]);
|
|
assign w_addr[23:1] = (ap1_address[23:1] & {23{r_psel[0]}})
|
|
| (ap2_address[23:1] & {23{r_psel[1]}})
|
|
| (ap3_address[23:1] & {23{r_psel[2]}});
|
|
assign w_wrdata[15:0] = (ap1_wrdata[15:0] & {16{r_psel[0]}})
|
|
| (ap2_wrdata[15:0] & {16{r_psel[1]}})
|
|
| (ap3_wrdata[15:0] & {16{r_psel[2]}});
|
|
|
|
// SDRAM speed adjustment
|
|
assign w_rd_cycle = (SDRAM_FREQ < 50000000) ? 4'd2 : 4'd3;
|
|
assign w_rd_start = (SDRAM_FREQ < 50000000) ? (seq_cyc[2] & r_rd_reg) : (seq_cyc[4] & r_rd_reg);
|
|
assign w_wr_start = (SDRAM_FREQ < 50000000) ? (seq_cyc[0] & w_wren & w_ram_sel) : (seq_cyc[1] & r_wr_reg);
|
|
|
|
// Write burst active flags, one cycle before "r_wr_act"
|
|
assign ap1_wr_bst_act = (r_wr_bctr[0] | r_wr_bctr[1] | r_wr_bctr[2] | w_wr_start) & r_psel[0];
|
|
assign ap2_wr_bst_act = (r_wr_bctr[0] | r_wr_bctr[1] | r_wr_bctr[2] | w_wr_start) & r_psel[1];
|
|
assign ap3_wr_bst_act = (r_wr_bctr[0] | r_wr_bctr[1] | r_wr_bctr[2] | w_wr_start) & r_psel[2];
|
|
|
|
// SDRAM data read
|
|
assign ap1_rddata = r_rddata;
|
|
assign ap2_rddata = r_rddata;
|
|
assign ap3_rddata = r_rddata;
|
|
|
|
// Hidden refresh / port select :
|
|
//-------------------------------
|
|
// rst : Global reset
|
|
// clk : SDRAM controller clock
|
|
// seq_cyc : Sequencer cycle (0 to 11)
|
|
// seq_ph : Sequencer phase (0 or 1)
|
|
// r_refr_req : Internal refresh cycle request
|
|
// r_refr_ack : Internal refresh cycle acknowledge
|
|
// r_refr_ctr : Internal refresh counter
|
|
// r_psel : Port select (one hot)
|
|
// r_psel_dly : Delayed port select
|
|
// ap1_ram_sel : Port #1 access
|
|
// ap2_ram_sel : Port #2 access
|
|
// ap3_ram_sel : Port #3 access
|
|
always @(posedge rst or posedge clk) begin
|
|
if (rst) begin
|
|
// Refresh counter
|
|
r_refr_ctr <= REF_COUNT;
|
|
// Refresh cycle request
|
|
r_refr_req <= 1'b0;
|
|
end else begin
|
|
// Hidden refresh case
|
|
if (HIDDEN_REFRESH == 1) begin
|
|
// Sequencer cycle #11
|
|
if (seq_cyc[11]) begin
|
|
// Internal refresh counter
|
|
if (r_refr_ctr == 0) begin
|
|
r_refr_req <= 1'b1;
|
|
r_refr_ctr <= REF_COUNT;
|
|
end
|
|
else begin
|
|
r_refr_ctr <= r_refr_ctr - 1;
|
|
end
|
|
end
|
|
// When refresh cycle is acknowledged
|
|
if (r_refr_ack == 1'b1) begin
|
|
// Clear the refresh cycle request
|
|
r_refr_req <= 1'b0;
|
|
end
|
|
end else begin
|
|
// External refresh
|
|
r_refr_req <= refr_cyc;
|
|
end
|
|
end
|
|
|
|
if (rst) begin
|
|
// Port select
|
|
r_psel <= 3'b000;
|
|
r_psel_dly <= 3'b000;
|
|
end else begin
|
|
// Access port select
|
|
if (seq_cyc[11]) begin
|
|
if (!seq_ph) begin
|
|
// Phase #0 : select port #1 (CPU) -> #3 (CTL) -> none
|
|
r_psel[0] <= ap1_ram_sel;
|
|
r_psel[1] <= 1'b0;
|
|
r_psel[2] <= ap3_ram_sel & ~ap1_ram_sel;
|
|
end
|
|
else begin
|
|
// Phase #1 : select port #2 (GPU) -> #1 (CPU) -> #3 (CTL) -> none
|
|
r_psel[0] <= ap1_ram_sel & ~ap2_ram_sel;
|
|
r_psel[1] <= ap2_ram_sel;
|
|
r_psel[2] <= ap3_ram_sel & ~(ap1_ram_sel | ap2_ram_sel);
|
|
end
|
|
end
|
|
// Delayed port select for data read multiplexer
|
|
if (seq_cyc[1]) begin
|
|
r_psel_dly <= r_psel;
|
|
end
|
|
end
|
|
end
|
|
|
|
// Burst activities :
|
|
//-------------------
|
|
// rst : Global reset
|
|
// clk : SDRAM controller clock
|
|
// w_rd_start : Read start conditions
|
|
// w_wr_start : Write start conditions
|
|
// r_rd_reg : Read mode (registered)
|
|
// r_rd_act : Read active
|
|
// r_wr_act : Write active
|
|
// r_rd_bctr : Burst read counter
|
|
// r_wr_bctr : Burst write counter
|
|
// r_psel_dly : Port select delayed
|
|
always @(posedge rst or posedge clk) begin
|
|
if (rst) begin
|
|
// Burst signals
|
|
r_rd_act <= 1'b0;
|
|
r_wr_act <= 1'b0;
|
|
r_rd_bctr <= 3'b000;
|
|
r_wr_bctr <= 3'b000;
|
|
ap1_rd_bst_act <= 1'b0;
|
|
ap2_rd_bst_act <= 1'b0;
|
|
ap3_rd_bst_act <= 1'b0;
|
|
// Data bus
|
|
r_rddata <= 16'h0000;
|
|
r_sdram_dqm_n <= 2'b11;
|
|
r_sdram_dq_oe <= 1'b0;
|
|
r_sdram_dq_o <= 16'h0000;
|
|
end else begin
|
|
// Prepare write burst cycles
|
|
if (w_wr_start) begin
|
|
// Set the active bits
|
|
r_wr_act <= 1'b1;
|
|
// Start the burst counter
|
|
r_wr_bctr <= w_bst_siz;
|
|
end
|
|
// Prepare read burst cycles
|
|
if (w_rd_start) begin
|
|
// Set the active bits
|
|
r_rd_act <= 1'b1;
|
|
// Start the burst counter
|
|
r_rd_bctr <= r_bst_stp;
|
|
end
|
|
// Read burst counter management
|
|
if (r_rd_act) begin
|
|
if (r_rd_bctr == 0) begin
|
|
// Burst finished : clear the active bit
|
|
r_rd_act <= 1'b0;
|
|
end
|
|
else begin
|
|
r_rd_bctr <= r_rd_bctr - 3'b1;
|
|
end
|
|
end
|
|
// Write burst counter management
|
|
if (r_wr_act) begin
|
|
if (r_wr_bctr == 0) begin
|
|
// Burst finished : clear the active bit
|
|
r_wr_act <= 1'b0;
|
|
end
|
|
else begin
|
|
r_wr_bctr <= r_wr_bctr - 3'b1;
|
|
end
|
|
end
|
|
// Read burst active flags, one cycle after "r_rd_act"
|
|
ap1_rd_bst_act <= r_rd_act & r_psel_dly[0];
|
|
ap2_rd_bst_act <= r_rd_act & r_psel_dly[1];
|
|
ap3_rd_bst_act <= r_rd_act & r_psel_dly[2];
|
|
// Read SDRAM data
|
|
r_rddata <= sdram_dq_i;
|
|
// Write SDRAM data / DQM management
|
|
if (r_wr_act) begin
|
|
r_sdram_dqm_n[0] <= ~w_dqm[0];
|
|
r_sdram_dqm_n[1] <= ~w_dqm[1];
|
|
r_sdram_dq_oe <= 1'b1;
|
|
r_sdram_dq_o <= w_wrdata;
|
|
end
|
|
else begin
|
|
r_sdram_dqm_n[0] <= ~r_rd_reg;
|
|
r_sdram_dqm_n[1] <= ~r_rd_reg;
|
|
r_sdram_dq_oe <= 1'b0;
|
|
r_sdram_dq_o <= 16'h0000;
|
|
end
|
|
end
|
|
end
|
|
|
|
// SDRAM controller state machine :
|
|
//---------------------------------
|
|
// rst : Global reset
|
|
// clk : SDRAM controller clock
|
|
// seq_cyc : Sequencer cycle
|
|
// r_refr_req : Refresh cycle requested
|
|
// r_refr_act : Refresh cycle active
|
|
// r_refr_ack : Refresh cycle acknowledge
|
|
// w_ram_sel : SDRAM selected
|
|
// w_rden : Read enable flag
|
|
// w_wren : Write enable flag
|
|
// r_rd_reg : Read mode (registered)
|
|
// r_wr_reg : Write mode (registered)
|
|
// w_bst_siz : Burst size (1 to 8 words)
|
|
// r_bst_stp : Burst stop cycle
|
|
// r_init_fsm : SDRAM initialization state
|
|
// r_init_tmr : SDRAM initialization timer (>100 us)
|
|
always @(posedge rst or posedge clk) begin
|
|
if (rst) begin
|
|
// SDRAM outputs
|
|
r_sdram_cs_n <= 1'b1;
|
|
r_sdram_ras_n <= 1'b1;
|
|
r_sdram_cas_n <= 1'b1;
|
|
r_sdram_we_n <= 1'b1;
|
|
r_sdram_ba <= 2'b00;
|
|
r_sdram_addr <= 12'b000000000000;
|
|
// Controller state
|
|
r_rd_reg <= 1'b0;
|
|
r_wr_reg <= 1'b0;
|
|
r_bst_stp <= 3'b000;
|
|
sdram_rdy <= 1'b0;
|
|
r_refr_ack <= 1'b0;
|
|
r_refr_act <= 1'b0;
|
|
// 1024 * 12 cycles > 100 us
|
|
r_init_tmr <= 11'd0; // 143 us
|
|
r_init_fsm <= 3'b000;
|
|
end else begin
|
|
// Default : NOPs
|
|
r_sdram_ras_n <= 1'b1;
|
|
r_sdram_cas_n <= 1'b1;
|
|
r_sdram_we_n <= 1'b1;
|
|
if (r_init_fsm[2]) begin
|
|
// Chip select management
|
|
if (seq_cyc[0]) begin
|
|
// RAM selected or refresh request
|
|
r_sdram_cs_n <= ~(w_ram_sel | r_refr_req);
|
|
end
|
|
// If there is an active refresh
|
|
if (r_refr_act) begin
|
|
//------------------
|
|
// Refresh cycles --
|
|
//------------------
|
|
// Cycle #0 : clear read/write enable signals
|
|
r_rd_reg <= 1'b0;
|
|
r_wr_reg <= 1'b0;
|
|
// Cycle #2 : prepare AUTO REFRESH cmd for cycle #3
|
|
if (seq_cyc[2]) begin
|
|
r_sdram_ras_n <= 1'b0;
|
|
r_sdram_cas_n <= 1'b0;
|
|
end
|
|
// Cycle #9 : acknowledge the refresh request
|
|
if (seq_cyc[9]) begin
|
|
// Hidden refresh case
|
|
if (HIDDEN_REFRESH == 1) begin
|
|
r_refr_ack <= 1'b1;
|
|
end
|
|
r_refr_act <= 1'b0;
|
|
end
|
|
end
|
|
else begin
|
|
//-----------------
|
|
// Normal cycles --
|
|
//-----------------
|
|
// Hidden refresh case
|
|
if (HIDDEN_REFRESH == 1) begin
|
|
// Clear any refresh acknowledge
|
|
r_refr_ack <= 1'b0;
|
|
end
|
|
if (seq_cyc[0]) begin
|
|
// If no access, activate refresh
|
|
r_refr_act <= ~((w_rden | w_wren) & w_ram_sel) & r_refr_req;
|
|
// Register read/write enable signals
|
|
r_rd_reg <= w_rden & w_ram_sel;
|
|
r_wr_reg <= w_wren & w_ram_sel;
|
|
// Register the burst stop
|
|
r_bst_stp <= w_bst_siz;
|
|
end
|
|
// Cycle #0 : prepare ACTIVATE cmd for cycle #1
|
|
// set the row address and the bank number
|
|
if ((seq_cyc[0]) && (w_ram_sel) && ((w_rden) || (w_wren))) begin
|
|
r_sdram_ras_n <= 1'b0;
|
|
if (SDRAM_SIZE == 16) begin
|
|
// 4096 rows : 12 address lines
|
|
r_sdram_addr <= w_addr[23:12];
|
|
// 4 banks : 2 address lines
|
|
r_sdram_ba <= w_addr[11:10];
|
|
end else begin
|
|
// 4096 rows : 12 address lines
|
|
r_sdram_addr <= w_addr[22:11];
|
|
// 4 banks : 2 address lines
|
|
r_sdram_ba <= w_addr[10:9];
|
|
end
|
|
end
|
|
// Cycle #1/2 : prepare READ/WRITE cmd for next cycle
|
|
// set the column address and the bank number
|
|
if ((seq_cyc[w_rd_cycle - 1]) && ((r_rd_reg) || (r_wr_reg))) begin
|
|
r_sdram_cas_n <= 1'b0;
|
|
r_sdram_we_n <= ~r_wr_reg;
|
|
if (SDRAM_SIZE == 16)
|
|
// 512 columns : 9 address lines
|
|
r_sdram_addr <= {3'b010, w_addr[9:1]};
|
|
else
|
|
// 256 columns : 8 address lines
|
|
r_sdram_addr <= {4'b0100, w_addr[8:1]};
|
|
end
|
|
// Cycles #2/3+ : prepare the PRECHARGE cmd (burst stop)
|
|
//if ((seq_cyc[w_rd_cycle + r_bst_stp]) && ((r_rd_reg) || (r_wr_reg))) begin
|
|
// r_sdram_ras_n <= 1'b0;
|
|
// r_sdram_we_n <= 1'b0;
|
|
//end
|
|
end
|
|
end
|
|
else begin
|
|
//---------------
|
|
// Init cycles --
|
|
//---------------
|
|
if (r_init_tmr[10]) begin
|
|
// Select SDRAM
|
|
r_sdram_cs_n <= 1'b0;
|
|
case (r_init_fsm[1:0])
|
|
2'd0 : begin
|
|
// Prepare PRECHARGE ALL cmd
|
|
if (seq_cyc[3]) begin
|
|
r_sdram_ras_n <= 1'b0;
|
|
r_sdram_we_n <= 1'b0;
|
|
r_sdram_addr[10] <= 1'b1;
|
|
end
|
|
end
|
|
2'd1 : begin
|
|
// Prepare AUTO REFRESH cmd
|
|
if (seq_cyc[3]) begin
|
|
r_sdram_ras_n <= 1'b0;
|
|
r_sdram_cas_n <= 1'b0;
|
|
end
|
|
end
|
|
2'd2 : begin
|
|
// Prepare AUTO REFRESH cmd
|
|
if (seq_cyc[3]) begin
|
|
r_sdram_ras_n <= 1'b0;
|
|
r_sdram_cas_n <= 1'b0;
|
|
end
|
|
end
|
|
2'd3 : begin
|
|
// Prepare MODE REGISTER SET value
|
|
if (seq_cyc[1]) begin
|
|
r_sdram_addr <= MRS_VALUE;
|
|
end
|
|
// Prepare MODE REGISTER SET cmd
|
|
if (seq_cyc[3]) begin
|
|
r_sdram_ras_n <= 1'b0;
|
|
r_sdram_cas_n <= 1'b0;
|
|
r_sdram_we_n <= 1'b0;
|
|
end
|
|
// SDRAM is initialized
|
|
if (seq_cyc[10]) begin
|
|
sdram_rdy <= 1'b1;
|
|
end
|
|
end
|
|
default : begin
|
|
end
|
|
endcase
|
|
// Cycle #11 : next state
|
|
if (seq_cyc[11]) begin
|
|
r_init_fsm <= r_init_fsm + 3'd1;
|
|
end
|
|
end
|
|
else begin
|
|
// Deselect SDRAM
|
|
r_sdram_cs_n <= 1'b1;
|
|
// Cycle #11 : timer management
|
|
if (seq_cyc[11]) begin
|
|
r_init_tmr <= r_init_tmr + 11'd1;
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
// TCO delay on all outputs
|
|
always@(r_sdram_cs_n or r_sdram_ras_n or r_sdram_cas_n or r_sdram_we_n or
|
|
r_sdram_dqm_n or r_sdram_ba or r_sdram_addr or r_sdram_dq_oe or r_sdram_dq_o) begin
|
|
`ifdef SIMULATION
|
|
|
|
`ifdef verilator3
|
|
// Cycle based simulation
|
|
sdram_cs_n = r_sdram_cs_n;
|
|
sdram_ras_n = r_sdram_ras_n;
|
|
sdram_cas_n = r_sdram_cas_n;
|
|
sdram_we_n = r_sdram_we_n;
|
|
sdram_dqm_n = r_sdram_dqm_n;
|
|
sdram_ba = r_sdram_ba;
|
|
sdram_addr = r_sdram_addr;
|
|
sdram_dq_oe = r_sdram_dq_oe;
|
|
sdram_dq_o = r_sdram_dq_o;
|
|
`else
|
|
// Timing based simulation
|
|
sdram_cs_n = #Tco_dly r_sdram_cs_n;
|
|
sdram_ras_n = #Tco_dly r_sdram_ras_n;
|
|
sdram_cas_n = #Tco_dly r_sdram_cas_n;
|
|
sdram_we_n = #Tco_dly r_sdram_we_n;
|
|
sdram_dqm_n = #Tco_dly r_sdram_dqm_n;
|
|
sdram_ba = #Tco_dly r_sdram_ba;
|
|
sdram_addr = #Tco_dly r_sdram_addr;
|
|
sdram_dq_oe = #Tco_dly r_sdram_dq_oe;
|
|
sdram_dq_o = #Tco_dly r_sdram_dq_o;
|
|
`endif
|
|
|
|
`else
|
|
// Synthesis
|
|
sdram_cs_n = r_sdram_cs_n;
|
|
sdram_ras_n = r_sdram_ras_n;
|
|
sdram_cas_n = r_sdram_cas_n;
|
|
sdram_we_n = r_sdram_we_n;
|
|
sdram_dqm_n = r_sdram_dqm_n;
|
|
sdram_ba = r_sdram_ba;
|
|
sdram_addr = r_sdram_addr;
|
|
sdram_dq_oe = r_sdram_dq_oe;
|
|
sdram_dq_o = r_sdram_dq_o;
|
|
`endif
|
|
end
|
|
|
|
`ifdef SIMULATION
|
|
|
|
`ifndef verilator3
|
|
// Setup and hold times check for DQ
|
|
reg r_dq_noti;
|
|
|
|
specify
|
|
specparam
|
|
Tsu_dly = 0.7, // Input setup time
|
|
Th_dly = -0.5; // Input hold time
|
|
$setuphold(posedge clk, sdram_dq_i, Tsu_dly, Th_dly, r_dq_noti);
|
|
endspecify
|
|
|
|
always @(r_dq_noti)
|
|
begin
|
|
$display($realtime, " ns : Setup/Hold time violation on DQ inputs");
|
|
end
|
|
`endif
|
|
|
|
`endif
|
|
|
|
endmodule
|
|
|
|
/* verilator tracing_off */
|