概要
SRAM(Static Random Access Memory: スタティックRAM)は、フリップフロップ回路でデータを記憶する揮発性半導体メモリです。「スタティック」という名称は、DRAMが必要とするような定期的なリフレッシュ動作が不要であることに由来します。電源が供給されている限り、リフレッシュなしでデータを保持し続けます。
SRAMの最大の特徴は高速なアクセス速度です。アクセス時間は数nsから数十ns程度で、DRAMの数倍〜数十倍の速度を実現します。この速度がCPUのキャッシュメモリに採用される理由です。また、マイコン(MCU)に内蔵されるRAMもほぼすべてSRAMです。
一方で、1ビットを記憶するのに4〜6個のトランジスタが必要なため、DRAMに比べてビット単価が高く、集積度が低い(同面積で実現できる容量が小さい)という欠点があります。組み込みシステムでは用途に応じてSRAMとDRAMを使い分けるか、マイコン内蔵SRAMのみで完結する設計を取ります。
歴史・背景
SRAMの歴史はDRAMとほぼ同時期の1960年代に始まります。初期のメモリは磁気コアメモリが主流でしたが、半導体プロセスの発展とともにSRAMが実用化されました。
1970年代にはIntelやMostek(後にTexas Instrumentsが買収)が商用SRAMを量産。当初はCPUの主記憶として使われていましたが、DRAMが容量・コストで圧倒的に有利になるにつれ、SRAMはキャッシュメモリ・小容量高速バッファという役割に特化していきました。
1980年代〜1990年代、マイコンの内蔵RAMとしてSRAMが標準化しました。組み込み向けマイコンは数KB〜数百KBのSRAMを内蔵し、プログラムの変数・スタック・ヒープを格納します。
現在のCPUではL1キャッシュ(数十KB〜数百KB)・L2キャッシュ(数百KB〜数MB)がSRAMで構成されており、DRAM(主記憶)とプロセッサの速度差を埋める重要な役割を担っています。マイコン内蔵SRAM容量は年々増加し、STM32H7では1MB以上のSRAMを内蔵するものもあります。
技術仕様
セル構造(6T SRAMセル)
標準的なSRAMセルは6個のトランジスタ(6T)で構成されます:
VDD
|
[P1] [P2]
| |
Q ─┬──[N1] [N2]──┬─ /Q
| | | |
└───[N3] [N4]───┘
| |
WL(Word Line)
| |
BL /BL
(Bit Line) (Bit Line Bar)
|
GND
P1・P2はPMOSロードトランジスタ、N1・N2はNMOSドライバトランジスタ、N3・N4はNMOSアクセストランジスタです。Q・/Qが互いに反転した状態で安定し、データを保持します。
主要仕様比較
| 項目 | 高速SRAM(CPU L1$) | 汎用SRAM(MCU内蔵) | 低電力SRAM |
|---|---|---|---|
| アクセス時間 | 0.5〜2ns | 5〜30ns | 10〜100ns |
| 動作電圧 | 0.5〜1.2V | 1.8〜3.3V | 1.2〜1.8V |
| 動作電流 | 数百mA | 数mA〜数十mA | 数µA〜数mA |
| スタンバイ電流 | − | 数µA | 数nA〜数µA |
| 典型容量 | 32KB〜1MB | 2KB〜8MB | 4KB〜数MB |
メモリ帯域幅
SRAMはバス幅・クロック周波数によって帯域幅が決まります:
- 例: 32ビット幅、200MHz動作 → 理論帯域幅 = 32bit × 200MHz = 6.4Gbps = 800MB/s
- マイコン内蔵SRAM(STM32H7, AHB 240MHz, 32bit) → 960MB/s
動作原理
読み出し動作
- ワード線(WL)をHighにしてアクセストランジスタN3・N4をONにする
- ビット線(BL・/BL)をVDDにプリチャージしておく
- セルの状態(Q=High, /Q=Lowまたはその逆)がBL・/BLに現れる
- センスアンプがBLと/BLの差を増幅してデータを出力
読み出しはデータを破壊しない(Non-destructive Read)ため、読み出し後の書き戻しは不要です(DRAMとの大きな違い)。
書き込み動作
- ワード線(WL)をHighにしてアクセストランジスタをON
- BLに書き込みたいデータを、/BLにその反転をドライブ
- セルの状態が強制的に反転・保持される
スリープ・低電力モード
マイコンのDeep Sleepモードでは、SRAMへの供給電圧を通常より低いリテンション電圧(例: 0.7V〜1.0V)まで下げてデータを保持しながら消費電力を最小化する「SRAMリテンション」機能があります。STM32等では「RAM retention in Standby」として実装されています。
// STM32 低電力モード設定でSRAMリテンション
PWR_STOPModeTypeDef sStopModeConfig = {
.RamRetention = PWR_RAMRETENTION_ENABLE, // RAM内容を保持
.WakeUpFrom = PWR_WAKEUP_FROM_GPIO,
};
HAL_PWREx_EnterSTOPMode(&sStopModeConfig, PWR_STOPENTRY_WFI);
用途・ユースケース
マイコン内蔵RAM
STM32・nRF52・ESP32などのマイコンに内蔵されるRAMはすべてSRAMです。プログラムの変数・スタック・ヒープ・DMAバッファ・通信バッファなど実行時データをすべてここに格納します。容量は数KB〜数MB程度です。
// マイコンのメモリ配置イメージ(スタートアップ後)
// フラッシュ: コード・const定数
// SRAM:
// .data セクション (初期値ありグローバル変数)
// .bss セクション (初期値なしグローバル変数、0クリア済み)
// ヒープ (mallocで動的確保)
// スタック (関数呼び出し・ローカル変数)
// スタックサイズの設定例 (GCCリンカスクリプト)
// _Min_Stack_Size = 0x400; /* 1KB スタック */
// _Min_Heap_Size = 0x200; /* 512B ヒープ */
CPUキャッシュ
PCやMPUのL1/L2/L3キャッシュはSRAMで構成されます。CPUコアとDRAM(主記憶)の速度差(100倍以上)を埋めるために、頻繁にアクセスするデータをSRAMキャッシュに保持します。詳細はキャッシュを参照してください。
外付けSRAM(高速バッファ)
画像処理・動画処理など大きなバッファが必要でDRAMほどは不要な用途に、外付けSRAMが使われます。接続はSPI SRAM(23LCシリーズ等)や高速パラレルSRAMです。
// SPI SRAM (Microchip 23LC1024) 読み書き例
void sram_write(uint32_t addr, const uint8_t *data, size_t len) {
spi_select();
spi_send_byte(0x02); // WRITE コマンド
spi_send_byte((addr >> 16) & 0xFF);
spi_send_byte((addr >> 8) & 0xFF);
spi_send_byte( addr & 0xFF);
for (size_t i = 0; i < len; i++) spi_send_byte(data[i]);
spi_deselect();
}
Tightly Coupled Memory (TCM)
ARM Cortex-M7/A系CPUは、TCM(Tightly Coupled Memory)と呼ばれるSRAMをコアに直結する構成を持ちます。TCMへのアクセスは他のSRAMより高速で、割り込みハンドラ・タイムクリティカルな処理コードをTCMに配置することで確定的な低レイテンシを実現できます。
// TCM配置の例 (GCC属性)
// ITCM: 命令TCM(コード配置)
// DTCM: データTCM(データ配置)
__attribute__((section(".ITCM_func")))
void isr_critical(void) {
// ここに配置されたコードはITCMから実行される(最速)
}
不揮発SRAM(nvSRAM)
バッテリバックアップ付きSRAM(bbSRAM)や、フラッシュとSRAMを組み合わせたnvSRAM(Non-Volatile SRAM)は、電源断でもデータを保持します。産業用途のリアルタイムクロックバックアップ・設定値保持などに使われます。
実装・開発のポイント
スタックオーバーフロー
マイコン開発で最も多いSRAM関連のバグはスタックオーバーフローです。スタックがヒープ領域・.bss領域に侵食するとデータ破壊・クラッシュが発生します。対策:
// 1. スタック使用量のモニタリング(RTOSのタスクスタック)
// FreeRTOS: タスクスタックの高水位マーク確認
UBaseType_t highWaterMark = uxTaskGetStackHighWaterMark(NULL);
// highWaterMark が 0 に近いと危険(スタックオーバーフロー寸前)
// 2. リンカスクリプトでスタック領域を固定し、
// オーバーフロー検出用のガードパターンを配置
// 3. MPUでスタック領域外アクセスを検出(ARM Cortex-M)
SRAM容量の見積もり
SRAMを使い切らないように事前に見積もりが重要です:
SRAM使用量 = .data + .bss + ヒープ最大 + スタック最大 + DMAバッファ + ...
確認コマンド:
$ arm-none-eabi-size firmware.elf
text data bss dec hex filename
45232 1024 8192 54448 D4F0 firmware.elf
# data: 初期値ありグローバル変数 → フラッシュ+SRAMに存在
# bss : 初期値なしグローバル変数 → SRAMのみ
DMAバッファのアライメント
DMAを使う場合、転送バッファはDMAが要求するアライメント(通常4バイトまたはキャッシュラインサイズ)に合わせる必要があります。
// 4バイトアラインされたDMAバッファ
__attribute__((aligned(4))) uint8_t dma_rx_buf[256];
__attribute__((aligned(32))) uint8_t cache_aligned_buf[1024]; // Cortex-M7 32Bキャッシュライン
他技術との比較
SRAM vs DRAM
| 項目 | SRAM | DRAM |
|---|---|---|
| セル構造 | 6T(フリップフロップ) | 1T1C(トランジスタ+キャパシタ) |
| リフレッシュ | 不要 | 必要(64ms周期) |
| アクセス速度 | 高速(数ns〜) | 低速(数十ns〜) |
| ビット単価 | 高い | 低い |
| 集積度 | 低い | 高い |
| 容量 | 〜数十MB | GB単位 |
| 用途 | キャッシュ・MCU RAM | 主記憶・フレームバッファ |
SRAM vs フラッシュ
フラッシュメモリは不揮発でデータを保持しますが、書き込みが遅く書き換え寿命があります。SRAMは高速に読み書きできますが電源断でデータが消えます。組み込みシステムでは、コードと定数はフラッシュに格納し、実行時データはSRAMに配置するのが基本です。