接下來探討一種透過牛頓法
來找到相除解的方法
收斂除法
次數通常為:上高斯的(根號(bit 數))
宣告狀態
/*------localparam------*/
localparam IDLE = 2'd0;
localparam CAL = 2'd1;
localparam FINISH = 2'd2;
宣告輸入輸出
module divAegp(
clkSys,
en,
rst_n,
dividend,
divisor,
q_out,
done
);
/*------ports declarations------*/
input clkSys;
input en;
input rst_n;
input [8:0] dividend;
input [8:0] divisor;
output [8:0] q_out;
output done;
reg [8:0] q_out;
reg done;
宣告變數
/*------variables------*/
reg [1:0] fstate;
reg [1:0] count;
reg [9:0] x;
reg [9:0] t;
reg [9:0] f;
reg [17:0] tempX;
reg [17:0] tempT;
狀態邏輯
/*-------fstate state-------*/
always@(posedge clkSys or negedge rst_n)begin
if(!rst_n)fstate <= IDLE;
else begin
case(fstate)
IDLE:begin
if(en)fstate <= CAL;
else fstate <= IDLE;
end
CAL:begin
if(count == 2'd1)fstate <= FINISH;
else fstate <= CAL;
end
FINISH:fstate <= IDLE;
default:fstate <= IDLE;
endcase
end
end
輸出邏輯
/*-------fstate output-------*/
always@(posedge clkSys or negedge rst_n)begin
if(!rst_n)begin
q_out <= 9'd0;
x <= 10'd0;
t <= 10'd0;
f <= 10'd0;
tempX <= 18'd0;
tempT <= 18'd0;
count <= 2'd0;
done <= 1'b0;
end
else begin
case(fstate)
IDLE:begin
count <= 2'd0;
x <= {1'b0, dividend};
t <= {1'b0, divisor};
done <= 1'b0;
end
CAL:begin
f = 10'd512 - t;
tempX = (x * f);
tempT = (t * f);
x <= tempX >> 8;
t <= tempT >> 8;
count <= count + 2'd1;
end
FINISH:begin
q_out <= x[8:0];
done <= 1'b1;
end
default:begin
q_out <= 9'd0;
x <= 10'd0;
t <= 10'd0;
f <= 10'd0;
tempX <= 18'd0;
tempT <= 18'd0;
count <= 2'd0;
done <= 1'b0;
end
endcase
end
end
endmodule
`timescale 1ns/1ns
module tb_divAegp();
reg clkSys;
reg en;
reg rst_n;
reg [8:0] dividend;
reg [8:0] divisor;
wire [8:0] q_out;
wire done;
divAegp UUT(
.clkSys(clkSys),
.en(en),
.rst_n(rst_n),
.dividend(dividend),
.divisor(divisor),
.q_out(q_out),
.done(done)
);
initial begin
clkSys = 0;
en = 0;
rst_n = 0;
repeat(5)@(posedge clkSys)rst_n = 0;
rst_n = 1;
test(384, 307);//320
test(360, 300);//307
test(350, 310);//289
test(400, 257);//398#
#1000 $stop;
end
always #10 clkSys = ~clkSys;
task test;
input [8:0]a;
input [8:0]b;
begin
dividend = a;
divisor = b;
#100 en = 1;
#40 en = 0;
wait (done == 1);
end
endtask
endmodule
Wave
舉個例子:
第一筆測試資料為 1.5(384/256) 除以 1.2(307/256) 應該要得到的答案是 1.25(320),後面的例子以此類推~~
那麼今天的教學就到這邊嘍~~