我正在尝试像这样实现一段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实现是最快的吗?或者还有其他更好的解决方案来改善时机吗?感谢
答案 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);