該開方器的演算法與「手算」(以前並不知道開方還有這種手算的方法)演算法相似,使用迭代解決,文字描述如下
將0為餘數的初值a
,0作為結果初值b
將被開方數前兩位取出,與01比較大小。若前兩位大,則
- 01
為輸出餘數(a(m)
),輸出結果1(b(m)
),否則為輸出餘數(
a(m)
),輸出結果0(b(m)
)
將被開方數的從高位數第3,4位取出,比較
和
的大小,若前一項大,則輸出餘數
a(m - 1)
為前一項減後一項,輸出結果b(m - 1)
為;否則,輸出餘數為前一項(直接輸出),輸出結果
b(m - 1)
為...
直到計算完被開方數結束
迭代單元的演算法比較簡單,描述如下:
組合輸入餘數和當前開方數的兩位,組合輸入結果和01為
比較大小,若組合餘數大則輸出餘數為組合餘數減去組合結果,輸出結果
;否則餘數輸出組合餘數,結果輸出
module square_cell #(
parameter width = 4,
parameter step = 0
)( input clk, // clock
input rst_n, // asynchronous reset active low
input [2 * width - 1:0]radicand,
input [width - 1:0]last_dout,
input [2 * width - 1:0]remainder_din,
output reg [width - 1:0]this_dout,
output reg [2 * width - 1:0]remainder_dout
);wire [2 * width - 1:0]target_data = ;
wire [2 * width - 1:0]try_data = ;
always @(posedge clk or negedge rst_n) begin
if(~rst_n) begin
<= 'b0;
end else begin
if(target_data >= try_data) begin
this_dout <= ;
remainder_dout <= target_data - try_data;
end else begin
this_dout <= ;
remainder_dout <= target_data;
endend
endendmodule
module square_extractor #(
parameter width = 4
)( input clk, // clock
input rst_n, // asynchronous reset active low
input [2 * width - 1:0]radicand,
output [width - 1:0]dout,
output [2 * width - 1:0]remainder
);genvar i;
generate
for (i = width - 1; i >= 0; i = i - 1) begin:square
wire [2 * width - 1:0]remainder_dout,remainder_din;
wire [width - 1:0]this_dout,last_dout;
if(i == width - 1) begin
assign remainder_din = 'b0;
assign last_dout = 'b0;
end else begin
assign remainder_din = square[i + 1].remainder_dout;
assign last_dout = square[i + 1].this_dout;
endsquare_cell #(
.width(width),
.step(i)
) u_square_cell (
.clk(clk), // clock
.rst_n(rst_n), // asynchronous reset active low
.radicand(radicand),
.last_dout(last_dout),
.remainder_din(remainder_din),
.this_dout(this_dout),
.remainder_dout(remainder_dout)
);end
endgenerate
assign dout = square[0].this_dout;
assign remainder = square[0].remainder_dout;
endmodule
testbench輸入隨機的輸入後,等待完成,完成後取結果和餘數看是否能恢復出正確的輸入
module tb_square (
);parameter width = 4;
logic clk; // clock
logic rst_n; // asynchronous reset active low
logic [2 * width - 1:0]radicand;
logic [width - 1:0]dout;
logic [2 * width - 1:0]remainder;
square_extractor #(
.width(width)
) dut (
.clk(clk), // clock
.rst_n(rst_n), // asynchronous reset active low
.radicand(radicand),
.dout(dout),
.remainder(remainder)
);initial begin
clk = 0;
forever begin
#50 clk = ~clk;
endendinitial begin
rst_n = 1'b1;
#5 rst_n = 1'b0;
#10 rst_n = 1'b1;
endlogic [2 * width - 1:0]act;
logic [2 * width - 1:0]dout_ex;
initial begin
radicand = 'b0;
forever begin
@(negedge clk);
radicand = (2 * width)'($urandom_range(0,2 ** (2 * width)));
repeat(4 * width) begin
@(negedge clk);
enddout_ex = ';
act = dout_ex * dout_ex + remainder;
if(act != radicand) begin
$stop;
endend
endendmodule
基於迭代單元的除法器
數字訊號處理中,有大量的演算法是基於迭代演算法,即下一次的運算需要上一次運算的結果,將運算部分固化為迭代單元可以將資料處理和流程控制區分,更容易做出時序和面積優化更好的硬體描述,這次將基於迭代單元構造恢復餘數和不恢復餘數除法器 演算法將除數移位i位 判斷位移後的除數與餘數大小 若位移除數大於餘數,則...
關於開方的迭代演算法
去年某司有一道面試題是不用 開根號計算開方,當時第一反應就是迭代逼近,但是對方還要求能不能把速度加快,先稍作總結。迭代逼近意思就是 我先隨便取乙個數,如果平方大於給定 n,那麼就取乙個小一點的 如果小了,那就取個大一點,最後達到精度要求即可。實現 class solution else x x 快速...
Oracle恢復(七) 基於時間的恢復
首先有備份 其次知道自己想要恢復到的歷史時間 拷貝備份的所有資料檔案回來,startup mount 啟動到mount狀態 recover database until time 2012 04 10 16 43 01 穿越到今天 呵呵 因為10號發工資,所以喜歡穿越到10號 mediarecove...