Main Content

hdl.RAM

Single, simple dual, dual, true dual, or simple tri-port RAM for memory read/write access

Description

The hdl.RAM System object™ reads from and writes to memory locations for a single, simple dual, dual, true dual, or simple tri-port RAM. The output data is delayed one step. If your input data is:

  • scalar – the address and write enable inputs must be scalar. HDL Coder™ infers that you’re working with just a single RAM block.

  • vector – the address and write enable inputs can be scalars or vectors. HDL Coder infers that you need an array of parallel RAM banks. When you specify scalar inputs for the write enable and address ports, the System object applies the same operation to each RAM bank.

  • bus – the address and write enable inputs must be scalar. HDL Coder infers that you need an array of parallel RAM banks.

The hdl.RAM System object can have 231 bytes of internal storage. The RAM size takes into account the address width, the number of bytes that are used to store each word, and the number of RAM banks.

To read from or write to memory locations in the RAM:

  1. Create the hdl.RAM object and set its properties.

  2. Call the object with arguments, as if it were a function.

To learn more about how System objects work, see What Are System Objects?

Creation

Description

ram = hdl.RAM returns a single port RAM System object that you can write to or read from a memory location.

example

ram = hdl.RAM(Name,Value) returns a single, simple dual, dual, true dual, or simple tri-port RAM System object with properties set using one or more name-value pairs.

example

Properties

expand all

Unless otherwise indicated, properties are nontunable, which means you cannot change their values after calling the object. Objects lock when you call them, and the release function unlocks them.

If a property is tunable, you can change its value at any time.

For more information on changing property values, see System Design in MATLAB Using System Objects.

Type of RAM, specified as either:

  • 'Single port' — Create a single-port RAM with write data, write address, and write enable as inputs and read data as the output.

  • 'Simple dual port' — Create a simple dual-port RAM with write data, write address, write enable, and read address as inputs and data from the read address as the output.

  • 'Dual port' — Create a dual-port RAM with write data, write address, write enable, and read address as inputs and data from the read address and write address as the outputs.

  • 'True dual port' — Create a true dual-port RAM with write data a and b, write/read address a and b, and write enable a and b as inputs and data from the write address a and b as the outputs.

  • 'Simple tri port' — Create a simple tri-port RAM with write data, write address, write enable, and read address a and b as inputs and data from the read address a and b as the outputs.

Option to use the asynchronous read feature in your target hardware, specified as a numeric or logical 1 (true) or 0 (false). Boards that support asynchronous read allow the hardware to execute a read instruction immediately instead of waiting one cycle. This property is not available when you specify RAMType as True dual port.

Behavior for write output, specified as either:

  • 'New data' — Send out new data at the address to the output.

  • 'Old data' — Send out old data at the address to the output.

Dependencies

Specify this property when you set RamType to 'Single port', 'Dual port', or 'True dual port'. This property does not apply for the Simple Dual Port RAM or the Simple Tri Port RAM object. This property is not available if you set AsyncRead to true.

Initial simulation output of the System object, specified as either:

  • A scalar value.

  • A vector with one-to-one mapping between the initial value and the RAM words.

Since R2024b

If you specify:

  • true

    • The RAM delays the input data by one cycle before the output can read it.

    • The RAM is cycle-accurate to the generated HDL code.

  • false

    • The RAM reads and outputs the input data immediately, but adds one cycle of latency during HDL code generation.

    • You can leverage clock-rate pipelining when you specify an oversampling value or work with multirate models.

Dependencies

To enable this property, set AsyncRead to 0 (false).

Usage

Description

dataOut = ram(wrData,rwAddress,wrEn) reads the value in memory location rwAddress when wrEn is false and writes the value wrData into the memory location rwAddress when wrEn is true. dataOut is the new or old data at rwAddress. Use this syntax when you create a single port RAM System object.

rdDataOut = ram(wrData,wrAddress,wrEn,rdAddress) writes the value wrData into memory location wrAddress when wrEn is true. rdDataOut is the old data at the address location rdAddress. Use this syntax when you create a simple dual-port RAM System object.

[wrDataOut,rdDataOut] = ram(wrData,wrAddress,wrEn,rdAddress) writes the value wrData into the memory location wrAddress when wrEn is true. wrDataOut is the new or old data at memory location wrAddress, and rdDataOut is the old data at the address location rdAddress. Use this syntax when you create a dual-port RAM System object.

