複数のバージョンのツールを入手し、それぞれ「sram_dp_hsd_svt_mvt」と「sram_sp_hde_svt_mvt」が存在する。前者はデュアルポート型、後者はシングルポート型である。各々の「hsd」は高速、「hde」は高密度を意味し、最後の「svt_mvt」はトランジスタの種類を示す。実行ファイルを直接起動することでGUIを開くことができる。
ツール内のドキュメントを確認すると、"sram_sp_hde_svt_mvt_userguide"というガイドが見つかった。このコンパイラは.ver、.lib、.lef、.gds2、.cdlなどのファイルを出力する。これらのファイルは設計フローの前後段階でよく使われる。
あるVerilogモデルのビューを選択して生成してみた。設定は以下の通りである:
ファイルの冒頭は以下のようになる:
/* verilog_memcomp Version: c0.3.2-EAC */
/* common_memcomp Version: c0.1.0-EAC */
/* lang compiler Version: 4.1.6-EAC2 Oct 30 2012 16:32:37 */
//
// CONFIDENTIAL AND PROPRIETARY SOFTWARE OF ARM PHYSICAL IP, INC.
//
// Copyright (c) 1993 - 2024 ARM Physical IP, Inc. All Rights Reserved.
//
// Use of this Software is subject to the terms and conditions of the
// applicable license agreement with ARM Physical IP, Inc.
// In addition, this Software is protected by patents, copyright law
// and international treaties.
//
// The copyright notice(s) in this Software does not indicate actual or
// intended publication of this Software.
//
// Verilog model for High Density Single Port SRAM SVT MVT Compiler
//
// Instance Name: sram_sp_hde
// Words: 4096
// Bits: 16
// Mux: 16
// Drive: 6
// Write Mask: Off
// Write Thru: Off
// Extra Margin Adjustment: On
// Test Muxes On
// Power Gating: Off
// Retention: On
// Pipeline: Off
// Read Disturb Test: Off
//
// Creation Date: Sun Jan 14 11:45:44 2024
// Version: r0p4_02eac0
//
// Modeling Assumptions: This model supports full gate level simulation
// including proper x-handling and timing check behavior. Unit
// delay timing is included in the model. Back-annotation of SDF
// (v3.0 or v2.1) is supported. SDF can be created utilyzing the delay
// calculation views provided with this generator and supported
// delay calculators. All buses are modeled [MSB:LSB]. All
// ports are padded with Verilog primitives.
//
// Modeling Limitations: None.
//
// Known Bugs: None.
//
// Known Work Arounds: N/A
//
ここにはメモリのサイズやポート情報、インスタンス名などが記載されている。また、シミュレーション時のアサーションに関する情報も含まれており、SDFによるバックアノテーションが可能であることがわかる。
ポート定義は以下の通りであり、これは主に注目すべき部分である:
`ifdef POWER_PINS
module sram_sp_hde (VDDCE, VDDPE, VSSE, CENY, WENY, AY, Q, SO, CLK, CEN, WEN, A, D,
EMA, EMAW, TEN, TCEN, TWEN, TA, TD, RET1N, SI, SE, DFTRAMBYP);
`else
module sram_sp_hde (CENY, WENY, AY, Q, SO, CLK, CEN, WEN, A, D, EMA, EMAW, TEN, TCEN,
TWEN, TA, TD, RET1N, SI, SE, DFTRAMBYP);
`endif
parameter ASSERT_PREFIX = "";
parameter BITS = 16;
parameter WORDS = 4096;
parameter MUX = 16;
parameter MEM_WIDTH = 256; // redun block size 8, 128 on left, 128 on right
parameter MEM_HEIGHT = 256;
parameter WP_SIZE = 16 ;
parameter UPM_WIDTH = 3;
parameter UPMW_WIDTH = 2;
parameter UPMS_WIDTH = 0;
output CENY;
output WENY;
output [11:0] AY;
output [15:0] Q;
output [1:0] SO;
input CLK;
input CEN;
input WEN;
input [11:0] A;
input [15:0] D;
input [2:0] EMA;
input [1:0] EMAW;
input TEN;
input TCEN;
input TWEN;
input [11:0] TA;
input [15:0] TD;
input RET1N;
input [1:0] SI;
input SE;
input DFTRAMBYP;
`ifdef POWER_PINS
inout VDDCE;
inout VDDPE;
inout VSSE;
`endif
この例では、POWER_PINSマクロを使って電源ピンを定義している。VDDCEとVDDPEの両方が存在する理由については後で調べる必要がある。データポートは以下の通りである:
| Port | Width | Direction | Function |
|---|---|---|---|
| CLK | 1 | input | クロック |
| A | 12 | input | アドレス (A[0]=LSB) |
| D | 16 | input | データ入力 (D[0]=LSB) |
| Q | 16 | output | データ出力 (Q[0]=LSB) |
| CEN | 1 | input | チップイネーブル、アクティブLOW |
| WEN | 1 | input | グローバルライトイネーブル、アクティブLOW |
さらにいくつかの追加信号も存在する:
| Port | Width | Direction | Function |
|---|---|---|---|
| RET1N | 1 | input | レティエンションモードイネーブル1、アクティブLOW |
| EMA | 3 | input | エクストラマージン調整、EMA[0]=LSB |
| EMAW | 2 | input | エクストラマージン調整ライト、EMAW[0]=LSB |
| TEN | 1 | input | テストモードイネーブル、アクティブLOW。0=テスト動作、1=通常動作 |
| TA | 12 | input | テストモードアドレス入力、TA[0]=LSB |
| TD | 16 | input | テストモードデータ入力、TD[0]=LSB |
| TCEN | 1 | input | チップイネーブルテスト入力、アクティブLOW |
| TWEN | 1 | input | ライトイネーブルテスト入力、アクティブLOW |
| CENY | 1 | output | チップイネーブルマルチプレクサ出力 |
| WENY | 1 | output | ライトイネーブルマルチプレクサ出力 |
| AY | 12 | output | アドレスマルチプレクサ出力、AY[0]=LSB |
| SO | 2 | output | スキャン出力バス |
| SI | 2 | input | スキャン入力バス |
| SE | 1 | input | スキャンイネーブル入力 |
| DFTRAMBYP | 1 | input | テストコントロール入力 |
電源ピンのVDDPE、VDDCEおよびVSSEについて、VDDPEは周辺回路の電源、VDDCEはコア配列の電源である。これは低消費電力設計において、メモリが読み書き不要な場合にVDDPEをオフにして、VDDCEのみでデータを保持できるようにするためである。
EMAはタイミングマージンを調整する信号であり、高速SRAMのみに必要。デフォルト値はEMA=011、EMAW=01である。BIST(内蔵自己テスト)機能はTEN信号により切り替えることができ、TA、TD、DFTRAMBYP、SIなどのテスト入力信号が使用される。
メモリコンパイラの設定において、RAMアレイの最大サイズは256行と320列である。例えば、マルチプレクサ幅が4の場合、最大ワード数は1024となり、マルチプレクサ幅が8の場合は最大ビット幅は40となる。
アドレスビット数はワード数と関係しており、ワード数 = 2^アドレスビット数で計算される。例えば、アドレスビット数が12であれば、ワード数は4096となる。
SRAMの設計では、以下のようなパラメータ設定が必要である:
- ワード数×ビット数=行数×列数
- 行数=ワード数/マルチプレクサ幅
- 列数=ビット数×マルチプレクサ幅
マルチプレクサ幅が大きくなると、行数が減少し、列数が増加し、メモリセルの寸法が矮小かつ広くなる。
例えば、ROMの設定はワード数=16384、ビット数=32、マルチプレクサ幅=32とした場合、行数は512、列数は1024となる。RAMの設定はワード数=8192、ビット数=32、マルチプレクサ幅=16とした場合、行数は512、列数は512となる。
生成されたコードは以下の通りである:
module sram_sp_hde_rom (CENY, WENY, AY, Q, SO, CLK, CEN, WEN, A, D, EMA, EMAW, TEN,
TCEN, TWEN, TA, TD, RET1N, SI, SE, DFTRAMBYP);
`endif
parameter ASSERT_PREFIX = "";
parameter BITS = 32;
parameter WORDS = 16384;
parameter MUX = 32;
parameter MEM_WIDTH = 1024; // redun block size 8, 512 on left, 512 on right
parameter MEM_HEIGHT = 512;
parameter WP_SIZE = 32 ;
parameter UPM_WIDTH = 3;
parameter UPMW_WIDTH = 2;
parameter UPMS_WIDTH = 0;
output CENY;
output WENY;
output [13:0] AY;
output [31:0] Q;
output [1:0] SO;
input CLK;
input CEN;
input WEN;
input [13:0] A;
input [31:0] D;
module sram_sp_hde_ram (CENY, WENY, AY, Q, SO, CLK, CEN, WEN, A, D, EMA, EMAW, TEN,
TCEN, TWEN, TA, TD, RET1N, SI, SE, DFTRAMBYP);
`endif
parameter ASSERT_PREFIX = "";
parameter BITS = 32;
parameter WORDS = 8192;
parameter MUX = 16;
parameter MEM_WIDTH = 512; // redun block size 8, 256 on left, 256 on right
parameter MEM_HEIGHT = 512;
parameter WP_SIZE = 32 ;
parameter UPM_WIDTH = 3;
parameter UPMW_WIDTH = 2;
parameter UPMS_WIDTH = 0;
output CENY;
output WENY;
output [12:0] AY;
output [31:0] Q;
output [1:0] SO;
input CLK;
input CEN;
input WEN;
input [12:0] A;
input [31:0] D;
LEFファイルをVirtuosoにインポートした結果、RAMは2:1の長方形となり、ROMは1:4の長方形となった。面積はそれぞれ2000×2000μm²であり、密度は約581KB/mm²であった。
.libファイルから.dbファイルへの変換には、以下のスクリプトを使用した:
enable_write_lib_mode
set lib_file_list [ls *.lib]
foreach lib_file ${lib_file_list} {
read_lib ${lib_file}
set lib_name [get_attribute [get_libs *] name]
set lib_file [string trim ${lib_file} ".lib"]
write_lib ${lib_name} -o ${lib_file}.db
remove_design -all
}
exit
メモリの読み書きテストを行うには、以下の設定が必要である:
sram_sp_hde_ram u_sram_sp_hde_ram
(
.CENY(),
.WENY(),
.AY(),
.Q(dout),
.SO(),
.CLK(clk),
.CEN(cen),
.WEN(wen),
.A(addr),
.D(din),
.EMA(3'b011),
.EMAW(2'b01),
.TEN(1'b1),
.TCEN(),
.TWEN(),
.TA(),
.TD(),
.RET1N(1'b1),
.SI(),
.SE(),
.DFTRAMBYP()
);
シミュレーションでは、SEが0でDFTRAMBYPが0、TENが1の場合に正常動作する。メモリ初期化のために、+define+INITIALIZE_MEMORYマクロを追加した。
メモリへのデータ書き込みには、$readmemh命令を使用し、適切なパスを指定することで問題なく読み込めた。
最終的に、ARMのメモリコンパイラのシミュレーションフローは完了し、今後の合成処理は自然に進むだろう。