本文介绍了在 Verilog 上实现互惠的方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想在 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 上实现互惠的方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-22 18:50
查看更多