本模塊實(shí)現(xiàn)輸入與輸出位寬相同數(shù)據(jù)加法,并對(duì)結(jié)果進(jìn)行四舍五入截位,對(duì)標(biāo)matlab round函數(shù)。
`timescale 1ns/1ns module data_in_width_out_width_add_round # ( parameter DATA_WIDTH = 16 ) ( // 系統(tǒng)接口 input i_clk_sys , input i_rst , // 數(shù)據(jù)輸入 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 , // 數(shù)據(jù)輸出 output signed [DATA_WIDTH-1:0] o_dout , output o_dout_vld ); /****************************************************************************/ /* parameter /****************************************************************************/ /****************************************************************************/ /* signal /****************************************************************************/ logic 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) // 數(shù)據(jù)加法 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) // 數(shù)據(jù)四舍五入,根據(jù)要舍棄的位寬加不同的值 begin if (din_add_result[DATA_WIDTH] == 1'b0) // 每次加法先擴(kuò)充一個(gè)符號(hào)位,再對(duì)小數(shù)點(diǎn)位置進(jìn)行 加減 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仿真規(guī)定小數(shù)至少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) // 數(shù)據(jù)截位 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 // 如果數(shù)據(jù)沒有溢出,舍棄最后一位,賦值; 先補(bǔ)充符號(hào)位,再取表示起始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 // 如果正數(shù)溢出了,就給一個(gè)設(shè)置的位寬bit正數(shù)最大值,'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 // 如果負(fù)數(shù)溢出了,就給一個(gè)設(shè)置的位寬bit負(fù)數(shù)最大值,'h8000 din_add_result_truncate <= {1'b1,{(DATA_WIDTH-1){1'b0}}}; end end always @(posedge i_clk_sys) // 數(shù)據(jù)有效流水打拍 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
代碼中如果直接截位,數(shù)據(jù)的輸出將會(huì)產(chǎn)生直流,所以需要對(duì)數(shù)據(jù)的符號(hào)位進(jìn)行判斷,并進(jìn)行處理。簡(jiǎn)單的思路如下:
1.數(shù)據(jù)先進(jìn)行加法。
2.對(duì)加法后的結(jié)果,進(jìn)行判斷,正數(shù)+0.5,負(fù)數(shù)-0.5,此操作用于去除直流。
3.再對(duì)去除直流后的結(jié)果,進(jìn)行需要的截位取值,例如16bit+16bit=17bit,而最終的輸出結(jié)果,如果要16bit,那就去掉末位,也可以只要15bit,去掉末2bit,只要bit15-bit2。
上述代碼是簡(jiǎn)單的例子處理,輸入進(jìn)來(lái)的兩種數(shù)據(jù)同位寬,輸出也用同位寬輸出。后續(xù)可以改進(jìn)。
審核編輯:劉清
-
FPGA
+關(guān)注
關(guān)注
1625文章
21636瀏覽量
601308 -
matlab
+關(guān)注
關(guān)注
182文章
2960瀏覽量
230044
原文標(biāo)題:FPGA加法截位處理
文章出處:【微信號(hào):pdh的FPGA,微信公眾號(hào):pdh的FPGA】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
評(píng)論