如何在SystemVerilog中签名扩展?

时间:2016-03-03 05:07:07

标签: system-verilog

以下是我的模块代码:

module sext(input in[3:0], output out[7:0]);

    always_comb
        begin
            if(in[3]==1'b0)
                assign out = {4'b0000,in};
            else
                assign out = {4'b1111,in};
        end

endmodule

由于某种原因,这不起作用。而不是符号扩展它是零扩展。为什么会出现这种情况的任何想法?

4 个答案:

答案 0 :(得分:4)

我会假设你的意思是(input [3:0] in, output [7:0] out)。如果这是真的,那么你需要写的就是

module sext(input signed [3:0] in, output signed [7:0] out);

    assign out = in;

endmodule

你也可以写

module sext(input [3:0] in, output [7:0] out);

    assign out = 8'(signed'(in));

endmodule

也许你甚至不需要把它写成一个单独的模块。

答案 1 :(得分:2)

您需要注意的事项很少,

  1. 您尚未声明inout的数据类型,因此默认情况下,wirewire不能用于LHS在程序块内。请参阅第6.5 Nets and variables (SV LRM 1800-2012)节。因此要么使用连续赋值,要么将其声明为变量(即reg / logic等)。

  2. unpacked array的分配在您的示例中是非法的,因此请使用packed array或按照10.10 Unpacked array concatenation (SV LRM 1800-2012)

  3. 部分中的说明进行操作

答案 2 :(得分:1)

这不是非法语法,但在always块中使用的assign可能不会按照您的想法执行。使用分配电线,不要在初始或始终使用它。

您已在名称后定义了端口范围,这会产生4和8个1位数组,而不是4位和8位数值。

您已使用{}进行连接,但它们也可用于复制,即{4{1'b1}}

module sext(
  input      [3;0] in, 
  output reg [7:0] out ); //ranged defined before name

  //No assign in always
  //concatenation with replication
  always_comb begin
    out = { {4{in[3]}}, in}; 
  end

endmodule

或者:

module sext(
  input      [3;0] in, 
  output     [7:0] out ); //out left as wire

  assign out = { {4{in[3]}}, in}; 
endmodule

答案 3 :(得分:0)

我见过你的代码。 你的代码中有一些错误,你必须小心编写代码。

  1. 您使用了解压缩数组,因此您的目标元素和实际元素不匹配。 错误:目标表达式中的元素数与数量不匹配 源表达式中的元素。
  2. 使用压缩数组可以解决此错误。因此,您的目标元素和实际元素是匹配的。 这里是您可以更好地了解打包和解包数组的链接。 链接:[http://www.testbench.in/SV_09_ARRAYS.html][1]

    2.另外你需要注意的是你在输出信号(变量)中存储一些值,如assign out = {4'b0000,in};  因此,您必须使用reg数据类型来处理该值。 错误:非分配类型在此分配的左侧无效 当您使用reg数据类型时,您可以将值存储在out数据类型中。

    所以,你的问题已经解决了。

    在这里,我还提供了运行良好的代码。

        module sext(input [3:0]in, output reg [7:0]out);
    
        always_comb
            begin
                if(in[3]==1'b0)
                    assign out = {4'b0000,in};
                else
                    assign out = {4'b1111,in};
            end
    
        endmodule