Forum Discussion

Altera_Forum's avatar
Altera_Forum
Icon for Honored Contributor rankHonored Contributor
13 years ago

SRAM Read Question

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
No RepliesBe the first to reply