2

4 つの 16:4 マルチプレクサを実装するために、次のコードを作成しました。

module coder(
    selCh0, selCh1, selCh2, selCh3, 
    outCh0, outCh1, outCh2, outCh3,
    inEnc0, inEnc1, inEnc2, inEnc3
);
    input  wire [1:0] selCh0, selCh1, selCh2, selCh3;
    output wire [3:0] outCh0, outCh1, outCh2, outCh3;
    input  wire [3:0] inEnc0, inEnc1, inEnc2, inEnc3;

    mux_16x4 ch0(selCh0, inEnc0, inEnc1, inEnc2, inEnc3, outCh0);
    mux_16x4 ch1(selCh1, inEnc0, inEnc1, inEnc2, inEnc3, outCh1);
    mux_16x4 ch2(selCh2, inEnc0, inEnc1, inEnc2, inEnc3, outCh2);
    mux_16x4 ch3(selCh3, inEnc0, inEnc1, inEnc2, inEnc3, outCh3);
endmodule

module mux_16x4(sel, enc0, enc1, enc2, enc3, out);
    input wire [1:0] sel;
    input wire [3:0] enc0, enc1, enc2, enc3;
    output reg [3:0] out;

    always @(sel, enc0, enc1, enc2, enc3)
    begin
        case ({sel})
            2'b00: out <= enc0;
            2'b01: out <= enc1;
            2'b10: out <= enc2;
            2'b11: out <= enc3;
            default: out <= 4'b0;
        endcase;
    end
endmodule

私の質問は 2 つあります。

  1. これを行うためのより効率的および/またはより良い方法はありますか? 勉強中なので書いたコードに特に問題はありませんが、改善できないかチェックしてみようと思いました。
  2. 各 4:1 マルチプレクサの 4 番目のビットを逆にする必要があります。現在、各 inEncN バスのすべてのビットが入力であり、各 outChY バスのすべてのビットが出力です。最初はこのように書いて動作するかどうかを確認しましたが、実際のハードウェアには逆方向に進むための信号が必要です。

より簡潔にするために、特定のシグナルのセットで説明します。現在、outCh0[3:0] のビットはすべて出力です。outCh0[3] を入力として、選択信号によって選択された inEncN[3] バスにマップする必要があります。したがって、すべての inEncN[3] 信号を、それぞれのバスの他の 3 ビットのような入力ではなく出力にする必要があります。

orinoutの代わりに問題のすべてのバスを作成しようとしましたが、何を試してもコンパイルできませんでした。inputoutput

上記のコードは 32 個のロジック エレメントにコンパイルされ、8 個のスペアが残ります。コードを 40 個以下のロジック要素に収めることは大きなメリットですが、許容できるプラン B があります。

どんな助けでも大歓迎です。

4

1 に答える 1

1

ここでは双方向信号は必要ありません。ポートを少し再定義する必要があるだけです。システム Verilog を使用すると、このコードをもう少しコンパクトにするポートとして多次元配列を渡すことができます。1 つのオブジェクトに 3 つの入力と 1 つの出力を含む構造体を作成することもできます。ただし、これは Verilog の質問なので、次のようにします。

module coder(
  selCh0, selCh1, selCh2, selCh3, 
  outCh0, outCh1, outCh2, outCh3,
  inCh0, inCh1, inCh2, inCh3,
  inEnc0, inEnc1, inEnc2, inEnc3,
  outEnc0, outEnc1, outEnc2, outEnc3      
);
  input  [1:0] selCh0, selCh1, selCh2, selCh3;

  input  [2:0] inEnc0, inEnc1, inEnc2, inEnc3;
  output       outEnc0, outEnc1, outEnc2, outEnc3;

  output [2:0] outCh0, outCh1, outCh2, outCh3;
  input        inCh0, inCh1, inCh2, inCh3;

  wire [2:0] inEnc [0:3];
  wire       inCh [0:3];

  assign inEnc[0] = inEnc0;
  assign inEnc[1] = inEnc1;
  assign inEnc[2] = inEnc2;
  assign inEnc[3] = inEnc3;

  assign inCh[0] = inCh0;
  assign inCh[1] = inCh1;
  assign inCh[2] = inCh2;
  assign inCh[3] = inCh3;

  assign outCh0 = inEnc[selCh0];
  assign outCh1 = inEnc[selCh1];
  assign outCh2 = inEnc[selCh2];
  assign outCh3 = inEnc[selCh3];

  assign outEnc0 = inCh[selCh0];
  assign outEnc1 = inCh[selCh1];
  assign outEnc2 = inCh[selCh2];
  assign outEnc3 = inCh[selCh3];

endmodule

これは、システム Verilog のポートとして配列を使用して繰り返されます。これは、チャネル数の柔軟性のためにパラメーター化されています。チャネル数は 2 の累乗ではない可能性があるため、selCh が有効な値であることを確認する必要があります。そうでない場合は、デフォルト値を出力に割り当てます。この関数は、入力$clog2から選択するために必要な最小ビット数を計算するために使用されます。NUMCH

module coder #(parameter NUMCH=4) (
  input [$clog2(NUMCH)-1:0] selCh[NUMCH],

  input      [2:0] inEnc[NUMCH],
  output reg       outEnc[NUMCH],

  output reg [2:0] outCh[NUMCH],
  input            inCh[NUMCH]
  );

  always_comb begin
    for (int i=0; i<NUMCH; i++) begin
      if(selCh[i]<NUMCH) begin
        outCh[i] = inEnc[selCh[i]];
        outEnc[i] = inCh[selCh[i]];
      end
      else begin
        outCh[i] = '0;
        outEnc[i] = '0;
      end
    end
  end
endmodule
于 2013-11-30T14:33:49.343 に答える