精品国产一区在线_av无码中文字幕无码王_天海翼三点刺激高潮不停_好硬好大好爽视频_欧美高清一区三区在线专区_香蕉黄色片

數(shù)字設(shè)計筆試Verilog手撕代碼 - 浮點加法

前言

今天在網(wǎng)上看筆試題發(fā)現(xiàn)有個設(shè)計浮點累加器的題目,看了下題目說明感覺不太清楚,恰好記得之前做過浮點數(shù)的加法運算的設(shè)計,索性就改了下題目需求,作為一個小練習(xí)在重新設(shè)計一遍。具體設(shè)計要求如下:

設(shè)計需求

設(shè)計一個32bit浮點的加法器,out = A + B,假設(shè)AB均為無符號位,或者換個說法都為正數(shù)。

clk為系統(tǒng)時鐘;rst_n為系統(tǒng)復(fù)位,低有效;en信號控制數(shù)據(jù)輸入;busy指示模塊工作狀態(tài),busy拉高時,輸入無效;aIn和bIn是數(shù)據(jù)輸入,out_vld,指示輸出數(shù)據(jù)有效。

設(shè)計的信號列表如下:

module float_adder(
  input                clk,
  input              rst_n,
  input                 en, 
  input      [31:0]    aIn,
  input      [31:0]    bIn,
  output reg          busy,
  output reg       out_vld,   
  output reg [31:0]    out
);

32bit的浮點格式

EE標準754規(guī)定了三種浮點數(shù)格式:單精度、雙精度、擴展精度。前兩者正好對應(yīng)C語言里頭的float、double或者FORTRAN里頭的real、double精度類型。本文設(shè)計實現(xiàn)的為單精度。

單精度格式

單精度:N共32位,其中S占1位,E占8位,M占23位。

雙精度格式

雙精度:N共64位,其中S占1位,E占11位,M占52位。

浮點數(shù)的加法過程

運算過程:對階、尾數(shù)求和、規(guī)格化、舍入、溢出判斷

對階:

和定點數(shù)不相同的是,浮點數(shù)的指數(shù)量級不一定是一樣的,所以這也就意味著,尾數(shù)直接進行加法運算時會存在問題,也就需要首先對階數(shù)進行處理。該過程有點像科學(xué)計數(shù)法的加法處理,把科學(xué)計數(shù)法的指數(shù)化為一致,求出來指數(shù)相差多少,然后移位處理后再進行加法減法。所以這里處理也要先求階差。

如果把階碼大的向階碼小的看齊,就要把階碼大的數(shù)的尾數(shù)部分左移,階碼減小。這個操作有可能在移位過程中把尾數(shù)的高位部分移掉,這樣就引發(fā)了數(shù)據(jù)的錯誤,所以,尾數(shù)左移在計算機運算中不可取。

如果把階碼小的向階碼大的看齊,在移位過程中如果發(fā)生數(shù)據(jù)丟失,也是最右邊的數(shù)據(jù)位發(fā)生丟失,最右邊的數(shù)據(jù)位丟失,只會影響數(shù)據(jù)的精度,不會影響數(shù)據(jù)的大小。

尾數(shù)求和

這里就是常規(guī)的補碼加法。

規(guī)格化:

右規(guī)(尾數(shù)的絕對值太大時,右規(guī)) 尾數(shù)右移一位,階碼加1。當尾數(shù)溢出( >1 )時,需要右規(guī)。是否溢出,可以通過兩位的符號位得出:即尾數(shù)出現(xiàn)01.xx…xx或10.xx…xx(兩位符號位不同)

提高浮點數(shù)的表示精度,這里設(shè)計考慮比較簡單,我只考慮了同號數(shù)據(jù)相加的情況,所以這里只設(shè)計了右規(guī)的情況,不考慮符號位。

舍入判斷:

這里直接用截斷處理的方式,針對數(shù)據(jù)相加上溢的情況,規(guī)定了運算后上溢后將數(shù)據(jù)規(guī)定為最大值。

實現(xiàn)代碼

module float_adder(
  input                clk,
  input              rst_n,
  input                 en, 
  input      [31:0]    aIn,
  input      [31:0]    bIn,
  output reg          busy,
  output reg       out_vld,   
  output reg [31:0]    out
);
//運算過程:對階、尾數(shù)求和、規(guī)格化、舍入、溢出判斷
//分離階數(shù)、尾數(shù)
wire signal_bit = aIn[31];
wire [7:0] pow_a = aIn[30:23];
wire [7:0] pow_b = bIn[30:23];

