私は検証に取り組んでいます。私は現在、2xクロックでユニットに送られるデータを変換するという問題に直面しています。
132ビットの信号の場合、2xクロックで66ビットバスとして移動します。
再度受信すると、すべてのクロック変換が2xから1xに実行され、信号の132ビットすべてが返されます。
誰かがこれを行う方法について私を助けることができますか?
よろしくお願いします。
私は検証に取り組んでいます。私は現在、2xクロックでユニットに送られるデータを変換するという問題に直面しています。
132ビットの信号の場合、2xクロックで66ビットバスとして移動します。
再度受信すると、すべてのクロック変換が2xから1xに実行され、信号の132ビットすべてが返されます。
誰かがこれを行う方法について私を助けることができますか?
よろしくお願いします。
これは、クロック ドメインクロッシングテクニックに関する優れた論文です。
質問にタグが付けられているので、変換を行うための Verilog モジュールが必要であると思いますverilog
。system-verilog
入力クロックと出力クロックが同期していると仮定すると、コードは次のようになります (十分にテストされていないため、微調整が必要な場合があります)。
module conv_2x_to_1x (rst, clk_in, data_in, clk_out, data_out);
parameter IN_WIDTH = 66;
input wire rst, clk_in, clk_out;
input wire [IN_WIDTH-1:0] data_in;
output reg [2*IN_WIDTH-1:0] data_out;
localparam LOWER_HALF = 0, UPPER_HALF = 1;
reg [2*IN_WIDTH-1:0] data_tmp;
reg half;
always @(posedge clk_in or posedge rst)
if (rst) begin
data_tmp <= {2*IN_WIDTH {1'b0}};
half <= LOWER_HALF;
end else if (half == LOWER_HALF) begin
data_tmp [IN_WIDTH-1:0] <= data_in;
half <= UPPER_HALF;
end else begin
data_tmp [2*IN_WIDTH-1:IN_WIDTH] <= data_in;
half <= LOWER_HALF;
end
always @(posedge clk_out or posedge rst)
data_out <= rst ? {2*IN_WIDTH {1'b0}} : data_tmp;
endmodule
私はこの刺激でこれをテストしました:
module test;
reg rst;
reg [1:0] clk;
reg [65:0] data_in;
wire [131:0] data_out;
conv_2x_to_1x conv_2x_to_1x (rst, clk[0], data_in, clk[1], data_out);
always #5 clk = clk + 2'b01;
initial begin
$monitor ("%3t: %1b, %2b, %66h, %66h %66h", $time, rst, clk, data_in,
data_out [131:66], data_out [65:0]);
clk = 2'b00;
#2 rst = 1'b1;
@ (negedge clk [0]) #2 begin
rst = 1'b0;
data_in = 66'h2d_eadbe_efcaf_ebabe;
end
@ (negedge clk [0]) #2 data_in = 66'h1b_adc0f_fedea_dc0de;
@ (negedge clk [0]) #2 data_in = 66'h3c_afeba_bedea_dbeef;
@ (negedge clk [0]) #2 data_in = 66'h0d_eadc0_debad_c0ffe;
#12 $finish;
end
endmodule
入力クロックと出力クロックが同期していない場合は、入力クロック ドメインでフラグ信号をトグルする必要があると思います。これは、出力クロック ドメインに二重同期され、出力ロジックに渡される必要があります。出力側のロジックがトグルを検出すると、別のフラグ信号を読み取ることができ、data_out
設定する必要があります。このフラグ信号は、ダブル同期して入力側のロジックに渡す必要があります。入力ロジックがこの 2 番目のフラグのトグルを確認するまで、変更すべきではないと思いますdata_in
。
通常の方法は、132 ビットのデュアル ポート レジスタを使用することです。1x クロック ドメインに 1 つのポートを使用し、2x クロック ドメインにもう 1 つのポートを使用します。1つは読み取り専用、もう1つは書き込み専用なので、通常のレジスタと同じように記述できます。しかし、異なるクロック ドメイン間での移行は非常に厄介です。メタスタビリティのため。これを回避するには、別のレベルのフリップフロップ (つまり、別のレジスタ) を追加する必要があります。
私の答えはあまり具体的でも詳細でもありませんが、これはあなたの質問が非常に具体的でない/広範であるという事実によるものです。