[wrDataOutA,wrDataOutB] = ram(wrDataA,wrAddressA,wrEnA,wrDataB,wrAddressB,wrEnB) writes the value wrDataA into the memory location wrAddressA when wrEnA is true and writes the value wrDataB into the memory location wrAddressB when wrEnB is true. wrDataOutA is the new or old data at memory location wrAddressA. wrDataOutB is the new or old data at the memory location wrAddressB. wrAddressA and wrAddressB cannot be the same address. Use this syntax when you create a true dual-port RAM System object.

[rdDataOutA,rdDataOutB] = ram(wrData,wrAddress,wrEn,rdAddressA,rdAddressB) writes the value wrData into the memory location wrAddress when wrEn is true. rdDataOutA is the old data at address location rdAddressA, and rdDataOutB is the old data at the address location rdAddressB. Use this syntax when you create a simple tri-port RAM System object.

Input Arguments

expand all

Data to write into the RAM memory location when wrEn is true, specified as a scalar or a vector. This value can be double, single, half, integer, or a fixed-point (fi) object, and can be real or complex. The hdl.RAM System object uses fixed-point data internally for address calculations, which results in a checkout of the Fixed-Point Designer™ product license.

Bus Support:

You can use non-virtual bus at the data port for HDL code generation.

Data Types: single | double | half | int8 | int16 | int32 | uint8 | uint16 | uint32 | fi

Address to write or read, specified as a scalar or a vector. The System object writes the data from wrData to this address when wrEn is true and reads the value in memory location rwAddress when wrEn is false. This value can be either fixed-point (fi) or integer, must be unsigned, and must be between 2 and 31 bits long. Specify this address when you create a single-port RAM object.

Note

  • Even if the input data is a built-in integer data type, the hdl.RAM System object uses fixed-point data type internally for address calculations when RAM banks are used, which results in a checkout of the Fixed-Point Designer product license.

  • The hdl.RAM System object can have only 231 bytes of internal storage. The address depends on the number of bytes used to store each word, and the number of RAM banks.

Data Types: uint8 | uint16 | fi

Write enable, specified as a numeric or logical 1 (true) or 0 (false). When wrEn is true, you write the wrData into the RAM memory location. If you create a single-port RAM, the System object reads the value in the memory location when wrEn is false.

Data Types: logical

Address to read the data from when you create a simple dual-port RAM or dual-port RAM System object, specified as a scalar or vector. This value can be either fixed-point (fi) or integer, must be unsigned, and must be between 2 and 31 bits long.

Note

  • Even if the input data is a built-in integer data type, the hdl.RAM System object uses fixed-point data type internally for address calculations when RAM banks are used, which results in a checkout of the Fixed-Point Designer product license.

  • The hdl.RAM System object can have only 231 bytes of internal storage. The address depends on the number of bytes used to store each word, and the number of RAM banks.

Data Types: uint8 | uint16 | fi

Address to write the data into when you create a simple dual-port RAM, dual-port RAM, or simple tri-port RAM System object, specified as a scalar or vector. This value can be either fixed-point (fi) or integer, must be unsigned, and must be between 2 and 31 bits long.

Note

  • Even if the input data is a built-in integer data type, the hdl.RAM System object uses fixed-point data type internally for address calculations when RAM banks are used, which results in a checkout of the Fixed-Point Designer product license.

  • The hdl.RAM System object can have only 231 bytes of internal storage. The address depends on the number of bytes used to store each word, and the number of RAM banks.

Data Types: uint8 | uint16 | fi

Data to write into the RAM memory location when wrEnA is true, specified as a scalar or vector. This value can be double, single, half, integer, or a fixed-point (fi) object, and can be real or complex. This write data is used for a true dual-port RAM System object. The hdl.RAM System object uses fixed-point data type internally for address calculations when RAM banks are used, which results in a checkout of the Fixed-Point Designer product license.

Bus Support:

You can use non-virtual bus at the data port for HDL code generation.

Data Types: single | double | half | int8 | int16 | uint8 | uint16 | fi

Address to write the wrDataA into when you create a true dual-port RAM System object, specified as a scalar or vector. This value can be either fixed-point (fi) or integer, must be unsigned, and must be between 2 and 31 bits long.

