系统Verilog减法执行

问题描述 投票:0回答:1

我正在设计一个带有 8 位数据路径的 RISC 处理器。

在我的减法运算 ALU 中,我有以下代码:

logic[7:0] inA, inB, rslt;
logic c_o;

{c_o, rslt} = inA - inB;

在 modelsim 中进行模拟时,如果我有 A = 0000_1111,B = 1110_0001 并执行 A-B 我得到 rslt = 0010_1110,c_o = 1;

如果将 A-B 做为 (A + (~B + 1)),我会认为 c_o 会为零。

  0000_1111
  0001_1111 +
= 0010_1110   

我看来我的 c_o 或进位值是通过二进制补码加法进行减法得到的反转进位。或者换句话说,我的 c_o 实际上是借用的,表明需要借用来进行减法。

我查看了 IEEE Standard for SystemVerilog,但找不到任何有关从无符号减法中借用的信息。

有谁知道为什么会出现倒转执行?我认为有符号和无符号减法会得到相同的结果。有某种类型的

我知道借用对于将减法链接在一起很有用,我将要实现它。

即使我签署了 rslt、inA、inB,我仍然会得到反转执行。

module sub(
  input logic [7:0] inA,
  input logic [7:0] inB,
  output logic[7:0] rslt, rslt2,
  output logic c_o,
  output logic c_o2
);
    
logic [7:0] b_invert;

assign b_invert = (~inB);    

always_comb begin
    {c_o,rslt} = inA - inB;
    {c_o2, rslt2} = inA + b_invert + 1;
end

endmodule


`timescale 1ns/1ns
module subtest;
    
logic [7:0] a;
logic [7:0] b;
logic [7:0] rslt ,rslt2;
logic carry_out, carry_out2;
    
sub uut (
    .inA(a),
    .inB(b),
    .rslt,
    .rslt2,
    .c_o(carry_out),
    .c_o2(carry_out2)
);
    
initial begin

a = 'b00001111;
b = 'b11100001;
#5ns;
$display("a = %b, b = %b, operation a-b", a, b);
$display("a - b carry out is: %b", carry_out);
$display("a + (~ b + 1) carry out is %b", carry_out2);
$display("RESULT IS %b", rslt);

#5ns;

a = 'b11100001;
b = 'b00001111;
#5ns;
$display("a = %b, b = %b, operation a-b", a, b);
$display("a - b carry out is: %b", carry_out);
$display("a + (~ b + 1) carry out is %b", carry_out2);
$display("RESULT IS %b", rslt);
#5ns;

$stop;
end
endmodule
verilog system-verilog subtraction twos-complement alu
1个回答
0
投票

当您对两个 N 位事物进行加法或减法时,请分配 N + 1 位。您可以预先分配位,然后以两种不同的方式执行操作,并获得进位/借位的相同答案。像这样:

module tb;
  localparam WIDTH = 8;
  
  initial begin
    
    logic [WIDTH - 1     :0] a;
    logic [WIDTH - 1     :0] b;  
    logic [WIDTH - 1 + 1 :0] result_twos;
    logic [WIDTH - 1 + 1 :0] result;    
    a = 'b00001111;
    b = 'b11100001;
    result = a - b;
    result_twos = a + (~b) + 1;
    $display("result = %b, result_twos = %b",result,result_twos);
    $display("c_out twos = %d, c_out = %d\n",result[8], result_twos[8]);
  end
  
endmodule

产生

xcelium> run
result = 100101110, result_twos = 100101110
c_out twos = 1, c_out = 1

对于预分配的位,两种方式的工作方式相同,所以现在的问题是“为什么串联在这种情况下表现不同”。这与 Verilog 评估串联中位数的方式有关;它也可能是连接与上下文确定的运算符一起使用的方式,您已经证明它在您提供的两种情况下表现不同。

© www.soinside.com 2019 - 2024. All rights reserved.