ROMRTL記述

[] [] []


ROMは、アドレスを入力としてデータを出力するデコーダと同じだからcase文で書ける。

/* シングルポートROM - case文で書く*/

always @(posedge clk)

  case(adr)

  12'd0: dat <= 8'h00;

  12'd1: dat <= 8'h11;

  12'd2: dat <= 8'h22;

  ...

  12'd4095: dat <= 8'hff;

  endcase

別の書き方として、FPGAの場合、コンフィギュレーション時にブロックRAMに初期値がロードされるので、ライトなしのRAMRTL記述すればROMになる。コンフィギュレーション時の初期値代入はinitial文で書く。

/* シングルポートROM - initial文で値を書く */

reg[7:0] rom[0:4095];

always @(posedge clk) dat <= rom[adr];

initial begin

  rom[0] = 8'h00;

  rom[1] = 8'h11;

  rom[2] = 8'h22;

  ...

  rom[4095] = 8'hff;

end

この書き方だと2-port ROMも書ける。(2-port ROMは、処理を並列にするため同じROM値を並列にリードするときに必要になる)

/* デュアルポートROM - initial文で値を書く */

reg[7:0] rom[0:4095];

always @(posedge clk) dat0 <= rom[adr0];

always @(posedge clk) dat1 <= rom[adr1];

initial begin

  rom[0] = 8'h00;

  rom[1] = 8'h11;

  rom[2] = 8'h22;

  ...

  rom[4095] = 8'hff;

end

◇◇

ユーザガイドには、$readmemh()でテキストファイルから値を読み込む方法が載っているが、ソースファイルとテキストファイルに分けてしまうと管理しにくくなるのでよくない。

/* シングルポートROM - initial文で値をファイルから読み込む */

reg[7:0] rom[0:4095];

always @(posedge clk) dat <= rom[adr];

initial begin

  $readmemh("rom.txt",rom);

end

/* rom.txt */

00

11

22

...

ff

◇◇◇

もし値が数式で表せるならばfor文で書いてもよい。

/* シングルポートROM - initial文で値を数式で与える */

reg[7:0] rom[0:4095];

always @(posedge clk) dat <= rom[adr];

integer i;

initial begin

  for(i=0; i<4096; i=i+1) rom[i] = (i%255);

end


[] [] []