如何在数字有效的情况下对数字进行零扩展,或者对其进行X扩展?

问题描述:

我有一个16位数可能是x(即未知)。
我想零扩大到32位,但如果MSB是x,那么我希望它是x - 扩展而不是零扩展。 (这有助于我的模拟。)如何在数字有效的情况下对数字进行零扩展,或者对其进行X扩展?

我该怎么做?

除非您使用带符号的值,否则我认为您需要一个自定义函数。如果您使用带符号的值,则如果符号位为X,则MSB将在从16位值到32位值的分配上进行X扩展。但是,如果MSB(符号位)为1,则它将被1扩展,如果你使用无符号值,这很可能不是你想要的。

这是一个简单的功能来做到这一点。

function [31:0] extend(input[15:0] in); 
begin 
    if (in[15] === 1'bX) begin 
     extend = {16'hXXXX, in}; 
    end else begin 
     extend = {16'h0000, in}; 
    end 
end 
endfunction 

例子:

$display("%032b", extend(16'h0000)); 
$display("%032b", extend(16'hFFFF)); 
$display("%032b", extend(16'bX000_0000_0000_0000)); 

输出:

00000000000000000000000000000000 
00000000000000001111111111111111 
xxxxxxxxxxxxxxxxx000000000000000 
+0

您也可避免的if/else只要说'extend = {{16 {in [15}},in};'避免不必要的控制流程语句,我认为它几乎总是在Verilog中获胜,因为它更接近你实际构建的模型。 – 2013-03-19 13:07:08

+1

@BrianMagnuson这是一个很好的建议,但我认为即使第15位是1,OP也希望零扩展。在这种情况下,您拥有的扩展名是1。 – dwikle 2013-03-19 15:02:16

+1

啊,你说得对。我想你可以进行连接的第一部分{16 {in [15]&1'b1}}。虽然这开始有点混乱。 – 2013-03-19 18:21:43

如果你的模拟器是足够现代的支持的SystemVerilog语法:

module tb; 

reg [15:0] a; 
reg [31:0] b; 

initial begin 
    $monitor("a='b%b b='b%b", a, b); 
    #5 a= '1; extendo(); 
    #5 a= '0; extendo(); 
    #5 a= 'z; extendo(); 
end 

task extendo; 
    b[15:0] = a[15:0]; 
    b[31:16] = (a[15] === 1'bx) ? 'x : '0; 
endtask 

endmodule 

/* 
Output: 

a='bxxxxxxxxxxxxxxxx b='bxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx 
a='b1111111111111111 b='b00000000000000001111111111111111 
a='b0000000000000000 b='b00000000000000000000000000000000 
a='bzzzzzzzzzzzzzzzz b='b0000000000000000zzzzzzzzzzzzzzzz 
*/