Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations strongm on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Writing and reading from RAM

Status
Not open for further replies.

DrStrangelove13

Programmer
Jun 20, 2004
7
US
Hello,

I am working on a project to eventualy display frames on a monitor via the Xs40 board. Since this is such a large undertaking I have decided to start with writing some values to RAM and then getting them to display on the 7seg in order to gain a better understanding of RAM I/O and how to manipulate it.

I am a little unsure as far as how to start on this and have it work correctly so I was hoping to find some help here. My two main questions are....

(1) How would I go about writing something into RAM. Lets say I wanted to input a phrase like "hello world" in ascii.

(2) When I enable the OEB line, how do I get the contents of the RAM to display on my seven segment display?


What I envision is writing "hello world" into the RAM letter by letter and then enabling the OEB line and reading the values in each location in RAM and incrementint a RAM counter after each pass. Any hints, help, or examples to get me started in the right direction would be very appreciated.
 
first find out what you have to do to the RAM interface in order to write. look for specs on the RAM part.

then write some VHDL to do that. post your results and we will go from there.

--
 
Thanks for the response VHDL guy. Here is what I have discovered that has lead me to more confusion than before.

First of all, I am using the xs40 board with a 128kx8 RAM on it. I have written some VHDL to test writing into RAM and retreiving the contents of a particular location but I do not think I am doing this right. Here is my code....

LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL


-------------------------------------------
-- SRAM:
-- SYNCHRONOUS DATA MEMORY
-- 128K X 8BITS
-- READ ON NEGATIVE EDGE
-- WRITE ON POSITIVE EDGE
--
-- INTERFACE:
-- ADDRESS: 16 BIT ADDRESS BUS
-- DATA_IN: 8 BIT DATA INPUT BUS
-- DATA_OUT: 8 BIT DATA OUTPUT BUS
-- WE: WRITE ENABLE --ACTIVE LOW
-- OE: OUTPUT ENABLE --ACTIVE LOW
-- CE: ENABLES THE CHIP
--------------------------------------------

ENTITY SRAM IS
PORT( ADDRESS: IN STD_LOGIC_VECTOR(16 DOWNTO 0);
DATA_IN: IN STD_LOGIC_VECTOR(7 DOWNTO 0);
WE,OE,CE,CLK: IN STD_LOGIC;
DATA_OUT: OUT STD_LOGIC_VECTOR(7 DOWNTO 0)
);

END SRAM;


ARCHITECTURE SRAM_BHV OF SRAM IS

SIGNAL MEM0, MEM1, MEM2, MEM3, MEM4, MEM5, MEM6, MEM7, MEM8,
MEM9, MEMA, MEMB, MEMC, MEMD, MEME, MEMF:STD_LOGIC_VECTOR(7 DOWNTO 0);

SIGNAL DATA_OUT_S: STD_LOGIC_VECTOR(7 DOWNTO 0);


BEGIN
DATA_OUT<= DATA_OUT_S; --DATA TO BUS

READ: PROCESS(CLK, ADDRESS, DATA_IN)


