实现给定方程后输出错误

时间:2013-12-23 06:42:41

标签: verilog

我是Verilog的新手。在实现此功能时:

data_out = [ [data_in / ( |data_in| + 1 ) ] + 1 ] / 2

我没有得到正确的输出。有人能告诉我如何编写Verilog代码来实现这个功能吗?我正在发送我的代码和测试台。请纠正我错在哪里。

module act_fun(data_out,data_in);
  input  [22:0] data_in;
  output [22:0] data_out;
  reg    [22:0] data_out;
  reg    [22:0] mod;
  reg    [22:0] mod1;
  reg    [22:0] mod2;

  always @(data_in)
  begin 
    mod      = data_in + 23'b1;
    mod1     = data_in/mod;
    mod2     = mod1 + 23'b1;
    data_out = mod2>>1'b1;
  end

endmodule

测试平台

module act_tst;
  // Inputs
  reg [22:0] data_in;
  // Outputs
  wire [22:0] data_out;

  // Instantiate the Unit Under Test (UUT)
  act_fun uut (
    .data_out(data_out), 
    .data_in(data_in)
  );

  initial 
  begin
    data_in    = 23'b00000000000000000000000;
    #5 data_in = 23'b00000000000000000010000;
    #5 data_in = 23'b00000000000000001001100;
    #5 data_in = 23'b00000000000000111100010;
  end      
endmodule

输出:

data_out = 0000000000000000000000
5 data_out = 0000000000000000000000
5 data_out = 0000000000000000000000

1 个答案:

答案 0 :(得分:1)

如果您在波形窗口中查看此内容或打印有关内部mod变量的更多信息,您会注意到mod1永远不会更改,始终为0.

mod1     = data_in/mod;

我之前回答this question关于如何根据输入字长扩展乘法的输出。分部也是如此。

mod1永远不会达到1,即最大值是+ ve无穷大/(+ ve无穷大+ 1)。你正在执行整数除法,所以答案总是为0.

您需要确定所需的小数位数并填充分子。答案将是分数,你必须通过计算跟踪二进制点。

实施例

module act_fun(
  input      [22:0] data_in,
  output reg [22:0] data_out
);
  reg    [22:0] mod;
  reg    [22:0] mod1;
  reg    [22:0] mod2;

  always @(data_in) begin 
    mod      = data_in + 23'b1;
    mod1     = {data_in, 10'b0}/mod; //Adding 10 fractional bits
    mod2     = mod1 + 23'b1;
    data_out = mod2>>1'b1;
  end

endmodule

验证

为了验证您可能需要考虑使用实数评估方程(模型)并应用与您添加的小数位数相关的容差。

real data_in_r
real data_out_r 
always @* begin
  data_out_r = (( data_in / ( (data_in+1 ))+1 ) / 2 ;
end