Programmable Devices
CPLDs, FPGAs, SoC FPGAs, Configuration, and Transceivers
21335 Discussions

SRAM Read Question

Altera_Forum
Honored Contributor II
945 Views

Am using TerASIC DE2-115. SRAM is asynchornous 10ns ISSI. Have Nios CPU and custom interface (TDR) multiplexed to SRAM. CPU interface works perfectly. However, when I try to read SRAM from TDR interface, the readdata component always reports the previous address's data, not the current. Clock is 100Mhz and I currently have 3 wait states set between activating the read and reading the data. Have also tried setting WS to 10. Results are different, but still incorrect. It seems that once the control and address lines are set, and after 10ns, the readdata should become, and remain, valid until I dectivate the control lines.  

 

Below is SRAM interface and the TDR interface controlling it. I've excluded some of the control logi (cpu_tdr_sel, etc.) Would appreciate any thoughts on my mistake. It seems that since I am at 100Mhz 3 WS would be more than sufficient. Also, from the ISSI datasheet, it appears that I should be able to set all control (WE,OE,CS,UBE,LBE) and address lines at the same time. 

 

Apologies for lengh post... 

 

RT 

 

/********* SRAM Interface *************/ 

 

reg [15:0] s_writedata_reg;  

reg [15:0] tdr_writedata_reg;  

 

assign SRAM_DQ = ((cpu_tdr_select == cpu_sel) ? (~SRAM_WE_n ? s_writedata_reg : 16'hzzzz) : (~SRAM_WE_n ? tdr_writedata_reg : 16'hzzzz));  

 

always @(posedge clk)  

begin  

if (reset_n == 0)  

begin  

s_readdata = 16'h0000;  

s_writedata_reg = 16'h0000;  

 

SRAM_ADDR = 20'h00000;  

SRAM_LB_n = 1'b1;  

SRAM_UB_n = 1'b1;  

SRAM_CE_n = 1'b1;  

SRAM_OE_n = 1'b1;  

SRAM_WE_n = 1'b1;  

end  

else  

begin  

if (cpu_tdr_select == cpu_sel) // CPU 

begin 

s_readdata = SRAM_DQ;  

s_writedata_reg = s_writedata;  

 

SRAM_ADDR = s_address;  

SRAM_LB_n = s_byteenable_n[0] | s_chipselect_n;  

SRAM_UB_n = s_byteenable_n[1] | s_chipselect_n;  

SRAM_CE_n = s_chipselect_n;  

SRAM_OE_n = s_read_n | s_chipselect_n;  

SRAM_WE_n = s_write_n | s_chipselect_n;  

end 

else // TDR 

begin 

tdr_readdata = SRAM_DQ;  

tdr_writedata_reg = tdr_writedata;  

 

SRAM_ADDR = tdr_address;  

SRAM_LB_n = tdr_byteenable_n[0] | tdr_chipselect_n;  

SRAM_UB_n = tdr_byteenable_n[1] | tdr_chipselect_n;  

SRAM_CE_n = tdr_chipselect_n;  

SRAM_OE_n = tdr_read_n | tdr_chipselect_n;  

SRAM_WE_n = tdr_write_n | tdr_chipselect_n;  

end 

end  

 

/********** TDR Host *************/ 

 

reg perform_sram_test; 

reg [3:0] sram_test_state; 

localparam waiting_to_start_sram_test = 0; 

localparam start_sram_test = 1; 

localparam sram_wait = 2; 

localparam sram_end_read = 3; 

reg [7:0] sram_wait_state_counter; 

reg [31:0] sram_checksum; 

reg [19:0]local_sram_address; 

 

task enable_sram_read; 

input [31:0] sram_index; 

begin 

sram_chipselect_n = 0; 

sram_write_n = 1; 

sram_address = sram_index; 

sram_read_n = 0; 

sram_byteenable_n[0] = 0; 

sram_byteenable_n[1] = 0; 

end 

endtask 

task disable_sram_read; 

begin 

sram_chipselect_n = 1; 

sram_write_n = 1; 

sram_address = 20'hzzzzz; 

sram_read_n = 1; 

sram_byteenable_n[0] = 1; 

sram_byteenable_n[1] = 1; 

end 

endtask 

// Manage SRAM verification 

always @(posedge clk or negedge reset_n) 

begin 

if (reset_n == 0) 

begin 

perform_sram_test <= 1; 

sram_test_state <= waiting_to_start_sram_test; 

sram_wait_states <= 3; 

end 

else if (clk_en) 

begin 

if (chipselect && ~write_n && (address == 6)) 

begin 

perform_sram_test <= 0; 

end 

if (chipselect && ~write_n && (address == 8)) 

begin 

sram_wait_states <= readdata; 

end 

 

case (sram_test_state) 

waiting_to_start_sram_test: 

begin 

if (perform_sram_test == 0) 

begin 

local_sram_address = 0; 

sram_wait_state_counter = sram_wait_states; 

sram_checksum = 0; 

perform_sram_test <= 1; 

sram_test_state <= start_sram_test; 

end 

end 

start_sram_test: 

begin 

enable_sram_read(local_sram_address); 

sram_test_state <= sram_wait; 

end 

sram_wait: 

begin 

sram_wait_state_counter = sram_wait_state_counter - 1; 

if (sram_wait_state_counter == 0) 

begin 

sram_checksum = sram_checksum + sram_readdata; 

sram_test_state <= sram_end_read; 

if (sram_readdata != 0) 

begin 

int_sram_address = local_sram_address; 

int_sram_data = sram_readdata; 

end 

end 

end 

sram_end_read: 

begin 

disable_sram_read(); 

local_sram_address = local_sram_address + 1; 

if (local_sram_address <= 20'h3ffff) 

begin 

sram_wait_state_counter = sram_wait_states; 

sram_test_state <= start_sram_test; 

end 

else 

begin 

sram_test_state <= waiting_to_start_sram_test; 

fire_int <= ~fire_int; 

end 

end 

default: 

begin 

disable_sram_read(); 

sram_test_state <= waiting_to_start_sram_test; 

end 

endcase
0 Kudos
0 Replies
Reply