定点数乘累加器的 MATLAB 模拟

大致题意

为实现 FPGA 上的信号处理,通常要经过算法的设计,算法的定点化以及顶点算法的实现三个步骤。这里要实现定点数乘累加器的第二阶段设计——用 MATLAB 设计算法的定点化。

s u m = ∑ i a i b i sum=\sum_{i}a_{i} b_{i} sum=iaibi

MATLAB 的仿真结果要与 HDL 模拟结果一致,即模拟出的定点数能够与算法在硬件中实现后的对应信号在每个bit 上都匹配(bit-true)。

Fixed-Point Designer 工具可以高效的进行算法的定点化设计。用Fixed-PointDesigner工具来描述定点数,每一个定点数都是一个 fi 对象;“定点格式”用 numerictype 对象给出;而定点数之间的运算规则,对应的是 fimath 对象。

乘累加器类

支持自定义输入输出的定点数格式,且在溢出发生后饱和处理,并模拟电路复位的过程,以保证其持续工作。通过字符串修改操作数的 hex 属性完成对操作数实数值的修改。定点数运算同时在乘累加器内部进行一致的浮点数运算,以方便观察定点数与浮点数结果差异以及引入的噪声。

classdef fixed_mac < handle
    % Mutiply accumulator that support fixed point number    
    properties
        a;
        b;
        res;
        ref_res;
        F;
    end
    
    methods
        function obj = fixed_mac(din_a_numerictype, din_b_numerictype, ...
                dout_numerictype)
            %Construct
            obj.F = fimath('RoundingMethod', 'Floor', ...
                'SumMode', 'SpecifyPrecision', ...
                'SumWordLength', dout_numerictype.WordLength, ...
                'SumFractionLength', ...
                dout_numerictype.FractionLength);
            obj.a = fi(0, din_a_numerictype);
            obj.b = fi(0, din_b_numerictype);
            obj.res = fi(0, dout_numerictype, obj.F);
            obj.ref_res = 0;
        end
        
        function mul_ac(obj, hex_a, hex_b)
            % Simulate a reset clock
            if(obj.res.double == 7.9375 || obj.res.double == -8)
                obj.res.double = 0;
                obj.ref_res = 0;
            else
                % Multiply and accumulate
                obj.a.hex = hex_a;
                obj.b.hex = hex_b;
                obj.res = obj.res + fi(obj.a * obj.b, obj.F);
                obj.ref_res = obj.ref_res + obj.a.double * obj.b.double;
            end
        end
        
        function [dout_hex, dout, ref_dout] = output(obj)
            %Print the result of fixed_mac
            dout_hex = obj.res.hex;
            dout = obj.res.double;
            ref_dout = obj.ref_res;
        end
    end
end
testbench

定义输入输出的定点数格式,通过读取 txt 文件的数据模拟乘累加器模块的输入信号。din_a, din_b 算术操作完成后同步打印结果(实际输入输出相差一个时钟),绘制定点数与浮点数结果曲线并分析信噪比。

clear all;
Ta = numerictype(0, 7, 3);
Tb = numerictype(1, 5, 7);
Tr = numerictype(1, 8, 4);
% Create a fixed_mac object
mac = fixed_mac(Ta, Tb, Tr);
% Open a txt file to read data
fid = fopen('test_data.txt');

% Multiply and accumulate synchronously
i = 1;
while 1
    tline1 = fgetl(fid);
    % Determine whether input is character array
    if ~ischar(tline1), break, end
    % The file has one empty line every 14 hex numbers
    if tline1 == "", continue, end
    tline2 = fgetl(fid);
    if ~ischar(tline2), break, end
    % Simulate multiply and accumulate in fixed_number 
    mac.mul_ac(tline1, tline2);
    [res_hex, res(i), ref_res(i)] = mac.output();
    i = i + 1;
    disp(['din_a = ' tline1 ', din_b = ' tline2 ', Dout = ' res_hex]);
end

% Print dout, ref_dout
plot([res', ref_res']);
title('fixed_mac dout & ref dout');
legend('fixed mac dout', 'ref dout');

% Calculate the SNR
err = res - ref_res;
err_energy = err * err';
ref_energy = ref_res * ref_res';
snr_db = 10 * log10(ref_energy / err_energy)
数据格式

70
0F
72
0F
74
0F
76

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值