首页 | 新闻 | 新品 | 文库 | 方案 | 视频 | 下载 | 商城 | 开发板 | 数据中心 | 座谈新版 | 培训 | 工具 | 博客 | 论坛 | 百科 | GEC | 活动 | 主题月 | 电子展
返回列表 回复 发帖

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

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;
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
继承事业,薪火相传
返回列表