请设计一个输入8bits数据的开根运算器,条件:(1)输入不连续,两个输入数据至少间隔5个时钟周期,(2)消耗资源尽可能少,(3)输出结果保留整数 部分并完成四舍五入; module sqrt8dat( input clk, input rst_n, input [7:0] din, input din_vld, output wire [3:0] dout, output wire dout_vld ); 请将代码补充完整
时间: 2023-06-16 12:03:21 浏览: 82
根据题目要求,可以使用牛顿迭代法实现开根运算。具体实现如下:
```
module sqrt8dat (
input clk,
input rst_n,
input [7:0] din,
input din_vld,
output wire [3:0] dout,
output wire dout_vld
);
reg [7:0] x;
reg [7:0] x_next;
reg [3:0] result;
reg [2:0] cnt;
reg [1:0] stage;
reg [1:0] round;
assign dout = result;
assign dout_vld = (stage == 2);
always @(posedge clk or negedge rst_n) begin
if (~rst_n) begin
x <= 0;
x_next <= 0;
result <= 0;
cnt <= 0;
stage <= 0;
round <= 0;
end else begin
if (din_vld) begin
x <= din;
cnt <= cnt + 1;
end
if (cnt >= 5) begin
cnt <= 0;
case (stage)
0: begin
x_next <= x;
stage <= 1;
end
1: begin
x_next <= (x + (din >> 4)) >> 1;
stage <= 2;
end
default: begin
stage <= 0;
end
end
end
if (stage == 2) begin
if (round < 3) begin
x_next <= x_next + ((x >> (6 - round*2)) & 2'b11) - 1;
round <= round + 1;
end else begin
result <= x_next[7:4];
stage <= 0;
round <= 0;
end
end
end
end
endmodule
```
代码中使用了一个状态机来控制牛顿迭代法的各个阶段,同时使用了一个计数器来判断输入数据是否连续。在第一个阶段,将当前值赋给 x_next;在第二个阶段,使用牛顿迭代法计算下一个值;在第三个阶段,将结果四舍五入后输出,并重置状态机和计数器。
需要注意的是,牛顿迭代法的迭代公式为:
```
x_next = (x + a/x) / 2
```
其中 a 为被开方数,x 为当前值,x_next 为下一个值。在本题中,被开方数为 8bits,因此需要将输入数据右移 4 位,即 a = din >> 4。同时,每个阶段迭代两次,因此需要将 x 右移 2 位。
最后,结果需要四舍五入并保留整数部分。这里采用了一个简单的方法:将结果向上加一位,然后取高四位作为最终结果。这个过程可以通过一个计数器和一个状态机来实现。具体实现如下:
```
if (round < 3) begin
x_next <= x_next + ((x >> (6 - round*2)) & 2'b11) - 1;
round <= round + 1;
end else begin
result <= x_next[7:4];
stage <= 0;
round <= 0;
end
```
其中,round 记录当前迭代的次数,stage 记录当前阶段。在每次迭代中,将 x_next 右移一定位数,然后加上当前这一位的值(0 或 1),再减去 1。最后,将结果向上取整并保留高四位作为最终结果。