Verilog 配列とメモリ
配列 ネットまたは変数の宣言は、スカラーまたはベクターのいずれかです。識別子名の後にアドレス範囲を指定することにより、任意の数の次元を作成でき、多次元配列と呼ばれます。 reg
の Verilog では配列が許可されています 、 wire
、 integer
そして real
データ型。
reg y1 [11:0]; // y is an scalar reg array of depth=12, each 1-bit wide
wire [0:7] y2 [3:0] // y is an 8-bit vector net with a depth of 4
reg [7:0] y3 [0:1][0:3]; // y is a 2D array rows=2,cols=4 each 8-bit wide
配列の特定の要素にアクセスするには、すべての次元のインデックスを指定する必要があり、他の変数の式にすることができます。 Verilog でサポートされているさまざまなデータ型の配列を作成できます。
n 1 ビット reg のメモリは、n ビット ベクトル reg と同じではないことに注意してください。
課題
y1 = 0; // Illegal - All elements can't be assigned in a single go
y2[0] = 8'ha2; // Assign 0xa2 to index=0
y2[2] = 8'h1c; // Assign 0x1c to index=2
y3[1][2] = 8'hdd; // Assign 0xdd to rows=1 cols=2
y3[0][0] = 8'haa; // Assign 0xaa to rows=0 cols=0
例
以下に示すコードは、さまざまな配列をモデル化し、割り当て、アクセスする方法を示しています。 mem1 は 8 ビット ベクトル、mem2 は深さ 4 の 8 ビット配列 (範囲 [0:3] で指定)、mem3 は 4 行 2 列の 16 ビット ベクトル 2D 配列です。これらの変数には異なる値が割り当てられ、出力されます。
module des ();
reg [7:0] mem1; // reg vector 8-bit wide
reg [7:0] mem2 [0:3]; // 8-bit wide vector array with depth=4
reg [15:0] mem3 [0:3][0:1]; // 16-bit wide vector 2D array with rows=4,cols=2
initial begin
int i;
mem1 = 8'ha9;
$display ("mem1 = 0x%0h", mem1);
mem2[0] = 8'haa;
mem2[1] = 8'hbb;
mem2[2] = 8'hcc;
mem2[3] = 8'hdd;
for(i = 0; i < 4; i = i+1) begin
$display("mem2[%0d] = 0x%0h", i, mem2[i]);
end
for(int i = 0; i < 4; i += 1) begin
for(int j = 0; j < 2; j += 1) begin
mem3[i][j] = i + j;
$display("mem3[%0d][%0d] = 0x%0h", i, j, mem3[i][j]);
end
end
end
endmodule
シミュレーションログ ncsim> run mem1 = 0xa9 mem2[0] = 0xaa mem2[1] = 0xbb mem2[2] = 0xcc mem2[3] = 0xdd mem3[0][0] = 0x0 mem3[0][1] = 0x1 mem3[1][0] = 0x1 mem3[1][1] = 0x2 mem3[2][0] = 0x2 mem3[2][1] = 0x3 mem3[3][0] = 0x3 mem3[3][1] = 0x4 ncsim: *W,RNQUIE: Simulation is complete.
思い出
メモリは、デジタル回路にデータと情報を保存するのに役立つデジタル ストレージ要素です。 RAM や ROM は、このようなメモリ要素の良い例です。ストレージ要素は、reg
型の 1 次元配列を使用してモデル化できます メモリーと呼ばれる .メモリ内の各要素は単語を表し、単一の配列インデックスを使用して参照されます。
ベクトルの登録
Verilog ベクトルは、変数名の左側のサイズ範囲を使用して宣言され、これらは変数のサイズに一致するフロップに実現されます。以下に示すコードでは、デザイン モジュールはクロック、リセット、およびいくつかの制御信号を受け取り、ブロックに読み書きします。
これには、レジスタと呼ばれる 16 ビットのストレージ要素が含まれており、書き込み中に更新され、読み取り中に現在の値を返します。レジスタは、同じクロック エッジで sel と wr が High のときに書き込まれます。 sel が高く、wr が低い場合、現在のデータを返します。
module des ( input clk,
input rstn,
input wr,
input sel,
input [15:0] wdata,
output [15:0] rdata);
reg [15:0] register;
always @ (posedge clk) begin
if (!rstn)
register <= 0;
else begin
if (sel & wr)
register <= wdata;
else
register <= register;
end
end
assign rdata = (sel & ~wr) ? register : 0;
endmodule
ハードウェア回路図は、書き込み用の制御ロジックがアクティブなときに 16 ビット フロップが更新され、制御ロジックが読み取り用に構成されているときに現在の値が返されることを示しています。
配列
この例では、register は、それぞれが 16 ビット幅の 4 つの位置を持つ配列です。設計モジュールは、addr と呼ばれる追加の入力信号を受け入れて、配列内の特定のインデックスにアクセスします。
module des ( input clk,
input rstn,
input [1:0] addr,
input wr,
input sel,
input [15:0] wdata,
output [15:0] rdata);
reg [15:0] register [0:3];
integer i;
always @ (posedge clk) begin
if (!rstn) begin
for (i = 0; i < 4; i = i+1) begin
register[i] <= 0;
end
end else begin
if (sel & wr)
register[addr] <= wdata;
else
register[addr] <= register[addr];
end
end
assign rdata = (sel & ~wr) ? register[addr] : 0;
endmodule
配列の各インデックスが 16 ビットのフロップであり、入力アドレスがフロップの特定のセットにアクセスするために使用されることは、ハードウェア回路図で確認できます。
Verilog