Note

  • Even if the input data is a built-in integer data type, the hdl.RAM System object uses fixed-point data type internally for address calculations when RAM banks are used, which results in a checkout of the Fixed-Point Designer product license.

  • The hdl.RAM System object can have only 231 bytes of internal storage. The address depends on the number of bytes used to store each word, and the number of RAM banks.

Data Types: uint8 | uint16 | fi

Write enable, specified as a numeric or logical 1 (true) or 0 (false). When wrEnA is true, you write the wrDataA into the RAM memory location. This enable is used for a true dual-port RAM System object.

Data Types: logical

Data that you write into the RAM memory location when wrEnB is true, specified as a scalar or vector. This value can be double, single, half, integer, or a fixed-point (fi) object, and can be real or complex. This write data is used for a true dual-port RAM System object. The hdl.RAM System object uses fixed-point data type internally for address calculations when RAM banks are used, which results in a checkout of the Fixed-Point Designer product license.

Bus Support:

You can use non-virtual bus at the data port for HDL code generation.

Data Types: single | double | half | int8 | int16 | uint8 | uint16 | fi

Address to write the wrDataB into when you create a true dual-port RAM System object, specified as a scalar or vector. This value can be either fixed-point (fi) or integer, must be unsigned, and must be between 2 and 31 bits long.

Note

  • Even if the input data is a built-in integer data type, the hdl.RAM System object uses fixed-point data type internally for address calculations when RAM banks are used, which results in a checkout of the Fixed-Point Designer product license.

  • The hdl.RAM System object can have only 231 bytes of internal storage. The address depends on the number of bytes used to store each word, and the number of RAM banks.

Data Types: uint8 | uint16 | fi

Write enable, specified as a numeric or logical 1 (true) or 0 (false). When wrEnB is true, you write the wrDataB into the RAM memory location. This enable is used for a true dual-port RAM System object.

Data Types: logical

Address to read the data from and store in rdDataOutA when you create a simple tri-port RAM System object, specified as a scalar or vector. This value can be either fixed-point (fi) or integer, must be unsigned, and must be between 2 and 31 bits long.

Note

  • Even if the input data is a built-in integer data type, the hdl.RAM System object uses fixed-point data type internally for address calculations when RAM banks are used, which results in a checkout of the Fixed-Point Designer product license.

  • The hdl.RAM System object can have only 231 bytes of internal storage. The address depends on the number of bytes used to store each word, and the number of RAM banks.

Data Types: uint8 | uint16 | fi

Address to read the data from and store in rdDataOutA when you create a simple tri-port RAM System object, specified as scalar or vector. This value can be either fixed-point (fi) or integer, must be unsigned, and must be between 2 and 31 bits long.

Note

  • Even if the input data is a built-in integer data type, the hdl.RAM System object uses fixed-point data type internally for address calculations when RAM banks are used, which results in a checkout of the Fixed-Point Designer product license.

  • The hdl.RAM System object can have only 231 bytes of internal storage. The address depends on the number of bytes used to store each word, and the number of RAM banks.

Data Types: uint8 | uint16 | fi

Output Arguments

expand all

Output data that the System object reads from the memory location rwAddress of a single-port RAM object when wrEn is false, returned as a scalar or vector.

Old output data that the System object reads from the memory location rdAddress of a simple dual port RAM or dual port RAM System object, returned as a scalar or vector.

New or old output data that the System object reads from the memory location wrAddress of a simple dual port RAM or dual port RAM System object, returned as a scalar or vector.

New or old output data that the System object reads from the memory location wrAddressA of a true dual port RAM System object, returned as a scalar or vector.

New or old output data that the System object reads from the memory location wrAddressB of a true dual port RAM System object, returned as a scalar or vector.

Old output data that the System object reads from the memory location rdAddressA of a simple tri port RAM System object, returned as a scalar or vector.

Old output data that the System object reads from the memory location rdAddressB of a simple tri port RAM System object, returned as a scalar or vector.

Object Functions

To use an object function, specify the System object as the first input argument. For example, to release system resources of a System object named obj, use this syntax:

release(obj)

expand all

stepRun System object algorithm
releaseRelease resources and allow changes to System object property values and input characteristics
resetReset internal states of System object

Examples

collapse all