wire [22:0] val_a = aIn[22:0];
wire [22:0] val_b = bIn[22:0];

//找到輸入指數(shù)階數(shù)較大,和階數(shù)差
//對階:在計算機中,采用小階向大階看齊的方法,實現(xiàn)對階。即右移
reg [22:0] pow_max ;
reg [23:0] pow_dif ;
reg [22:0] val_max ;
reg [22:0] val_min ;
reg en_dly0;
always @(posedge clk or negedge rst_n) begin
  if(rst_n==0)begin
    pow_max <= 'd0;
    val_max <= 'd0;
    val_min <= 'd0;
    pow_dif <= 'd0;
    en_dly0 <= 'd0;
  end
  else if( en == 1 && busy == 0)begin
    if(pow_a >= pow_b)begin
      pow_max <= pow_a;
      val_max <= val_a;
      val_min <= val_b;
      en_dly0 <= 'd1;
      if ( pow_a - pow_b > 'd23) begin
        pow_dif <= 'd23;
      end 
      else begin
        pow_dif <= pow_a - pow_b;
      end
    end
    else begin
      pow_max <= pow_b;
      val_max <= val_b;
      val_min <= val_a;
      en_dly0 <= 'd1;
      if ( pow_b - pow_a > 'd23) begin
        pow_dif <= 'd23;
      end 
      else begin
        pow_dif <= pow_b - pow_a;
      end
    end
  end
  else begin
    pow_max <= pow_max;
    val_max <= val_max;
    val_min <= val_min;
    pow_dif <= pow_dif;
    en_dly0 <= 'd0;
  end
end

//移位忙指示信號
reg shift_busy;
reg [4:0] shift_cnt;
always @(posedge clk or negedge rst_n) begin
  if (rst_n==0) begin
    shift_busy<='d0;
  end
  else if(en_dly0 == 1 )begin
    shift_busy <='d1;
  end
  else if(shift_cnt == pow_dif)begin
    shift_busy <=  0;
  end
end

//移位計數(shù)

always @(posedge clk or negedge rst_n) begin
  if(rst_n == 0)begin
    shift_cnt <= 'd0;
  end
  else if (shift_busy ==1) begin
    if (shift_cnt == pow_dif) begin
      shift_cnt <= shift_cnt;
    end
    else begin
      shift_cnt <= shift_cnt + 1'b1;
    end
  end
  else begin
    shift_cnt <= 'd0;
  end
end
reg [22:0] val_shift;
always @(posedge clk or negedge rst_n) begin
  if(rst_n == 0)begin
    val_shift <= 'd0;
  end
  else if (en_dly0==1'b1) begin
    val_shift <= val_min;
  end
  else if (shift_busy == 1) begin
    val_shift <= {1'b0,val_shift[22:1]};
  end
  else begin
    val_shift <= val_shift;
  end
end

//尾數(shù)求和
wire val_add_flag = (shift_cnt == pow_dif)&&(shift_busy ==1);
reg [23:0] val_sum;
reg val_sum_vld;
always @(posedge clk or negedge rst_n) begin
  if (rst_n==0) begin
    val_sum<='d0;
    val_sum_vld<='d0;
  end
  else if(val_add_flag == 1)begin
    val_sum <= val_max + val_shift;
    val_sum_vld<='d1;
  end
  else begin
    val_sum <= val_sum;
    val_sum_vld<='d0;
  end
end

//規(guī)范
always @(posedge clk or negedge rst_n) begin
  if (rst_n==0) begin
    out<='d0;
    out_vld<='d0;
  end
  else if(val_sum_vld == 1)begin
    //尾數(shù)求和有溢出
    out_vld<='d1;
    out[31]<= signal_bit;
    if(val_sum[23] == 1 && out[30:23] == 8'hFF)begin
      out[30:23]<= 8'hFF;
      out[22:0] <= 23'h7F_FFFF;
    end
    else if(val_sum[23] == 1)begin
      out[30:23]<= pow_max + 1;
      out[22:0] <= val_sum[23:1];
    end
    else begin
      out[30:23]<= pow_max;
      out[22:0] <= val_sum[22:0];
  end 
  end
  else begin
    out <= out;
    out_vld<='d0;
  end
end

//運算忙指示
always @(posedge clk or negedge rst_n) begin
  if (rst_n==0) begin
    busy<='d0;
  end
  else if(en == 1 && busy == 0)begin
    busy<='d1;
  end
  else if(out_vld == 1 )begin
    busy<='d0;
  end
  else begin
    busy <= busy;
  end
end

endmodule

仿真代碼

這里簡單測試了下代碼的功能,模擬了連續(xù)輸入多個數(shù)據(jù),核查是否數(shù)據(jù)會影響正常計算過程。

`timescale 1ns/1ps
module float_adder_tb;

  // Parameters

  // Ports
  reg clk = 1;
  reg rst_n = 0;
  reg en = 0;
  reg [31:0] aIn;
  reg [31:0] bIn;
  wire busy;
  wire out_vld;
  wire [31:0] out;

  float_adder float_adder_dut (
    .clk (clk ),
    .rst_n (rst_n ),
    .en (en ),
    .aIn (aIn ),
    .bIn (bIn ),
    .busy (busy ),
    .out_vld (out_vld ),
    .out  ( out)
  );
  always
    #5  clk = ! clk ;
  initial begin
    rst_n = 0;
    #100;
    rst_n = 1;
    #100;
    aIn = {1'b0,8'd2,23'd7};
    bIn = {1'b0,8'd2,23'd8};
    en  = 1 ;
    #10;
    aIn = {1'b0,8'd0,23'd7};
    bIn = {1'b0,8'd2,23'd8};
    en  = 1 ;
    #1000;
    $finish;
  end

endmodule

仿真測試

從仿真測試中可以看出,當輸入信號連續(xù)輸入兩個浮點數(shù)時,在busy拉高狀態(tài)下,第二次輸入的數(shù)據(jù)無效,數(shù)據(jù)使能信號常為1,也不會影響正常模塊運算過程,只有在該次運算完成busy拉低后數(shù)據(jù)可重新加載。

仿真截圖

小結(jié)

本文的設(shè)計方法對于對階移位的操作需要循環(huán)操作,也即當階數(shù)相差較小時,結(jié)果輸出延遲較小,在極端情況下,比如階數(shù)差大于10,輸出延時會比階數(shù)差為0時,多10個周期,上限為23。如在實際使用時,對延時要求較小的情況,可針對移位操作部分,使用更多的資源來換取性能的提升。可使用case語句對具體情況進行遍歷。

針對原始題目中的累加操作,可將任意一個輸入和輸出相接,即可實現(xiàn)累加操作。此外,如果要實現(xiàn)異號加法情況,則需要仔細考慮對階,規(guī)格化等情況進行進一步設(shè)計。

聲明:本內(nèi)容為作者獨立觀點,不代表電子星球立場。未經(jīng)允許不得轉(zhuǎn)載。授權(quán)事宜與稿件投訴,請聯(lián)系:editor@netbroad.com
覺得內(nèi)容不錯的朋友,別忘了一鍵三連哦!
贊 2
收藏 3
關(guān)注 17
成為作者 賺取收益
全部留言
0/200
成為第一個和作者交流的人吧
主站蜘蛛池模板: 成人片国产精品亚洲 | 国产SUV精品一区二区 | 久久久成人精品视频 | 日本久久久久久久做爰片日本 | www.91成人 | 欧洲精品一区二区三区 | 亚洲精品无码一区二区三区污 | 亚洲国产综合专区在线播放 | 最新男同志69可播放gay | 极品久久久久 | 亚洲高清视频一区二区三区 | 国产人妻人伦精品1国产 | eeuss国产一区二区三区四区 | 无码精品一区二区三区四区爱奇艺 | 涩涩网站入口 | 日韩一卡2卡3卡4卡2021免费观看国色天香 | 国产免费97| 69日影院| 蜜臀精品一区二区 | 艳妇乳肉豪妇荡乳在线视频 | 久久第二页 | 色翁荡熄又大又硬又粗又动态图 | 中文字幕日产av一二三区 | 色综合天天综合综合国产 | 国产丝袜视频一区二区三区 | 国产二二三区 | 成人福利视频网站 | 一级黄色录像片 | xxxx色| 91亚洲精品乱码久久久久久蜜桃 | 中文字幕a级片 | 日本一区二区在线观看视频 | 日本残虐sm一区二区三区 | 一级二级三级黄色片 | 中文字幕中文字幕中文字幕亚洲无线 | 国产一卡二卡3卡四卡免费 亚洲免费毛片基地 | 草逼小视频 | 精品久久影院 | 鬼灭之刃在线观看免费 | 美女主播在线观看 | 大地资源网在线观看免费高清 |