问题描述
我想在 Verilog 上实现一个交互模块,稍后将在 FPGA 上进行综合.输入应该是带符号的 32 位字长和 16 位小数长度.输出应具有相同的格式.
I want to implement a reciprical block on Verilog that will later be synthesized on an FPGA. The input should be a signed 32 bit wordlength with a 16 bit fraction length. The output should have the same format.
示例
输入:x ---> 输出 ---> 1/x
我已经使用内置的 IP 核分频器解决了这个问题.我想知道是否有一种优雅/替代的方法来解决这个问题,例如通过位移或 2 的补码和一些异或研磨.
I have solved the problem using the inbuilt IP core divider. I'm wondering if there is an elegant/altenative way of solving this by for example by bit shifting or 2's complement with some xor grinds.
我已经使用 IP 核来实现手册中所说的逆,但由于某种原因,我并不真正理解结果是错误的,需要向左移动 1.例如;1 的倒数给出 0.5 .2 的倒数给出 1.
I have used the IP core to implement the inverse as it says in the manual but for some reason that i don't really understand the result is wrong and it needs to be shifted to the left by 1. For example; Reciprical of 1 gives 0.5 . Reciprical of 2 gives 1.
以下是手册和我的测试平台代码的部分
Below is a section from the manual and my testbench code
module reciprical_tb;
// Inputs
reg clk;
reg [1:0] dividend;
reg [31:0] divisor;
// Outputs
wire rfd;
wire [1:0] quotient;
wire [31:0] fractional;
// Instantiate the Unit Under Test (UUT)
reciprical uut (
.rfd(rfd),
.clk(clk),
.dividend(dividend),
.quotient(quotient),
.divisor(divisor),
.fractional(fractional)
);
// clock
always begin
#5 clk = ~clk;
end
initial begin
// Initialize Inputs
clk = 0;
dividend = 2'b1; // 1
divisor = 2**16;; // = 1 when fraction length is 16bit
// Wait 100 ns for global reset to finish
#100;
// Add stimulus here :: Inverse of 2 should give 0.5
//$display("inv(%g) => %g || inv = %b",$itor(divisor)*2.0**-16, $itor(fractional)*2.0**-16, fractional); //gives zero
$monitor("inv(%d) => q = %d || inv = %b", divisor>>>16,fractional>>>16, fractional); //gives a wrong answer by a factor of 2
// Using the monitor i get inv(1) = 0.5 instead of 1.
#100;
end
endmodule
手册部分(第 4 页):
Manual section (page 4):
...除法器可用于实现 X 的倒数;这就是 1/X 函数.要做到这一点,被除数位宽设置为 2 并选择小数模式.然后将股息输入绑定到 01无符号或有符号操作,X 值通过除数输入提供.
使用的IP核
推荐答案
尝试调试部分问题:
你可以试试吗:
// Wait 10 clock cycles
repeat (10) begin
@(posedge clk);
end
// Add stimulus here :: Inverse of 2 should give 0.5
$display("dsiplay inv(%g) => %g || inv = %b",$itor(divisor)*2.0**-16, $itor(fractional)*2.0**-16, fractional); //gives zero
$monitor("inv(%d) => q = %d || inv = %b", divisor>>>16,fractional>>>16, fractional); //gives a wrong answer by a factor of 2
// Using the monitor i get inv(1) = 0.5 instead of 1.
// Wait 10 clock cycles
repeat (10) begin
@(posedge clk);
end
$display("dsiplay inv(%g) => %g || inv = %b",$itor(divisor)*2.0**-16, $itor(fractional)*2.0**-16, fractional);
//End simulation
$finish();
由于监视器只发出一次,它可能在 200 纳秒后才真正触发并输出更新的值.
As monitor is only issued once, it might be after 200ns that it is actually firing and outputting the updated value.
这篇关于在 Verilog 上实现互惠的方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!