Construct System object to read from or write to a memory location in RAM. Set WriteOutputValue to Old data to return the previous value stored at the write address.

The output data port corresponds to the read/write address passed in. During a write operation, the old data at the write address is sent out as the output.

ram_1p = hdl.RAM('RAMType','Single port',...
                           'WriteOutputValue','Old data')
ram_1p = 
  hdl.RAM with properties:

   Main
             RAMType: 'Single port'
           AsyncRead: false
    WriteOutputValue: 'Old data'
     RAMInitialValue: 0

  Use get to show all properties

dataLength    = 10;
dataIn = 1:10;
dataOut = zeros(1,dataLength);

Write a count pattern to the memory. Previous values on the first writes are all zero.

for ii = 1:dataLength
  addressIn   = uint8(ii-1);
  writeEnable = true;
  dataOut(ii) = ram_1p(dataIn(ii),addressIn,writeEnable);
end
dataOut
dataOut = 1×10

     0     0     0     0     0     0     0     0     0     0

Read the data back.

for ii = 1:dataLength
  addressIn   = uint8(ii-1);
  writeEnable = false;
  dataOut(ii) = ram_1p(dataIn(ii),addressIn,writeEnable);
end
dataOut
dataOut = 1×10

     0     1     2     3     4     5     6     7     8     9

Now, write the count in reverse order. The previous values are the original count.

for ii = 1:dataLength
  addressIn   = uint8(ii-1);
  writeEnable = true;
  dataOut(ii) = ram_1p(dataIn(dataLength-ii+1),addressIn,writeEnable);
end
dataOut
dataOut = 1×10

    10     1     2     3     4     5     6     7     8     9

Create System object that writes to a single port RAM and reads the newly written value.

Construct single-port RAM System object. When you write a location, the object returns the new value. The size of the RAM is inferred from the bitwidth of the address and write data on the first call to the object.

ram_1p = hdl.RAM('RAMType','Single port','WriteOutputValue','New data');
dataLength       = 16;
[dataIn,dataOut] = deal(uint8(zeros(1,dataLength)));

Write randomly generated data to the System object, and then read data back out again.

for ii = 1:dataLength
  dataIn(ii)  = randi([0 63],1,1,'uint8');
  addressIn   = fi((ii-1),0,4,0);
  writeEnable = true;
  dataOut(ii) = ram_1p(dataIn(ii),addressIn,writeEnable);
end  
dataOut
dataOut = 1x16 uint8 row vector

    0   52   57    8   58   40    6   17   35   61   61   10   62   61   31   51

for ii = 1:dataLength
  addressIn   = fi((ii-1),0,4,0);
  writeEnable = false;
  dataOut(ii) = ram_1p(dataIn(ii),addressIn,writeEnable);
end
dataOut
dataOut = 1x16 uint8 row vector

    9   52   57    8   58   40    6   17   35   61   61   10   62   61   31   51

Construct System object to read from and write to different memory locations in RAM.

The output data port corresponds to the read address. If a read operation is performed at the same address as the write operation, old data at that address is read out as the output. The size of the RAM is inferred from the bitwidth of the address and write data on the first call to the object.

ram_2p = hdl.RAM('RAMType','Simple dual port');
dataLength       = 16;
[dataIn,dataOut] = deal(uint8(zeros(1,dataLength)));

Write randomly generated data to the System object, and read the old data from the same address.

for ii = 1:dataLength
  dataIn(ii)  = randi([0 63],1,1,'uint8');
  wrAddr  = fi((ii-1),0,4,0);
  writeEnable = true;
  dataOut(ii) = ram_2p(dataIn(ii),wrAddr,writeEnable,wrAddr);
end  
dataOut
dataOut = 1x16 uint8 row vector

   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0

Write and read from different addresses. The object returns the read result after one cycle delay.

for ii = 1:dataLength
  wrAddr   = fi((ii-1),0,4,0);
  rdAddr   = fi(dataLength-ii+1,0,4,0);
  writeEnable = true;
  dataOut(ii) = ram_2p(dataIn(ii),wrAddr,writeEnable,rdAddr);
end
dataOut
dataOut = 1x16 uint8 row vector

    0    9    9   51   31   61   62   10   61   61   35   17    6   40   58    8

Construct System object to read from and write to different memory locations in RAM.

