通过verilog实现带有签名号码的右移的最佳方法是什么?

时间:2018-03-07 22:31:31

标签: verilog hardware fpga

我正在尝试像这样实现一段C代码:

if (test_num>0)
    result = (test_num + offset) >> coeff;
else
    result = -((offset - test_num) >> coeff);

为了实现这一点,我确实设计了这个:

assign abs_result = test_num > signed(0) ? result : -result;

always @(*)
    case (coeff)
      4'd0: abs_result_tmp = abs_result;
      4'd1: abs_result_tmp = {1'b0, abs_result[7:1]};
      4'd2: abs_result_tmp = {2'b0, abs_result[7:2]};
      .....
      default: ...
    endcase

assign final_result = test_num > signed(0) ? abs_result_tmp : -abs_result_tmp;

因为我需要尽快完成这个功能,否则我将无法使用寄存器来实现此功能。只允许组合逻辑。我的这个C代码的verilog实现是最快的吗?或者还有其他更好的解决方案来改善时机吗?感谢

2 个答案:

答案 0 :(得分:0)

最简单的方法是将类型定义为已签名并使用>>>。

替代方法是重复MS位:(可能有拼写错误!)

@Html.CheckBoxFor(m => m.IsActive, new {  on="Active", off="Inactive" })

您希望-1>> 1变为零。你实际做的不是签名转移,而是转移然后舍入。在C -1>>中1也将是-1。 (因此你的标题有点误导。:-)这很好,因为有很多方法可以对数字进行舍入。但请注意,如果C代码和Verilog代码使用不同的方案,则会出现差异。 (查找银行家四舍五入)。

答案 1 :(得分:0)

经典verilog不支持已签名的数字,也不会为您进行签名比较。虽然负数自然由2-compliment cod表示,并且将uppper位设置为'1'。据说你的tes_num是32位,你总是可以测试test_num [31]的否定性。如果结果和偏移的大小相同,其余部分应该像'c'一样工作:

input  [31:0] test_num;
reg [31:0] result, offset;    
always @*
  if (test_num[31] == 0) //positive numbers
    result = (test_num + offset) >> coeff;
  else
    result = -((offset - test_num) >> coeff);