次にラウンドロビンスケジューリングでは、cpuによるビットtwiddling
-
20-08-2019 - |
質問
考え、以下の問題です。お持ちのビットを表す文字列の現在の予定スレーブに熱いエンコーディングです。例えば、"00000100"(左端に少している#7、もっとも右側#0)このレストラン#2を予定しております。
現在、私たちの次の予定スレーブにラウンドロビンスケジューリングでは、cpu制度の問題ではないでしょうか。私は、"マスク法"をスレーブを実際にしたいの開催も予定されています。次のスレーブただけるものからくりたい。
いくつかの事例とラウンドロビンスケジューリングは、人がいるように回転す。Example1:
- 電流:"00000100"
- マスク:"01100000"
- 次のスケジュール:"00100000"-通常のラウンドロビン,#3その#4のあとに行う必要があ#2もあるんですが、その要求、#5が出来ます。
Example2:
- 電流:"01000000"
- マスク:"00001010"
- 次:"00000010"でケジューリングによるサイクリング、#1は最初の依頼スレーブの順になりました。
現在、このグループったんですね、わかります。でも実際に取得したい私の結果によるビットtwiddling操作なしタイルです。の意欲:を実装したいのはこのハードウェア(FPGA)にVHDL/Verilog.
ボーナスを利用しようとしているアルゴリズムの汎用量のスレーブN.
ちなみに、この宿題をする質問です。この重要な問題についてい程のスレーブの一部には、条件のケジューリングをスレーブ毎に実施致します。私の現在の解や"重い"ってほしいとの申し入れであったい何かが足りないはずである。
解決 2
私は、アルテラの高度な合成料理でタスクを実行するために、次のVerilogコードを発見しました。
// 'base' is a one hot signal indicating the first request
// that should be considered for a grant. Followed by higher
// indexed requests, then wrapping around.
//
module arbiter (
req, grant, base
);
parameter WIDTH = 16;
input [WIDTH-1:0] req;
output [WIDTH-1:0] grant;
input [WIDTH-1:0] base;
wire [2*WIDTH-1:0] double_req = {req,req};
wire [2*WIDTH-1:0] double_grant = double_req & ~(double_req-base);
assign grant = double_grant[WIDTH-1:0] | double_grant[2*WIDTH-1:WIDTH];
endmodule
これは(ただし、一度だけ)減算を使用するため、概念的には、ダグのソリューションと非常によく似ています。
他のヒント
ループは悪いことする必要はありません。
私は単純にするだろう。
current[i] = current[i-1] & mask[i] | // normal shift logic
mask[i] & current[i-2] & !mask[i-1] | // here build logic
... // expression for
// remaining
そして表現のための並列ハードウェアを生産する生成ループ(すなわち、それはハードウェアに巻き戻されます)、にそれを置きます。
「 - 」その他ここに記載の解決策は、複数を使用しています。これはあなたに本当に高価な操作を取得するように私は、それを阻止することができます。 ESPの。ボローが(特定のFPGA上deadicatedキャリーロジックは、ビット数が少ないため、それは親しみ作る)すべてのビットを通過する必要があるように、1つのホットであなたは、簡単にHWで実装可能ではないだろう> 32ビット、より簡単に、より取得することができます。
以下のソリューション作品のための任意の数のスレーブ(K)、O(n)にコンフィギュレーションします。各ビットの分野で、必要な三つの論理ゲートのやつ打つ必要があります。私は試験の概念と基本的な論理シミュレータです。
チェーンのロジックゲートとの間 現在の や マスク 質を最優先システムの恩恵をビット"低下"にします。このチェーンはループを終了すが、 現在の ビットは分割するのに使用します。
を可視化するための運用を想像するビット 3 設定さ 現在の 分野の信号下の図に示します。論理でビット 3 場所を論理的にゼロを入力の最初のゲートすることを保証出力によるゲートもゼロ(ここではゲートチェーンが破損).ゼロは、出力の最初のゲートの場所は、一つの入力をゲートがあります。このビット 2 の 次へ 直接的に依存ビット 2 の マスク.
現在、チェーンまたはゲートが登場します。
場合はビット 2 の マスク 設定した、論理出力、またはゲートを直接左のできる場所を論理的に一つの入力をゲート以下のビット 2 の 現在の (ゼロから一つだけビット 現在の 設定可能です。論理の出力にトップゲートの場所を論理的にゼロを入力の下、ゲートが設定ビット 1 の 次へ ゼロに等しくなります。
場合はビット 2 の マスク ませんでしたセット、入力、またはゲートがゼロとなるので、出力のゲストビット 2 の 現在の このゼロを持たせることが一つの入力の下、ゲートが作りビット 1 の 次へ 依存性のトライボロジー 1 の マスク.
この論理のチェーンまたはゲート"のビット、ループを周りから左サイドバックの権利を確保し、一つだけビット 次へ 設定することができます。ループを停止しまし帰りのビット 3 の 現在の, 結果としてのビットがセットです。この回路からの滞在型永久ループを実行します。
私の経験がなくVerilogやVHDLでてしまい、実際のコードま のstackoverflow.
altテキストhttp://img145.imageshack.us/img145/5125/bitshifterlogicdiagramkn7.jpg
注記:
- このソリューションが部分的にとどまる。でも行うことが求めのラッチ機構、ビット。
- 意として数を増やすのビットを、必要な時間は、ゲート電圧の解決にも増加しました。
- がついては一部の論理を扱う場合には 現在の 分野はゼロに等しくなります。見 このstackoverflowの質問.
興味深い問題!私は助けるが、あなたのスケジューラの操作を簡略化することができない場合ので、操作のこの種が必要となるだろうことはできません。
あなたはVHDLを知っていることを考えると、私は詳細には触れませんが、私の提案は、次のようになります。
数に現在スケジュールされたタスクを有効にする3ビットエンコーダを使用します:
01000000 - > 6
続いてマスクを回転させるバレルシフタを使用すること数+ 1(現在のタスクをスキップする)。
00001010 - > 00010100
次に、最初に利用可能な「次の」タスクを見つけるために、プライオリティエンコーダを使用
00010100 - > 00000100 - > 2
次に添加によってバレルシフトをリバース:
(2 + 7)%8 = 1
と、次のスケジュールされたタスクを与える再エンコードどちらます:
00000010
バレルシフタがrealestateの用語で「高価」ですが、非常に高速かつ簡単ですが、私は、現時点ではその周りを取得するための簡単な方法が表示されません。
編集:ダグのソリューションは、はるかに洗練されて...
-Adam
Subracting 1は、ここでは必要不可欠なアイデアです。これは、カスケード接続に使われて次のタスクを見つけるために、ビットを通じて借りています。
bits_before_current = ~(current-1) & ~current
bits_after_current = current-1
todo = (mask & bits_before_current)
if todo==0: todo = (mask & bits_after_current) // second part is if we have to wrap around
next = last_bit_of_todo = todo & -todo
これは、内部でループを使用しますけれども...
2の補数表現を補完すると仮定すると、あなたの二つの単語を呼ぶmask
とcurrent
、Cでます:
mask_lo = (current << 1) - 1; // the bits to the right and including current
mask_hi = ~mask_lo; // the bits to the left of current
// the left bits, otherwise right:
next = (mask & mask_hi) ? (mask & mask_hi) : (mask & mask_lo);
return (next & -next); // the least significant bit set
これは、あなたが欲しいものを行う必要があります:
number_of_tasks= <number of tasks, in the example this is 8>
next_mask= current | (current - 1);
next_barrel= next | (next << number_of_tasks);
next_barrel&= ~number_of_tasks;
next_barrel&= -next_barrel;
next_barrel|= next_barrel >> number_of_tasks;
next_task_mask= next_barrel & -next_barrel;
基本的に、私たちはその後、最下位ビットのセットを取り、後ろに高ビットを折る、最下位セットビットを見つける、検討する必要はありませんビットをマスクオフ、次のタスクマスクのビットを複製します。これは、一定の時間で実行されます。
編集:アカウントに現在== 00010000とnext_maskの== 00111000を取るために更新
テストされていないが、これはミリアンペア合理的な合成を生成しなかった場合、私の頭の上から、私は驚かれることでしょう...典型的なビットいじるハックとは違って(とにかく私には)比較的読みやすいという利点があります。
for i in current'range loop
current := rotate_left(current, 1);
if or_reduce(mask and current) = '1' then
current:= mask and current;
end if;
end loop;
ラウンドロビン又は優先調停するように構成することができる完全なパラメータ化アービタ実装
https://github.com/alexforencich/verilog-軸/ブロブ/マスター/ RTL / arbiter.vする
このデザインは、シーケンス内の次の出力を選択するプライオリティエンコーダのペアを使用します。使用されるプライオリティエンコーダは、ツリーとして効率的に実装されています。