星空-verilog求倒数

verilog求倒数-ROM实现方式 时候:2024-12-19 20:24:14 手机看文章

扫描二维码随时随地手机看文章

采取线性迫近法连系32段线性查找表的体例来实现1/z的计较。

起首将1/32-1/64的定点化数据寄存到ROM中,ROM中寄存的是扩年夜了2^20 次方的数字四舍五入后的整数部门。n值越年夜,精度越年夜,误差越小。这里取n=20;

ROM中存储的数据是1/(32+i)*2^20的四舍五入的整数部门。

32-64间的数据可以经由过程查表来实现,其他的数据则采取的是线性迫近的方式。

线性迫近的步调为:

1.肯定最高非零比特位的位置

2.对z进行左移或右移,获得zp

3.zp查找ROM,获得1/zp,和1/(zp+1),

4.求的1/zp-1/(zp+1),为误差A

5.N=z-zp*2^(m-5)

6.B=A/2^(m-5)*N

7.将扩年夜的部门缩小归去,或缩小了的放年夜归去,那末1/z=(1/zp-B)*(1/2^(m-5))

代码插入:

moduletop_inv(inputclk,syn_rst,input[20:0]dataa,input[20:0]datab,//input[20:0]ampout,outputreg[19:0]inv//outputreg done );reg[4:0]address1;reg[4:0]address2;wire[4:0]m;//wire done;reg[19:0]invr;reg[20:0]ampout_r;reg[20:0]ampout_r1;wire[20:0]ampout;reg[20:0]ampoutr1,ampoutr2,ampoutr3,ampoutr4;wire[19:0]inv_r1;wire[19:0]inv_r2;reg[20:0]diff_r;reg[19:0]diffr;reg[19:0]diff;reg[19:0]N;reg[19:0]N1;regen;always@(posedgeclkornegedgesyn_rst)begin if(~syn_rst)beginampoutr1 =21'd0;ampoutr2 =21'd0;ampoutr3 =21'd0;ampoutr4 =21'd0;end else ampoutr1 =ampout; ampoutr2 =ampoutr1; ampoutr3 =ampoutr2; ampoutr4 =ampoutr3; end reg [19:0] inv_r1t1,inv_r1t2,inv_r1t3; always@(posedge clk or negedge syn_rst) begin if(~syn_rst)begininv_r1t1 inv_r1t2 inv_r1t3 end else begininv_r1t1 =inv_r1; inv_r1t2 =inv_r1t1; inv_r1t3 =inv_r1t2; end end reg [4:0] mt1,mt2,mt3,mt4,mt5; always@(posedge clk or negedge syn_rst) begin if(~syn_rst)beginmt1 mt2 mt3 mt4 mt5 end else beginmt1 mt2 =mt1; mt3 =mt2; mt4 =mt3; mt5 =mt4; end end reg sel; reg selr1,selr2; always @(posedge clk or negedge syn_rst) begin if(~syn_rst)begindiff diffr ampout_r ='b0;ampout_r1 address1 ='b0;address2 ='b0;en sel end else begin // if(done) //begin if((ampout =32) (ampout =64)) begin ampout_r ampout_r1 address1 =ampoutr3-32; address2 diff diffr N N1 en //不需要计较m的值 sel selr1 selr2 end else begin en //需要计较m的值 if(m 5)begin//ampoutrr =ampout; ampout_r =ampoutr1 (m-5);ampout_r1 =ampout_r;//zp address1 =ampout_r-32;///inv_r1 address2 =ampout_r-31;///inv_r2 diff = inv_r1-inv_r2; diffr =diff; N1 =ampout_r1 (mt2-5); N =ampoutr4-N1; selr1 selr2 = selr1; sel = selr2; end if(m 5) begin //ampoutrr =ampout; ampout_r =ampoutr1 (5-m);// mt4 mt3 mt2 ampout_r1 = ampout_r;// N N1 ampout_r1 address1 =ampout_r-32;///mt4 inv_r1 address2 =ampout_r-31;//inv_r1t3 inv_r2 mt1 diff = inv_r1-inv_r2;//diff_r (5-mt2);N =ampoutr4-N1; selr1 selr2 = selr1; sel = selr2; end end end // end end // assign diff=sel?(inv_r1-inv_r2):'b0;//assignN=sel?(ampout-N1):0;//assigndiff_r=en?(diff*N (m-5)):0;//assigndiff_r=(m 5)?(diff*N (m-5)):(diff*N (5-m)); // assign inv = sel?(inv_r1-diff_r) (m-5):inv_r1;always@(posedgeclkornegedgesyn_rst)begin if(~syn_rst)begininvr // done diff_r end else begin if(sel)begin if(m 5)begindiff_r = diffr*N (mt4-5);invr =(inv_r1t3-diff_r) (mt5-5);// done end else begindiff_r = diffr*N (5-mt4); invr =(inv_r1t3-diff_r) (5-mt5); // done end end else begindiff_r invr =inv_r1t3; end end end always@(posedge clk or negedge syn_rst) begin if(~syn_rst)begininv end else begin if(invr)inv = invr; else inv =inv; end end //ROM 核的例化 rom u_rom(.clk(clk), .address1(address1), .address2(address2), .inv_r1(inv_r1), .inv_r2(inv_r2)//, //.c(c) ); //例化寻觅最高非零位 not_0 u_not_0 ( // port map - connection between master ports and signals/registers .ampout(ampout), .clk(clk), .m(m), .en(en), .syn_rst(syn_rst) ); complex_abs u_comlex_abs( .clk(clk), .syn_rst(~syn_rst), .dataa(dataa), .datab(datab), .ampout(ampout) ); endmodule

那末终究的仿真成果:假如直接查询的话,成果输出延时一个时钟周期,假如线性迫近的方式获得,延时3-5个时钟周期,这里周期设定为20ns;

占用资本陈述:

增添一个求平方根的模块今后的仿真成果(数据输入后,一共需要约10个时钟周期才可以计较出一个平方更求导数值)。有一个小疑问就是怎样添加一个标记旌旗灯号,让我们知道哪里输出的inv 旌旗灯号是有用的

欲知详情,请下载word文档 下载文档

上一篇:星空-pll及其modesim仿真流程 下一篇:星空-Bourns 荣获 EE Awards Asia 亚洲金选奖年度分立组件大奖