1

私は以下のコードモジュールを持っています

always @(posedge Clk) begin

ForwardA = 0;
ForwardB = 0;

//EX Hazard
if (EXMEMRegWrite == 1) begin
 if (EXMEMrd != 0)
    if (EXMEMrd == IDEXrs)
        ForwardA = 2'b10;
   if (EXMEMrd == IDEXrt && IDEXTest == 0)
        ForwardB = 2'b10;
end


//MEM Hazard

if (MEMWBRegWrite == 1) begin
 if (MEMWBrd != 0) begin
    if (!(EXMEMRegWrite == 1 && EXMEMrd != 0 && (EXMEMrd == IDEXrs)))
            if (MEMWBrd == IDEXrs)
                ForwardA = 2'b01;
    if (IDEXTest == 0) begin
        if (!(EXMEMRegWrite == 1 && EXMEMrd != 0 && (EXMEMrd == IDEXrt)))
            if (MEMWBrd == IDEXrt)
                ForwardB = 2'b01;
    end
 end
end

end

問題は、ForwardAとForwardBである出力が、次の立ち上がりクロックエッジではなく、立ち上がりクロックエッジでは更新されないことです...これはなぜですか?出力が同じ正の立ち上がりクロックエッジで更新されるように解決するにはどうすればよいですか?

これが私が意味することです: 代替テキストhttp://img693.imageshack.us/img693/8660/timing.jpg

ForwardAは、同じ立ち上がりクロックエッジではなく、次の立ち上がりクロックエッジで2に更新されます。

4

1 に答える 1

2

この操作を期待します。それは、入力信号などがどのようMEMWBRegWriteに駆動されているかに関係しています。クロックから何かを起動すると、波形ビューアで一致しているように見えても、他のクロックブロックは次のクロックエッジまでそれを認識しないことを覚えておく必要があります。

起こっていることの現実を考えることは役に立ちます。クロックエッジから何かを起動すると、これはすぐには発生しません。わずかな遅延が発生します。RTL sim波形にはこれらの小さな遅延は見られませんが、デルタサイクルの形で存在します。

        1             2             3
         ______        ______
clk   __|      |______|      |______|

 q   ----<======A======X=======B======X====

 n1  -----<====A+1======X======B+1=====X=====        (combinatorial/logic)
 n2  ------------------X======A+1=====X=====B+1      (sequential/clocked)

上記の私の非常に素晴らしいアスキーアートを見ると、qクロックエッジ2で「B」に設定されていますが、これが伝播するまでには時間がかかります。すべて@(posedge clk)のブロックには、qクロックエッジ2で「A」の値が表示されます。次のエッジ3まで「B」は表示されません。これは、表示されているように見えます。

ただし、必要な場合は、ほぼすぐに信号を生成できます。n1ただし、これを行うには、組み合わせロジック(上記)を使用する必要があります。

 wire n1;
 assign n1 = q + 1;

また

 reg n1;
 always @(*)
     n1 = q + 1;

シーケンシャルロジックの使用(あなたがそうであるように):

 reg n2;
 always @(posedge clk)
     n2 <= q + 1;

'<='に注意してください。これはノンブロッキング割り当てです。これを使用して、デザインのレジスタまたはフロップになりたいものに割り当てることをお勧めします。はるかに良い説明については、SunburstDesignの論文をご覧ください。

于 2010-05-05T12:14:42.640 に答える