BEGIN
IF(CLK'EVENT AND CLK='0') THEN --NEGATIVE EDGE READ
IF(OE='1') THEN
IF(WE='0') THEN
CASE ADDRESS IS
WHEN "0000000000000000" =>
DATA_OUT_S <= MEM0;
WHEN "0000000000000001" =>
DATA_OUT_S <= MEM1;
WHEN "0000000000000010" =>
DATA_OUT_S <= MEM2;
WHEN "0000000000000011" =>
DATA_OUT_S <= MEM3;
WHEN "0000000000000100" =>
DATA_OUT_S <= MEM4;
WHEN "0000000000000101" =>
DATA_OUT_S <= MEM5;
WHEN "0000000000000110" =>
DATA_OUT_S <= MEM6;
WHEN "0000000000000111" =>
DATA_OUT_S <= MEM7;
WHEN "0000000000001000" =>
DATA_OUT_S <= MEM8;
WHEN "0000000000001001" =>
DATA_OUT_S <= MEM9;
WHEN "0000000000001010" =>
DATA_OUT_S <= MEMA;
WHEN "0000000000001011" =>
DATA_OUT_S <= MEMB;
WHEN "0000000000001100" =>
DATA_OUT_S <= MEMC;
WHEN "0000000000001101" =>
DATA_OUT_S <= MEMD;
WHEN "0000000000001110" =>
DATA_OUT_S <= MEME;
WHEN "0000000000001111" =>
DATA_OUT_S <= MEMF;
WHEN OTHERS =>
DATA_OUT_S <= X"FF";
END CASE;
END IF;
END IF;
END IF;
END PROCESS READ;



WRITE: PROCESS(CLK,WE, ADDRESS, RESET, DATA_IN) --POSITIVE EDGE WRITE

BEGIN
IF (CLK'EVENT AND CLK='1') THEN
IF(WE='1')THEN
IF(OE='0')THEN
CASE ADDRESS IS

WHEN "0000000000000000" =>
MEM0 <= DATA_IN;
WHEN "0000000000000001" =>
MEM1 <= DATA_IN;
WHEN "0000000000000010" =>
MEM2 <= DATA_IN;
WHEN "0000000000000011" =>
MEM3 <= DATA_IN;
WHEN "0000000000000100" =>
MEM4 <= DATA_IN;
WHEN "0000000000000101" =>
MEM5 <= DATA_IN;
WHEN "0000000000000110" =>
MEM6 <= DATA_IN;
WHEN "0000000000000111" =>
MEM7 <= DATA_IN;
WHEN "0000000000001000" =>
MEM8 <= DATA_IN;
WHEN "0000000000001001" =>
MEM9 <= DATA_IN;
WHEN "0000000000001010" =>
MEMA <= DATA_IN;
WHEN "0000000000001011" =>
MEMB <= DATA_IN;
WHEN "0000000000001100" =>
MEMC <= DATA_IN;
WHEN "0000000000001101" =>
MEMD <= DATA_IN;
WHEN "0000000000001110" =>
MEME <= DATA_IN;
WHEN "0000000000001111" =>
MEMF <= DATA_IN;
WHEN OTHERS =>
MEM0 <= X"FF";
END CASE;
END IF;
END IF;
END IF;
IF(RESET = '1') THEN --INITALIZING MEMORY WITH DATA
MEM0 <= "00001111";
MEM1 <= "00001111";
MEM2 <= "00001111";
MEM3 <= "00001111";
MEM4 <= "00001111";
MEM5 <= "00001111";
MEM6 <= "00001111";
MEM7 <= "00001111";
MEM8 <= "00001111";
MEM9 <= "00001111";
MEMA <= "00001111";
MEMB <= "00001111";
MEMC <= "00001111";
MEMD <= "00001111";
MEME <= "00001111";
MEMF <= "00001111";
END IF;
END PROCESS WRITE;

END ARCHITECTURE SRAM_BHV;


Now I realize that there are a lot more than 16 locations on the RAM, but could I not test reading and writing by simply doing my design this way and then using a control chip to sends some data and an address to the RAM and then read/write to/from one of these locations? If I was to display these results on a 7-seg display, would this not work?

Any more help would be appreciated.
 
yes you could create an internal ram this way to test your system and then build an interface to your real ram.

however you should make sure that you have the exact same timing clock for clock as your interface will require otherwise you might find yourself having to change your code to adjust. I would suggest just starting with the real RAM.

its not too difficult. You have an address, read/write, maybe a chip select and data. have once process for your address, read/write and chip select. have another for your data out and another for data in.

for your data out process: if you are using an fpga, your data will be 'Z' (or you can use another block of logic with an OE and set the data to 'Z' there) when reading and valid data when writing. You will probably find that the data is a couple of clocks delaying the address and read/write, so you will need to have some internal signals to know what you are supposed to be doing based on your old read/write etc.

if you really want to go with the internal memory, i would suggest making MEM an array and then indexing it based on the lowest 4 bits of the address (then it works even in the higher address ranges, it just overwrites the lower ranges).

Also your reset condition for MEM should be either before the if clk'event for an async reset (and change if clk'event to elsif clk'event), or inside the if clk'event for a sync reset. What you have there is not really valid.

other than that, and the clock-to-clock timing of your signals (delay between address and data) it looks ok.

--
 
Thanks again for your quick response. I have reworked the RAM portion to look like this:

ENTITY SRAM IS
PORT( ADDRESS: IN STD_LOGIC_VECTOR(16 DOWNTO 0);
DATA_IN: IN STD_LOGIC_VECTOR(7 DOWNTO 0);
WE:IN STD_LOGIC;
OE:IN STD_LOGIC;
CE:IN STD_LOGIC;
CLK: IN STD_LOGIC;
DATA_OUT: OUT STD_LOGIC_VECTOR(7 DOWNTO 0)
);

END SRAM;




ARCHITECTURE SRAM_BHV OF SRAM IS

TYPE MEMORY IS ARRAY(0 TO 2**8) OF STD_LOGIC_VECTOR(7 DOWNTO 0);
SIGNAL RAM:MEMORY;

BEGIN
READ: PROCESS(ADDRESS)
BEGIN
IF (CE = '0')THEN
IF (OE = '0')THEN
DATA_OUT <=RAM(CONV_INTEGER ADDRESS));
END IF;
END IF;
END PROCESS;

WRITE: PROCESS(WE)
BEGIN
IF(WE'EVENT AND WE ='1')THEN
IF(CE = '0') THEN
RAM(CONV_INTEGER(ADDRESS))<=DATA_IN;
END IF;
END IF;
END PROCESS;
END SRAM_BHV;


I believe this is what you had suggested. Now I am guessing need to get to writing a controller for the memory that handles getting the data into and out of the RAM with correct timing. I will post progress or problems here soon. Thanks again.
 
thats going to chew up the memory and speed of your simulation. but its sometimes nice to have all the ram available like that.

One thing you could do is convert to an integer when storing the data (and on read convert back). that will speed it up a little.


Look up the ram thats on the board and make sure that you follow the same timing. but you probably got that from my first message.

--
 
Thanks for your help so far. I have another quick question regarding the memory controller....

If I was going to have some 8-bit data values to write to the RAM through the controller but instead of an external source, use an input file, how would I go about doing this?

 
the std library textio package has the functions you want.

read and readline, write and writeline are the main functions for reading and writing. readline and writeline read and write a line of data from/to the file, you then use read and write to extract structures of data from the file. You must have a very rigid file definition, its not very flexible like say perl. But for a ram you can simply write in hex say:
00 00
01 5A
02 AB
03 CD

etc. then your process just needs to look for two hex characters followed by a space, followed by two more characters. easy enough.

A quick web search found this:
I didn't look hard at it, but it looks ok.

Note: there are differences between VHDL87 and 93 in the textio package, mainly to do with how you indicate the file and the type of operation you are doing (read write etc).


--
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top