0

私は Verilog を初めて使用し、直接マップされたキャッシュをモデル化する Verilog コードを構築しようとしています。コンパイル プロセス内ではすべて正常に動作していますが、テストベンチ モジュールが「メモリ」モジュール (インスタンス) を実行していないようです。出力変数は、テストベンチ自体で値を割り当てたものを除いて、常に不明です。メイン モジュールでデータを入力した RAM レジスタも例外ではありません。何が問題だと思いますか?事前に感謝 これはインスタンスモジュールコードです:

module Memory (outdata,address,indata,RE,WE);
input [31:0]address;
input [31:0]indata;
output reg [31:0]outdata;
input RE,WE;
//Declared the inputs and outputs
reg[31:0]RAM[0:1023];
reg[19:0]tag[0:1023];
reg valid [0:1023];
reg [31:0]Data[0:1023];
//Defined the registers that were supposed to be modules
//Divided the cache into tag,data and valid
//Starting thr Reading Process
always @ (RE or WE)
begin
  if (RE==1)
  begin
    if (address[31:12] == tag [address[11:2]])
    begin
      if (valid[address[11:2]] ==1)
      begin
        outdata = Data[address[11:2]];
      end
      else if (valid[address[11:2]] ==0) //Read from RAM
      begin
        Data[address[11:2]] = RAM [address];
        valid[address[11:2]] =1;
        outdata = Data[address[11:2]];
      end
    end
    if (address[31:12] != tag [address[11:2]])
    begin
      Data[address[11:2]] <= RAM [address];
      tag[address[11:2]] <= address [31:12];
      valid[address[11:2]] =1;
      outdata <= Data[address[11:2]];
    end
  end
  //Starting the Writing Process
  else if (WE==1)
  begin
    if(address[31:12]==tag[address[11:2]]) //Hit
    begin
      Data[address[11:2]]<=indata;
      valid[address[11:2]] =1;
      RAM[address]<=indata;
    end
    if (address[31:12] != tag [address[11:2]])//Miss
    begin
      RAM[address]<=indata;
    end
  end
end
initial
begin 
  $readmemb("D:\Verilog Project Data/MyMemory.txt",RAM);
end
endmodule
// Filling up the RAM

これは、RAM を埋めるデータをファイルに書き込むモジュールです。

module WritingToMemory;
reg[31:0]i;
integer file;
initial
begin
  i=0;
  file = $fopen("D:\Verilog Project Data/MyMemory.txt");
  $fmonitor(file,"%b\n",i);
  for(i=0; i<1024; i=i+1)
  begin
    #1
    i=i;
  end
end
endmodule

テストベンチ モジュール:

module TestBench;
reg[31:0]address;
reg[31:0]indata;
reg RE;
reg WE;
wire[31:0]outdata;
initial
begin
  $monitor("address= %b, Inputputdata= %b, Outputdata= %b, Data=%b,  RAMdata=%b",
            address,indata,outdata, Data[address[11:2]],RAM[address]);
  #10
  RE = 1;
  address = 0;
  #10
  RE=1;
  address =0;
  #10
  RE=1;
  address=0;
end
Memory M1(outdata,address,indata,RE,WE);
endmodule
4

1 に答える 1

2

これをシミュレートしたと確信していますか?現在の状態ではコンパイルされません。次回は、投稿するコードをインデントしていただけますか?

あなたの質問に行くと、3つの問題があります:

1) RAM のみを初期化すると、Tag および Valid 配列はすべて x になります。ハードウェアは、実際のシリコンでは完全に予測できません。キャッシュを使用する前に、タグと有効ビットを初期化する必要があります。理由がわかりました ;)

2) テストベンチが実際に生成するトランザクションは 1 つだけです。あなたが書いた:

#10
RE = 1;
address = 0;
#10
RE=1;
address =0;
#10
RE=1;
address=0;

最初の代入後に RE もアドレスも変更されないため、always @ (RE or WE) ステートメントが再度トリガーされることはありません。RE を 0 に戻すか、アドレスを変更する必要があります。または、実際のキャッシュの動作でより可能性が高いのは、クロックを導入することです。

3) always @ (RE or WE)アドレスは機密リストの一部ではないため、これも正しくありません。これにより、ストローブがアクティブ化されたときにのみメモリがアドレスをラッチするようになります。これは、実装で正しい場合と正しくない場合があります。それが時計を導入するもう1つの非常に良い理由です

于 2016-11-07T00:29:44.393 に答える