📄 sdrcnt.v
字号:
sd_wr_l <= `HI;
sd_cs_l <= `HI;
sd_ras_l <= `HI;
sd_cas_l <= `HI;
sd_dqm <= `HI;
burst_cntr_ena <= `LO;
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;
next_state <= `state_idle;
end
`state_delay_Tras2: begin
next_state <= `state_precharge;
end
// SET CAS state
`state_set_cas: begin
sd_ras_l <= `HI; // disble the RAS
sd_addx_mux <= 2'b11; // select COLUMN
sd_cs_l <= `LO;
sd_cas_l <= `LO;
sd_dqm <= `LO;
next_state <= `state_cas_latency1;
end
`state_cas_latency1: begin
sd_cs_l <= `HI; // disable CS
sd_cas_l <= `HI; // disable CAS
//mp_data_mux <= `HI; // drive the SD data bus with all zeros
if (modereg_cas_latency==3'b010) begin
next_state <= `state_read; // 2 cycles of lantency done.
// sd_dqm <= `HI; // disable DQM now only if CAS LAT=2
burst_cntr_ena <= `HI; // enable the burst lenght counter
sd_rd_ena <= `HI; // enable the read latch on the next state
end else begin
next_state <= `state_cas_latency2; // 3 cycles of latency
end
end
`state_cas_latency2: begin
next_state <= `state_read;
burst_cntr_ena <= `HI; // enable the burst lenght counter
// sd_dqm <= `HI; // done reading .. with CAS LAT = 3
sd_rd_ena <= `HI; // enable the read latch on the next state
end
`state_read: begin
//sd_rd_ena <= `HI; // enable the read latch on the next state
do_read_ack <= `HI; // acknowledge the read request (do it here due to the latency)
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;
next_state <= `state_idle;
sd_rd_ena <= `LO; // enable the read latch on the next state
sd_dqm <= `HI; // disable DQM now only if CAS LAT=2
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
//
// Enter 1 less than the actual burst count
//
always @(modereg_burst_length)
case (modereg_burst_length)
3'b000: modereg_burst_count <= 4'h0;
3'b001: modereg_burst_count <= 4'h1;
3'b010: modereg_burst_count <= 4'h3;
default modereg_burst_count <= 4'h7;
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 <= {`BW{1'b0}};
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
if (refresh_l) begin
//refresh_timer <= refresh_timer + 1;
refresh_state <= `state_count;
end else begin
refresh_state <= `state_halt;
//refresh_timer <= {`BW{1'b0}};
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 (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 <= {`BW{1'b0}};
end
endcase
endmodule
/*****************************************************************************/
/*****************************************************************************/
`include "inc.h"
module hostcont (
// system connections
sys_rst_l,
sys_clk,
// microprocessor side connections
mp_addx,
mp_data_in1,
mp_data_out1,
mp_data_in2,
mp_data_out2,
mp_rd_l,
mp_wr_l,
// SDRAM side connections
sd_addx,
sd_data_out1,
sd_data_in1,
sd_data_out2,
sd_data_in2,
sd_data_out3,
sd_data_in3,
sd_data_out4,
sd_data_in4,
sd_ba,
// SDRAMCNT side
sdram_dqm,
sd_addx_mux,
sd_rd_ena,
do_read,
do_write,
modereg_cas_latency,
modereg_burst_length,
mp_data_mux,
pwrup,
// debug
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 [23:0] mp_addx; // ABW bits for the addx
input [7:0] mp_data_in1; // DBW bits of data bus input (see INC.H)
output [7:0] mp_data_out1; // DBW bits of data bus output (see INC.H)
input [7:0] mp_data_in2; // DBW bits of data bus input (see INC.H)
output [7:0] mp_data_out2; // 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
// SDRAM side connections
output [11:0] sd_addx; // 11 bits of muxed SDRAM addx
input [7:0] sd_data_in1;
output [7:0] sd_data_out1;
input [7:0] sd_data_in2;
output [7:0] sd_data_out2;
input [7:0] sd_data_in3;
output [7:0] sd_data_out3;
input [7:0] sd_data_in4;
output [7:0] sd_data_out4;
output [1:0] sd_ba; // bank select output to the SDRAM
input pwrup;
// SDRAMCNT side
input [3:0] sdram_dqm;
input [1:0] sd_addx_mux;
input sd_rd_ena;
output do_write;
output do_read;
output [2:0] modereg_cas_latency;
output [2:0] modereg_burst_length;
input mp_data_mux;
//output decoded_dqm; // this is the decoded DQM according to the size. Used during writes
output [13:0] reg_modeset;
// ****************************************
//
// Memory Elements
//
// ****************************************
//
reg [13:0] reg_modeset;
reg [11:0] sd_addx;
reg [1:0] sd_ba;
wire do_read;
wire do_write;
assign do_write = ~mp_wr_l;
assign do_read = ~mp_rd_l;
assign sd_data_out1 = mp_data_in1;
assign sd_data_out2 = mp_data_in2;
assign sd_data_out3 = mp_data_in1;
assign sd_data_out4 = mp_data_in2;
assign mp_data_out1 = (!sdram_dqm[3] || !sdram_dqm[1]) ? sd_data_in3 : sd_data_in1;
assign mp_data_out2 = (!sdram_dqm[3] || !sdram_dqm[1]) ? sd_data_in4 : sd_data_in2;
assign modereg_cas_latency = reg_modeset[6:4];
assign modereg_burst_length = reg_modeset[2:0];
//
// MODE REG REG
//
`define default_mode_reg {4'b0000,`default_mode_reg_WRITE_MODE,2'b00,`default_mode_reg_CAS_LATENCY,`default_mode_reg_ADDR_MODE,`default_mode_reg_BURST_LENGHT}
always @(posedge sys_clk or negedge sys_rst_l)
if (~sys_rst_l)
reg_modeset <= 13'h0000;
else
if (pwrup)
reg_modeset <= `default_mode_reg;
// 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) begin
mp_data_out1 <= {8{1'b0}};
mp_data_out2 <= {8{1'b0}};
end
else if (sd_rd_ena) begin
mp_data_out1 <= sd_data_in1;
mp_data_out2 <= sd_data_in2;
end
*/
//ADDR
always @(sd_addx_mux or reg_modeset or mp_addx)
case (sd_addx_mux)
2'b00: sd_addx[11:0] <= mp_addx[21:10]; // ROW
2'b01: sd_addx[11:0] <= {2'b00, mp_addx[9:0]}; // COLUMN
2'b10: sd_addx[11:0] <= reg_modeset[11:0];
2'b11: sd_addx[11:0] <= {2'b01, mp_addx[9:0]}; // A10 = 1'b1
default: sd_addx[11:0] <= {12{1'b0}};
endcase
// SD_BA
always @(sd_addx_mux or mp_addx)
case (sd_addx_mux)
2'b00: sd_ba[1:0] <= mp_addx[23:22];
2'b01: sd_ba[1:0] <= mp_addx[23:22];
2'b11: sd_ba[1:0] <= mp_addx[23:22];
default: sd_ba[1:0] <= 2'b00;
endcase
endmodule
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -