2012-04-11 15 views
4

私はメモリモジュール(読み取りと書き込み信号を持つ単純なreg)があるシンプルなシステムを書いています。今では、このメモリには他のいくつかのモジュールがアクセスする必要があります(同時にではありません)。だから私はこのメモリのインスタンスを作成し、それにデータを送ります。しかし、他のモジュールがどのようにしてメモリモジュールの同じインスタンスにアクセスするのか分かりません。どんな助け?他のいくつかのモジュールの内部から1つのモジュールのインスタンスにアクセスしますか? (Verilog)

編集

私はいくつかのコードでビットを明確にしましょう。これは私のメモリモジュール、単純な信号です。

module rom(
    input [15:0] addr, 
    input [15:0] data_in, 
    input rd, 
    input wr, 
    input cs, 
    output reg [15:0] data_out 
    ); 

    reg [15:0] mem[255:0]; 
    integer k; 
    initial begin 
     for(k = 0;k<256;k=k+2) 
      mem[k] = 16'h0011; 
     for(k = 1;k<256;k=k+2) 
      mem[k] = 16'h0101; 
    end 

    always @(cs)begin 
     if(wr) 
      mem[addr] <= data_in; 
     if(rd) 
      data_out <= mem[addr]; 
    end 

endmodule 

これは、今、このトップモジュールは、メモリに接続したいと思ういくつかの他のモジュールが含まれています、私の上のモジュールにこの

module Top; 

    // Inputs 
    reg [15:0] addr; 
    reg [15:0] data_in; 
    reg rd; 
    reg wr; 
    reg cs; 

    // Outputs 
    wire [15:0] data_out; 

    // Instantiate the Unit Under Test (UUT) 
    rom uut (
     .addr(addr), 
     .data_in(data_in), 
     .rd(rd), 
     .wr(wr), 
     .cs(cs), 
     .data_out(data_out) 
    ); 
.... 
.... 
.... 
endmodule 

のようなものをインスタンス化されます。どのように私はそれらを接続するか分かりません。このようなモジュールが1つあるとします。

module IF_stage(
    input clk, 
    input rst, 
    output reg [15:0] pc, 
    output [15:0] instruction 
    ); 

    //pc control 
    [email protected](posedge clk or posedge rst) 
    begin 
     if(rst) 
      pc <= 16'hFFFF; 
     else 
      pc <= pc+1; 
    end 

.... 

ここからメモリモジュールにどのようにアクセスしますか?

+2

「モジュールにアクセスする」という正確な意味は?あなたは他のもののようにそれにワイヤを接続するだけです。階層をもう少し詳しく説明し、ポート/ワイヤでモジュールを接続できない理由を説明できますか? – Tim

+0

@Tim私はワイヤで接続することはできません(私が理解できる限り)。メモリモジュールは1つであり、他のすべてのモジュールはそこからデータにアクセスしたい。したがって、他のモジュールの中にインスタンスを作成すると、別のインスタンスになります。どのように私はそれらをワイヤで接続することを提案しますか? –

答えて

1

コメントを入力すると、メモリを複数回インスタンス化しません。階層のあるレベルでメモリの1つのインスタンスを作成し、ポート/ワイヤを介してすべてのコンシューマをそこに接続します。したがって、最上位レベルでは、メモリにアクセスする3つのモジュールと、1つのメモリモジュールがあります。 3つのアクセサはそれぞれ1つのインスタンスに接続し、独自のメモリをインスタンス化しません。

メモリは他のモジュールと並列である必要があります。あなたは、メモリと通信できるインターフェイスを追加するIF_stageを変更する必要が

+0

新しいコードを質問に追加しました、多分私の質問を明確にします –

2

、このような何か:IF_stageがメモリを読み書きしたい場合

module IF_stage(
    input clk, 
    input rst, 
    input [15:0] read_data_from_memory,   //new 
    input  read_data_from_memory_valid, //new 
    output reg [15:0] pc, 
    output [15:0] instruction 

    output  do_memory_write    //new 
    output  do_memory_read    //new 
    output [15:0] memory_write_data    //new 
    output [15:0] addr       //new 

); 

はその後、それはそれの出力にアドレス/データを置きますportを使用してメモリモジュールにコマンドを発行し、read_data_from_memory(_valid)が入力ポートにアサートされるのを待ちます。これらの出力と入力は、最上位のメモリモジュールに接続されます。

