在FPGA 設計過程當中常常會遇到關於數表示之間的轉化問題,最多見的是無符號數和有符號數之間的轉化問題。
(1)在FPGA設計過程當中,可以很直接的看出數字的位寬,但常常以無符號數的形式輸出,在後繼的處理中每每要將之轉化爲有符號數(如:計算頻譜):
對於一個比特寬度爲W的有符號數,其值每每能夠表示爲(令W = 4):
-1*b3*2^3 + b2*2^2 + b1*2^1 + b0*2^0
根據這一原理,給出如下Matlab 代碼:
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function [b] = unsigned2signed(data, width)
%This fuction covert an unsigned data into a signed data with bit width ==
%width.The input matrix should be positive.
%Example:unsign2signed([0:3],2),return ans = [0 1 -2 -1];
data_size = size(data);
sign_mask = 2^(width-1);
data_mask = ones(data_size)*sign_mask;
%
data_sign = -1*bitand(data_mask,data);
data_remainder = bitand((data_mask - 1),data);
%
b = data_sign + data_remainder;
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
同時根據補碼的原理,也能夠用幾句簡單的語句表示:
%設數據位寬爲4,1位符號位,數據矩陣爲a
a(find(a>= 2^3)) = a(find(a>= 2^3)) -2^4;
以上能夠當作先將負數找出,先除去符號位(減去2^3)獲得相應的負數的補碼,再加上符號表明的意義-1*2^3,
即總共減去2^4.
(2)在FPGA設計中可能會遇到要將數值求相反數,對應的硬件描述數語言可表示爲:
/////////////////HDL///////////
`timescale 1ns/1ps
module inv_test(in_data,
out_data);
input [15 : 0] in_data;
output out_data; reg[15 : 0] out_data;
reg temp;
always @(in_data)
begin
{temp,out_data} = {{1'b1},{16'd0}} - in_data;
end
endmodule
///////////////////Testbench///////////////////////////////
`timescale 1ns/1ps
module tb_inv_test;
parameter CYC = 10;
reg [15 : 0] in_data;
wire[15 : 0] out_data;
inv_test uut(.in_data(in_data),
.out_data(out_data));
integer cnt;
initial
begin
in_data = 0;
#(CYC);
for(cnt = 1; cnt <100; cnt = cnt + 1)
begin
in_data = cnt;
#(CYC);
end
for(cnt = 16'h8000; cnt < 16'h8100; cnt = cnt + 1)
begin
in_data = cnt;
#(CYC);
end
$stop;
end
endmodule
/////////////////////////////////////////////////////
注意因爲正負的不對稱性,在16‘h8000處對應的正數會溢出。
(3)在寫入測試數據時,可能會用到要將有符號數轉成無符號數表示的狀況,跟據(1)的描述能夠很快地寫出其Matlab代碼:
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function b = signed2unsigned(a,wl);
%This function covert an signed integer number into an unsinged integer
%number. a is the input vector while wl means the width of input number;
%Example: a = [-2,-1,0,1];
%signed2unsigned(a,3); THEN return [2,3,0,1]
k = 2^(wl)*(a<0);
b = k + a;
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%測試