matlab和FPGA中无符号数和有符号数的转化,转

在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;

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%