通过matlab对verilog中无符号数、有符号数进行转化
转自:http://hojze.blog.163.com/blog/static/10637396520104472146566/
在FPGA 设计过程中经常会遇到关于数表示之间的转化问题,最常见的是无符号数和有符号数之间的转化问题。
(1)在FPGA设计过程中,能够很直接的看出数字的位宽,但经常以无符号数的形式输出,在后继的处理中往往要将之转化为有符号数(如:计算频谱):
对于一个比特宽度为W的有符号数,其值往往可以表示为(令W = 4):
-1*b3*2^3 + b2*2^2 + b1*2^1 + b0*2^0
根据这一原理,给出以下Matlab 代码:
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function [b] = unsigned2signed(da
%This fuction covert an unsigned da
%width.The input matrix should be positive.
%Example:unsign2signed([0:3],2),return ans = [0 1 -2 -1];
da
sign_mask = 2^(width-1);
da
%
da
da
%
b = da
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
同
%设数据位宽为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_da
out_da
input [15 : 0] in_da
output out_da
reg temp;
always @(in_da
begin
{temp,out_da
end
endmodule
///////////////////Testbench///////////////////////////////
`timescale 1ns/1ps
module tb_inv_test;
parameter CYC = 10;
reg [15 : 0] in_da
wire[15 : 0] out_da
inv_test uut(.in_da
.out_da
integer cnt;
initial
begin
in_da
#(CYC);
for(cnt = 1; cnt <100; cnt = cnt + 1)
begin
in_da
#(CYC);
end
for(cnt = 16'h8000; cnt < 16'h8100; cnt = cnt + 1)
begin
in_da
#(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;
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%