全球最实用的IT互联网信息网站!

AI人工智能P2P分享&下载搜索网页发布信息网站地图

当前位置:诺佳网 > 电子/半导体 > 可编程逻辑 >

FPGA加法截位处理方法介绍

时间:2024-04-18 16:53

人气:

作者:admin

标签:

导读:本模块实现输入与输出位宽相同数据加法,并对结果进行四舍五入截位,对标matlab round函数。...

本模块实现输入与输出位宽相同数据加法,并对结果进行四舍五入截位,对标 round函数。

`mescale 1ns/1ns


module data_in_width_out_width_d_round #
(
    paer DATA_WIDTH   = 16                             
)
(
    // 系统
    input                               i_clk_sys       ,
    input                               i_t           ,
        
    // 数据输入
    input  signed   [DATA_WIDTH-1:0]    i_din_a         ,
    input                               i_din_a_vld     ,
    input  signed   [DATA_WIDTH-1:0]    i_din_b         ,
    input                               i_din_b_vld     ,
    
    // 数据输出
    output signed   [DATA_WIDTH-1:0]    o_dout          ,
    output                              o_dout_vld  
);


/****************************************************************************/
/*  parameter
/****************************************************************************/


/****************************************************************************/
/*  signal
/****************************************************************************/
 signed    [DATA_WIDTH-1+1:0]  din_add_result          ;
logic                               din_add_result_vld      ;
logic signed    [DATA_WIDTH-1+2:0]  din_add_result_round    ;
logic signed    [DATA_WIDTH-1:0]    din_add_result_truncate ;        
logic                               din_add_result_vld_1dly ;
logic                               din_add_result_vld_2dly ;        
   
/****************************************************************************/
/*  process
/****************************************************************************/
always @(posedge i_clk_sys or posedge i_rst)                    // 数据加法
begin 
    if (i_rst)
    begin 
        din_add_result <= {{DATA_WIDTH+1}{1'b0}};
    end
    else 
    begin 
        din_add_result <= i_din_a + i_din_b;
    end
end


always @(posedge i_clk_sys)                
begin 
    din_add_result_vld <= i_din_a_vld && i_din_b_vld;
end


always @(posedge i_clk_sys)                                     // 数据四舍五入,根据要舍弃的位宽加不同的值
begin 
    if (din_add_result[DATA_WIDTH] == 1'b0)                     // 每次加法先扩充一个符号位,再对小数点位置进行 加减 0.5
    begin 
        din_add_result_round <= {din_add_result[DATA_WIDTH],din_add_result + 1'b1}; 
    end 
    else                                                        // 4'b1000}; +4bit 1是为了modelsim仿真,modelsim仿真规定小数至少3位
    begin 
        din_add_result_round <= {din_add_result[DATA_WIDTH],din_add_result - 1'b1};  
    end
end


always @(posedge i_clk_sys or posedge i_rst)                    // 数据截位
begin 
    if (i_rst)
    begin 
        din_add_result_truncate <= {DATA_WIDTH{1'b0}};
    end
    else if (din_add_result_round[DATA_WIDTH+1] == din_add_result_round[DATA_WIDTH])
    begin                                                       // 如果数据没有溢出,舍弃最后一位,赋值; 先补充符号位,再取表示起始bit为1,包含bit1并往上升DATA_WIDTH-1位
        din_add_result_truncate <= {din_add_result_round[DATA_WIDTH+1],din_add_result_round[1+ :(DATA_WIDTH-1)]};
    end
    else if (din_add_result_round[DATA_WIDTH+1] == 1'b0 && din_add_result_round[DATA_WIDTH] == 1'b1)
    begin                                                       // 如果正数溢出了,就给一个设置的位宽bit正数最大值,'h7fff 
        din_add_result_truncate <= {1'b0,{(DATA_WIDTH-1){1'b1}}};
    end
    else if (din_add_result_round[DATA_WIDTH+1] == 1'b1 && din_add_result_round[DATA_WIDTH] == 1'b0)
    begin                                                       // 如果负数溢出了,就给一个设置的位宽bit负数最大值,'h8000
        din_add_result_truncate <= {1'b1,{(DATA_WIDTH-1){1'b0}}};
    end    
end


always @(posedge i_clk_sys)                                     // 数据有效流水打拍
begin 
    din_add_result_vld_1dly <= din_add_result_vld;
    din_add_result_vld_2dly <= din_add_result_vld_1dly;


    o_dout                  <= din_add_result_truncate;
    o_dout_vld              <= din_add_result_vld_2dly;
end


endmodule

代码中如果直接截位,数据的输出将会产生直流,所以需要对数据的符号位进行判断,并进行处理。简单的思路如下:

1.数据先进行加法。

2.对加法后的结果,进行判断,正数+0.5,负数-0.5,此操作用于去除直流。

3.再对去除直流后的结果,进行需要的截位取值,例如16bit+16bit=17bit,而最终的输出结果,如果要16bit,那就去掉末位,也可以只要15bit,去掉末2bit,只要bit15-bit2。

上述代码是简单的例子处理,输入进来的两种数据同位宽,输出也用同位宽输出。后续可以改进。



审核编辑:刘清

温馨提示:以上内容整理于网络,仅供参考,如果对您有帮助,留下您的阅读感言吧!
相关阅读
本类排行
相关标签
本类推荐

CPU | 内存 | 硬盘 | 显卡 | 显示器 | 主板 | 电源 | 键鼠 | 网站地图

Copyright © 2025-2035 诺佳网 版权所有 备案号:赣ICP备2025066733号
本站资料均来源互联网收集整理,作品版权归作者所有,如果侵犯了您的版权,请跟我们联系。

关注微信