2013-11-09 38 views
4

我想創建一個模塊,根據一個熱輸入將x個輸入數據包切換爲單個輸出數據包。如何使用SystemVerilog定義參數化多路複用器

如果x是4個固定值,我只想創造一個case語句,

case (onehot) 
    4'b0001 : o_data = i_data[0]; 
    4'b0010 : o_data = i_data[1]; 
    4'b0100 : o_data = i_data[2]; 
    4'b1000 : o_data = i_data[3]; 
    default : o_data = 'z; 
endcase 

但隨着變量x,我如何定義所有的案件?

謝謝。

回答

10
parameter X = 4; 

input [X-1:0] onehot; 
input i_data [X]; 
output reg o_data; 

always_comb begin 
o_data = 'z; 
for(int i = 0; i < X; i++) begin 
    if(onehot == (1 << i)) 
    o_data = i_data[i]; 
end 
+0

是的,我確實表示謝謝,我將編輯q。雖然 爲什麼行'o_data ='z'不與'o_data = i_data [i];'相沖突並且是if(oneshot ==(1 << i))'if' oneshot [i] == 1)'? – user2646276

+2

for循環之前的賦值就像默認值一樣。最後的任務應該贏。這兩個比較是不相同的,因爲'oneshot [i] == 1'僅基於那一個比特匹配。如果多位高,那麼你會得到多個匹配。 – nguthrie

+1

例如,如果'oneshot == 4'b1001'然後'oneshot [0] == 1'將成立,但'oneshot ==(1 << 0)'將是錯誤的。 – nguthrie

7

如果可以斷言,onehot確實是一個熱或0,那麼你可以使用一個生成

package mytypes; 
typedef logic [7:0] packet_t; 
endpackage 

module mux #(int X) (
     input logic [X-1:0] onehot, 
     input mytypes::packet_t i_data[X], 
     output wire mytypes::packet_t o_data 
    ); 
for(genvar i=0;i<X;i++) begin 
    assign o_data = onehot[i] ? i_data[i] : 'z; 
end 
endmodule 
+1

+1爲Verilog綜合答案。 – stanri

+0

我以前使用Xilinx工具使用過這種技術,但現在我使用Altera,我得到一個警告,說明內部三態緩衝區是不允許的。我可能會對原理圖進行檢查,看看它是如何實現的,但是如果沒有機會,你知道這種技術是否仍然可以與Altera工具一起使用? – stanri

1

下面是一個熱輸入而優化的完全參數化合成的複用(即無優先級編碼)使用OR樹。請注意,如果未啓用任何輸入,則將輸出驅動爲0而不是'z':

module mux 
#(parameter int unsigned inputs = 4, 
    parameter int unsigned width = 8) 
    (output logic [width-1:0] out, 
    input logic sel[inputs], 
    input logic [width-1:0] in[inputs]); 

    always_comb 
    begin 
     out = {width{1'b0}}; 
     for (int unsigned index = 0; index < inputs; index++) 
     begin 
      out |= {width{sel[index]}} & in[index]; 
     end 
    end 
endmodule 
相關問題