There are two output ports: a write output data port and a read output data port. The write output data port sends out the new data at the write address. The read output data port sends out the old data at the read address. The size of the RAM is inferred from the bitwidth of the address and write data on the first call to the object.

ram_2p = hdl.RAM('RAMType','Dual port','WriteOutputValue','New data');
dataLength       = 16;
[dataIn,wrDataOut,rdDataOut] = deal(uint8(zeros(1,dataLength)));

Write randomly generated data to the System object, and read the old data from the same address.

for ii = 1:dataLength
  dataIn(ii)  = randi([0 63],1,1,'uint8');
  wrAddr  = fi((ii-1),0,4,0);
  writeEnable = true;
  [wrDataOut(ii),rdDataOut(ii)] = ram_2p(dataIn(ii),wrAddr,writeEnable,wrAddr);
end  
wrDataOut
wrDataOut = 1x16 uint8 row vector

    0   52   57    8   58   40    6   17   35   61   61   10   62   61   31   51

rdDataOut
rdDataOut = 1x16 uint8 row vector

   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0

Write and read from different addresses. The object returns the read result after one cycle delay.

for ii = 1:dataLength
  wrAddr   = fi((ii-1),0,4,0);
  rdAddr   = fi(dataLength-ii+1,0,4,0);
  writeEnable = true;
  [wrDataOut(ii),rdDataOut(ii)] = ram_2p(dataIn(ii),wrAddr,writeEnable,rdAddr);
end
wrDataOut
wrDataOut = 1x16 uint8 row vector

    9   52   57    8   58   40    6   17   35   61   61   10   62   61   31   51

rdDataOut
rdDataOut = 1x16 uint8 row vector

    0    9    9   51   31   61   62   10   61   61   35   17    6   40   58    8

Create a System object that can write vector data to a dual-port RAM and read vector data out. Each element of the vector corresponds to a separate bank of RAM. This example creates 4 16-bit banks. Each bank has eight entries.

Construct dual-port RAM System object.

ram_2p = hdl.RAM('RAMType','Dual port','WriteOutputValue','New data');

Create vector write data and addresses. Use a 3-bit address (for 8 locations), and write 16-bit data. Read and write addresses are independent. Allocate memory for the output data.

ramDataIn = fi(randi((2^16)-1,1,4),0,16,0);
ramReadAddr = fi([1,1,1,1],0,3,0);
ramWriteAddr = fi([1,1,1,1],0,3,0);
[wrOut,rdOut] = deal(fi(zeros(1,4),0,16,0));

First, write locations in bank 1 and 4, then read all banks. The write data is echoed in the wrOut output argument. The object returns read results after one cycle delay.

[wrOut,rdOut] = ram_2p(ramDataIn,ramWriteAddr,[true,false,false,true],ramReadAddr);
[wrOut,rdOut] = ram_2p(ramDataIn,ramWriteAddr,[false,false,false,false],ramReadAddr);
[wrOut,rdOut] = ram_2p(ramDataIn,ramWriteAddr,[false,false,false,false],ramReadAddr)
wrOut = 
       53393           0           0       59859

          DataTypeMode: Fixed-point: binary point scaling
            Signedness: Unsigned
            WordLength: 16
        FractionLength: 0
rdOut = 
       53393           0           0       59859

          DataTypeMode: Fixed-point: binary point scaling
            Signedness: Unsigned
            WordLength: 16
        FractionLength: 0

Algorithms

expand all

In a Simulink® model, you can use the hdl.RAM System object inside a MATLAB System or a MATLAB Function block. If you log the output of a MATLAB System block, the output data has at least three dimensions because the MATLAB System block has at least two dimensions, and the time data adds a third dimension. For example, if you input scalar data to the block, the logged output data has the dimension 1 by 1 by N, where N is the number of time steps. To obtain an output dimension that is same as the input dimension, add a Reshape block at the output with the Output dimensionality parameter set to Derive from reference input port.

Extended Capabilities

C/C++ Code Generation
Generate C and C++ code using MATLAB® Coder™.

HDL Code Generation
Generate VHDL, Verilog and SystemVerilog code for FPGA and ASIC designs using HDL Coder™.

Fixed-Point Conversion
Design and simulate fixed-point systems using Fixed-Point Designer™.

Version History

Introduced in R2015a

expand all