ここでもバスの競合を処理する必要があります。たとえば、IF_stageの2つのインスタンスが同時に読み書きしようとすると、両方の要求を確認して転送するためのアービタモジュールが必要です一度に1つずつメモリに格納し、有効なデータを適切なモジュールに返します。

1

まず、あなたのメモリの名前は "rom"です。これは読み取り専用です。私はそれが誤植であると仮定します。そうでなければ、wrポートを持つ必要はなく、単にクライアントに個別のROMを実装し、シンセサイザに設計を最適化させることができます。

あなたの質問には、基本的には複数のクライアント間の競合を処理するアービターが必要です。すべてのクライアントはメモリを占有しているとみなすことができますが、メモリはすべてのクライアントによって共有され、同時にアクセスすることはできません。

ティムはIF_stageについてです。すべてのクライアントは、あなたはすべてのクライアントにメモリとして動作するメモリコントローラ/アービタを、必要とするが、実際にクライアント間での競合を処理する別のメモリインタフェース

output [15:0] addr; 
output [15:0] data_out; 
input [15:0] data_in; 
output  wr, rd, cs; 
input   rdy;   // only when rdy == 1, the memory operation is finished 

を持っている必要があります。3つのクライアントがあると仮定し、すべてのクライアントが一度、3サイクルあたりより少ないメモリをアクセスし、あなたは、単に次のように何かを持つことができます。すべてのクライアントのアクセス速度は、かつてよりも低い場合

module mem_ctl( 
       addr_c1, dw_c1, dr_c1, wr_c1, rd_c1, cs_c1, 
       addr_c2, dw_c2, dr_c2, wr_c2, rd_c2, cs_c2, 
       addr_c3, dw_c3, dr_c3, wr_c3, rd_c3, cs_c3, 
       addr_m, dw_m, dr_m, wr_m, rd_m, cs_m, 
       rdy_c1, rdy_c2, rdy_c3, 
       rst_n, clk 
      ); 
input  clk, rst_n; 
input [15:0] addr_c1, addr_c2, addr_c3, dw_c1, dw_c2, dw_c3; // addr and data_write from clients 
output [15:0] dr_c1, dr_c2, dr_c3;       // data read from clients 
input   wr_c1, wr_c2, wr_c3, rd_c1, rd_c2, rd_c3, cs_c1, cs_c2, cs_c3; // control from clients 
output [15:0] addr_m, dw_m;        // addr and data write to memory 
input [15:0] dr_m; 
output  wr_m, rd_m, cs_m;         // control the memory 
output  rdy_c1, rdy_c2, rdy_c3; 

reg [15:0] dr_c1, dr_c2, dr_c3, dw_m, addr_m; 
reg   wr_m, rd_m, cs_m; 

reg [1:0]  cnt; 

always @(posedge clk or negedge rst_n) 
    if (~rst_n) 
    cnt <= 0; 
    else if(cnt == 2'd2) 
    cnt <= 0; 
    else 
    cnt <= cnt + 1; 

always @(*) // Verilog 2001, if not recognizable, fill in yourself 
begin 
    case(cnt) 
    0: begin 
    dw_m = dw_c1; 
    wr_m = wr_c1; 
    cs_m = cs_c1; 
    rd_m = rd_c1; 
    dr_c1 = dr_m; 
    end 
    1: begin 
    dw_m = dw_c2; 
    wr_m = wr_c2; 
    cs_m = cs_c2; 
    rd_m = rd_c2; 
    dr_c2 = dr_m; 
    end 
    default: begin 
    dw_m = dw_c3; 
    wr_m = wr_c3; 
    cs_m = cs_c3; 
    rd_m = rd_c3; 
    dr_c3 = dr_m; 
    end 
    endcase 
end 

assign rdy_c1 = (cnt == 0) & cs_c1; 
assign rdy_c2 = (cnt == 1) & cs_c2; 
assign rdy_c3 = (cnt == 2) & cs_c3; 

endmodule 

をしかし、これだけでOKです3サイクルごとに。アクセス速度が変わってそれよりも高い場合、mem_ctlモジュールには実際のアービタが必要です。私は、ラウンドロビンのアービタがうまくいくと思います。

最終的なコメントは、すべてのクライアントの累積アクセス速度がサイクルごとに1回より大きい場合、ハードウェアでは処理できません。その場合は、他の方法で行う必要があります。

関連する問題