Verilog: how to take the absolute value

假如想象 提交于 2020-01-04 21:39:01

问题


In verilog I have an array of binary values. How do I take the absolute value of the subtracted values ?

Verilog code:

module aaa(clk);
  input clk;

  reg [7:0] a [1:9];  
  reg [7:0] s [1:9];

  always@(posedge clk)  
  begin
    s[1] = a[1] - a[2];
    s[2] = a[2] - a[3];
    s[3] = a[1] + a[3];
  end
endmodule

I want my s[1] and s[2] values to be always positive. How can I do it in synthesisable verilog?

I have tried using signed reg, but it shows an error.


回答1:


Regardless of whether the number is signed or not twos complement is still used which correctly performs addition and subtraction at the bit level.

If a number is to be interpreted as signed the MSB can be used to tell if it is positive (0) or negative (1)

To absolute the number just invert based on the MSB:

reg [31:0] ans    ; // Something else drives this value
reg [31:0] abs_ans; // Absolute version of ans
// invert (absolute value)
always @* begin
  if (ans[31] == 1'b1) begin
    abs_ans = -ans;
  end
  else begin
    abs_ans = ans;
  end
end

NB: using = because it is a combinatorial block, if using a flip-flop (edge trigger) use <= as @TzachiNoy has mentioned.




回答2:


This should do the work:

s[1] <= (a[1]>a[2])?(a[1]-a[2]):(a[2]-a[1]);

Note: you should always use '<=' in clocked always blocks.




回答3:


Just following the answer from @Morgan, and because I already had a module in my system that performed this operation, here is my contribution:

module Mod(
  input  signed [11:0] i,
  output signed [11:0] o
  );

  assign o = i[11] ? -i : i; // This does all the magic
endmodule

And here is a testbench:

module tb;
  reg signed [11:0] i;
  wire signed [11:0] o;

  Mod M(i,o);

  integer t;

  initial begin
    for (t = -10; t < 10; t = t + 1) begin
      #1
      i <= t;
      $display("i = %d, o = %d", i, o);
    end
  end
endmodule

The output is:

i =     x, o =     x
i =   -10, o =    10
i =    -9, o =     9
i =    -8, o =     8
i =    -7, o =     7
i =    -6, o =     6
i =    -5, o =     5
i =    -4, o =     4
i =    -3, o =     3
i =    -2, o =     2
i =    -1, o =     1
i =     0, o =     0
i =     1, o =     1
i =     2, o =     2
i =     3, o =     3
i =     4, o =     4
i =     5, o =     5
i =     6, o =     6
i =     7, o =     7
i =     8, o =     8


来源:https://stackoverflow.com/questions/19423792/verilog-how-to-take-the-absolute-value

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!