我是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
答案 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