2016-09-15 538 views
0

考慮以下我想要參數化的函數。我創建了一些參數來設置輸出的寬度和相應的寬度參數。參數化verilog中的casex語句

parameter SELECT_WIDTH = 6; 
parameter PRIENC_WIDTH = $clog2(SELECT_WIDTH+1); 


function [PRIENC_WIDTH-1:0] prienc6; 
input [SELECT_WIDTH-1:0] select; 
reg [PRIENC_WIDTH-1:0] out; 
begin 
    casex(select) 
    6'b000001: out = 3'b101; // Is it possible to parameterize the case statement with generate 
    6'b00001x: out = 3'b100; 
    6'b0001xx: out = 3'b011; 
    6'b001xxx: out = 3'b010; 
    6'b01xxxx: out = 3'b001; 
    6'b1xxxxx: out = 3'b000; 
    endcase 
    prienc6 = out ; 
end 
end function 

很明顯,casex聲明的情況下不會像書面擴展。
所以我嘗試了以下,它沒有正確編譯,指出發現意外的生成。

function [PRIENC_WIDTH-1:0] prienc_n; 
input [SELECT_WIDTH-1:0] select; 
reg [PRIENC_WIDTH-1:0] out; 
begin 
    genvar gv_j; 
    casex(select) 
     for (gv_j = 0; gv_j < SELECT_WIDTH; gv_j = gv_j + 1) 
     begin 
      {{(SELECT_WIDTH-1)-gv_j{1'b0}},1'b1,{gv_j{1'bx}}} : out = (SELECT_WIDTH-1)-gv_j; 
     end 
    endcase 
    prienc_n = out ; 
end 
end function 

我已經能夠使用參數化if得到正確的行爲,但它似乎我應該能夠參數化該casex語句。有關如何做到這一點的任何想法?我想接下來要嘗試的是將casex包裝在生成循環中,並創建6個casex語句,每個語句只有一個狀態。

+1

我推薦使用'casez'而不是'casex',因爲如果在第一個例子中'select'由於某種原因變成了所有的X,那麼它會匹配任何分支,因爲'1'bX'意味着'不在乎'在'casex'中。如果你使用'casez',那麼'select'就不得不成爲所有Z才能發生的事情,這是不太可能發生的。如果您使用的是System-Verilog,請不要使用;改用'case ... inside'。 –

回答

1

既然你標記SystemVerilog的這個問題,我會告訴你如何做到這一點沒有case陳述或generate

function logic [PRIENC_WIDTH-1:0] prienc_n(
input [SELECT_WIDTH-1:0] select); 
for (int j = 0; j < SELECT_WIDTH; j++) begin 
    if (select[SELECT_WIDTH-1]) return j; 
    select <<=1; 
end 
// if no 1 found 
return ('x); // you did not specify this case 
endfunction 

如果你需要留在Verilog的,它需要一箇中間變量

function reg [PRIENC_WIDTH-1:0] prienc_n(
    input [SELECT_WIDTH-1:0] select); 
    reg [PRIENC_WIDTH-1:0] out; 
    integer j; 
    begin 
     out = {PRIENC_WIDTH{1'bx}}; // what should be returned if no 1 found 
     for (j = 0; j < SELECT_WIDTH; j = j + 1) begin 
     if (select[SELECT_WIDTH-1]) begin 
             out = j; 
             select = 0; 
            end 
     select = select << 1; 
    end 
    prienc_n = out; 
    end 
    endfunction 
+0

爲'if'條件,我們可以只做'if(select [SELECT_WIDTH - 1 - j)return j;'''不必改變'select'的值。對於第二個函數,當'select'中有多個'1'時,它看起來不正確。 –

+0

對於SystemVerilog版本,您的建議有效。但展開合成後,我認爲它們是相同的。我修復了第二個功能。 –