【Day28】2次收敛除法器实作

接下来探讨一种透过牛顿法来找到相除解的方法

收敛除法

  • Step1 : 规格化 N 和 D,令 D 趋近於 1,例如 0.5 <= D < 1 or 1 <= D < 2
  • step2 : 初始化 x0 = Nt0 = D
  • step3 : 重复如下循环,直到 xk 满足所需精度
    • fk = 2 - tk
    • xk+1 = xk * fk
    • tk+1 = tk * fk

次数通常为:上高斯的(根号(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;

宣告变数

  • tempX 及 tempT 用来存放乘法後结果,需要两倍宽的 bit 数
/*------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

TestBench


`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),後面的例子以此类推~~

那麽今天的教学就到这边喽~~


<<:  Day 28 Rails shallow nesting

>>:  【Side Project】 赛後检讨

Day27 Router useParams 小实作

在 URL 中设置动态参数传递给指定参数组件。 在App.js 的Route path="...

[Day6] 开发环境建置

这节将介绍笔者这次的开发环境。 笔者这次选用Python做为开发的程序语言。 会选择Anaconda...

30天轻松学会unity自制游戏-调整摄影机

现在会遇到Boss也会一直往前移动,(要测试可以先把摄影机跟player的这行注解掉)如果不做测试就...

33岁转职者的前端笔记-DAY 19 练习写一个计算机

写计算机前必学的知识点 资料型别 (typeof) 检查变数的型别:typeof 资料型别如下: s...

Day26 - HTML 与 CSS (8) - 背景图片

背景图片 background-image:使用 url(pic路径) 来显示图片 backgrou...