从Matlab到FPGA(Matlab生成coe文件或mem文件)
2018-03-22 14:38
330 查看
当定点仿真完成后,就需要使用FPGA实现。
这时候需要把之前仿好的滤波器参数或者输入信号输出为coes文件:%% output coe file
Ff = fimath('CastBeforeSum', 0, 'OverflowMode', 'Saturate', ...
'RoundMode', 'round', 'ProductMode', 'SpecifyPrecision', 'SumMode', 'SpecifyPrecision', ...
'ProductWordLength', 16, 'ProductFractionLength', 15, 'SumWordLength', 16, 'SumFractionLength', 15);
Tf = numerictype('WordLength', 16, 'FractionLength', 15);
wr = 'ram'; % select the output type
outset = fi(hmc.Numerator, Tf, Ff); % the filter need to be outputted, datatype:fi
outset_len = length(outset);
fp = fopen('D:\tmp\fpga_matlab\FIR.coe','w');
if( strcmp(wr, 'ram') )
fprintf( fp, 'MEMORY_INITIALIZATION_RADIX=16;\n' );
fprintf( fp, 'MEMORY_INITIALIZATION_VECTOR=\n' );
elseif( strcmp(wr, 'fir') )
fprintf( fp, 'radix=10;\n' );
fprintf( fp, 'coefdata=\n' );
end
for i = 1:outset_len
out = outset(i);
if( strcmp(wr, 'ram') )
out_r = real(out); %ram
out_i = imag(out);
fprintf(fp, '%s%s\n', out_i.hex, out_r.hex);
elseif( strcmp(wr, 'fir') )
out = outset(i); %fir
fprintf(fp, '%.17f\n', out);
end
end
fclose(fp);由于滤波器在仿真中一个结构体,所以把里面的参数变成fi对象,这样可以很方便输出十六进制或者二进制之类。
这里代码还提供了RAM的coe文件输出的选择。
这样,使用IP核的时候就可以把这些文件拖进去。
也可以使用原语的方式实现RAM,这样可以很方便地移植代码,如下:xpm_memory_sdpram # (
// Common module parameters
.MEMORY_SIZE (4096), //positive integer
.MEMORY_PRIMITIVE ("auto"), //string; "auto", "distributed", "block" or "ultra";
.CLOCKING_MODE ("common_clock"), //string; "common_clock", "independent_clock"
.MEMORY_INIT_FILE (file), //string; "none" or "<filename>.mem"
.MEMORY_INIT_PARAM ("" ), //string;
.USE_MEM_INIT (1), //integer; 0,1
.WAKEUP_TIME ("disable_sleep"), //string; "disable_sleep" or "use_sleep_pin"
.MESSAGE_CONTROL (0), //integer; 0,1
.ECC_MODE ("no_ecc"), //string; "no_ecc", "encode_only", "decode_only" or "both_encode_and_decode"
.AUTO_SLEEP_TIME (0), //Do not Change
// Port A module parameters
.WRITE_DATA_WIDTH_A (16), //positive integer
.BYTE_WRITE_WIDTH_A (16), //integer; 8, 9, or WRITE_DATA_WIDTH_A value
.ADDR_WIDTH_A (8), //positive integer
// Port B module parameters
.READ_DATA_WIDTH_B (16), //positive integer
.ADDR_WIDTH_B (8), //positive integer
.READ_RESET_VALUE_B ("0"), //string
.READ_LATENCY_B (2), //non-negative integer
.WRITE_MODE_B ("no_change") //string; "write_first", "read_first", "no_change"
) xpm_memory_sdpram_inst (
// Common module ports
.sleep (1'b0),
// Port A module ports
.clka (clk),
.ena (1'b1),
.wea (enw),
.addra (waddr),
.dina (wdata),
.injectsbiterra (
4000
1'b0),
.injectdbiterra (1'b0),
// Port B module ports
.clkb (clk),
.rstb (1'b0),
.enb (1'b1),
.regceb (1'b1),
.addrb (raddr),
.doutb (rdata),
.sbiterrb (),
.dbiterrb ()
);这样就例化了一个读写RAM
这里RAM的初始化数据是mem文件,可以用如下Matlab代码输出:outset = [0;ER1];
outset = fi(outset, T, F); % the filter need to be outputted, datatype:fi
outset_len = length(outset);
fp = fopen('D:\tmp\fpga_matlab\ER1.mem','w');
for i = 1:outset_len
out = outset(i);
fprintf(fp, '@%04x %04x\n', (i-1), out.int);
end
fclose(fp);使用Verilog测试时,需要读取txt文件的数据输入仿真的模块,并把输出的数据保存到txt再用Matlab读取出来分析,Matlab侧输出数据到txt的代码如下:%% output fi object
outset = RR;%fi(Tx, T, F); % the filter need to be outputted, datatype:fi
outset_len = length(outset);
% if(outset_len>10000)
% outset_len = 10000;
% end
fp = fopen('D:\tmp\fpga_matlab\Tx.txt','w');
for i = 1:outset_len
out = outset(i);
r_out = real(out);
i_out = imag(out);
fprintf(fp, '%s %s\n', r_out.dec, i_out.dec);
end
fclose(fp);Matlab侧读取txt的代码为:%% input fi object
fp = fopen('D:\tmp\fpga_matlab\Rx.txt','r');
in = textscan(fp, '%s');
fclose(fp);
ins = in{1,1};
in_l = length(ins);
rx = zeros( in_l/2, 1 );
for i = 1:2:in_l
in_r = str2double(ins{i});
in_i = str2double(ins{i+1});
rx( (i+1)/2 ) = in_r/(2^14) + 1j*in_i/(2^14);
end对应的verilog代码如下:
这时候需要把之前仿好的滤波器参数或者输入信号输出为coes文件:%% output coe file
Ff = fimath('CastBeforeSum', 0, 'OverflowMode', 'Saturate', ...
'RoundMode', 'round', 'ProductMode', 'SpecifyPrecision', 'SumMode', 'SpecifyPrecision', ...
'ProductWordLength', 16, 'ProductFractionLength', 15, 'SumWordLength', 16, 'SumFractionLength', 15);
Tf = numerictype('WordLength', 16, 'FractionLength', 15);
wr = 'ram'; % select the output type
outset = fi(hmc.Numerator, Tf, Ff); % the filter need to be outputted, datatype:fi
outset_len = length(outset);
fp = fopen('D:\tmp\fpga_matlab\FIR.coe','w');
if( strcmp(wr, 'ram') )
fprintf( fp, 'MEMORY_INITIALIZATION_RADIX=16;\n' );
fprintf( fp, 'MEMORY_INITIALIZATION_VECTOR=\n' );
elseif( strcmp(wr, 'fir') )
fprintf( fp, 'radix=10;\n' );
fprintf( fp, 'coefdata=\n' );
end
for i = 1:outset_len
out = outset(i);
if( strcmp(wr, 'ram') )
out_r = real(out); %ram
out_i = imag(out);
fprintf(fp, '%s%s\n', out_i.hex, out_r.hex);
elseif( strcmp(wr, 'fir') )
out = outset(i); %fir
fprintf(fp, '%.17f\n', out);
end
end
fclose(fp);由于滤波器在仿真中一个结构体,所以把里面的参数变成fi对象,这样可以很方便输出十六进制或者二进制之类。
这里代码还提供了RAM的coe文件输出的选择。
这样,使用IP核的时候就可以把这些文件拖进去。
也可以使用原语的方式实现RAM,这样可以很方便地移植代码,如下:xpm_memory_sdpram # (
// Common module parameters
.MEMORY_SIZE (4096), //positive integer
.MEMORY_PRIMITIVE ("auto"), //string; "auto", "distributed", "block" or "ultra";
.CLOCKING_MODE ("common_clock"), //string; "common_clock", "independent_clock"
.MEMORY_INIT_FILE (file), //string; "none" or "<filename>.mem"
.MEMORY_INIT_PARAM ("" ), //string;
.USE_MEM_INIT (1), //integer; 0,1
.WAKEUP_TIME ("disable_sleep"), //string; "disable_sleep" or "use_sleep_pin"
.MESSAGE_CONTROL (0), //integer; 0,1
.ECC_MODE ("no_ecc"), //string; "no_ecc", "encode_only", "decode_only" or "both_encode_and_decode"
.AUTO_SLEEP_TIME (0), //Do not Change
// Port A module parameters
.WRITE_DATA_WIDTH_A (16), //positive integer
.BYTE_WRITE_WIDTH_A (16), //integer; 8, 9, or WRITE_DATA_WIDTH_A value
.ADDR_WIDTH_A (8), //positive integer
// Port B module parameters
.READ_DATA_WIDTH_B (16), //positive integer
.ADDR_WIDTH_B (8), //positive integer
.READ_RESET_VALUE_B ("0"), //string
.READ_LATENCY_B (2), //non-negative integer
.WRITE_MODE_B ("no_change") //string; "write_first", "read_first", "no_change"
) xpm_memory_sdpram_inst (
// Common module ports
.sleep (1'b0),
// Port A module ports
.clka (clk),
.ena (1'b1),
.wea (enw),
.addra (waddr),
.dina (wdata),
.injectsbiterra (
4000
1'b0),
.injectdbiterra (1'b0),
// Port B module ports
.clkb (clk),
.rstb (1'b0),
.enb (1'b1),
.regceb (1'b1),
.addrb (raddr),
.doutb (rdata),
.sbiterrb (),
.dbiterrb ()
);这样就例化了一个读写RAM
这里RAM的初始化数据是mem文件,可以用如下Matlab代码输出:outset = [0;ER1];
outset = fi(outset, T, F); % the filter need to be outputted, datatype:fi
outset_len = length(outset);
fp = fopen('D:\tmp\fpga_matlab\ER1.mem','w');
for i = 1:outset_len
out = outset(i);
fprintf(fp, '@%04x %04x\n', (i-1), out.int);
end
fclose(fp);使用Verilog测试时,需要读取txt文件的数据输入仿真的模块,并把输出的数据保存到txt再用Matlab读取出来分析,Matlab侧输出数据到txt的代码如下:%% output fi object
outset = RR;%fi(Tx, T, F); % the filter need to be outputted, datatype:fi
outset_len = length(outset);
% if(outset_len>10000)
% outset_len = 10000;
% end
fp = fopen('D:\tmp\fpga_matlab\Tx.txt','w');
for i = 1:outset_len
out = outset(i);
r_out = real(out);
i_out = imag(out);
fprintf(fp, '%s %s\n', r_out.dec, i_out.dec);
end
fclose(fp);Matlab侧读取txt的代码为:%% input fi object
fp = fopen('D:\tmp\fpga_matlab\Rx.txt','r');
in = textscan(fp, '%s');
fclose(fp);
ins = in{1,1};
in_l = length(ins);
rx = zeros( in_l/2, 1 );
for i = 1:2:in_l
in_r = str2double(ins{i});
in_i = str2double(ins{i+1});
rx( (i+1)/2 ) = in_r/(2^14) + 1j*in_i/(2^14);
end对应的verilog代码如下:
integer fp_r, fp_w, cnt, r_n, w_n; // read data initial begin fp_r = $fopen("D:/tmp/fpga_matlab/Tx1.txt", "r"); r_n = 0; s_axis_data_tvalid = 0; s_axis_data_tdata = 0; wait(rst_n==1); @(posedge clk) while(!$feof(fp_r)) begin #1 cnt = $fscanf(fp_r, "%d %d", data_in_I, data_in_Q); r_n = r_n + 1; s_axis_data_tdata = { data_in_Q[15:0], data_in_I[15:0] }; s_axis_data_tvalid = 1; @(posedge clk); #1 s_axis_data_tvalid = 0; #(1*PERIOD); end s_axis_data_tvalid = 0; s_axis_data_tdata = 0; $fclose(fp_r); end // write data initial begin fp_w = $fopen("D:/tmp/fpga_matlab/Tx2_fpga.txt","w");//以写的方式打开文件 w_n = 0; @(posedge m_axis_data_tvalid) while(m_axis_data_tvalid) begin @(posedge clk) data_out_I = m_axis_data_tdata[15:0]; data_out_Q = m_axis_data_tdata[31:16]; $fwrite(fp_w,"%d %d\n", $signed(data_out_I), $signed(data_out_Q)); w_n = w_n + 1; end $fclose(fp_w); end
相关文章推荐
- 使用matlab生成rom初始化文件.coe
- Matlab生成Xilinx Rom IP CORE的初始化内容coe文件
- 手把手教你,借助matlab,如何制作Xilinx的coe文件
- 各种软核处理器二进制文件FPGA初始化文件生成程序
- matlab生成二值图像,m文件的使用
- [FPGA][Quartus]代码保护-生成网表文件
- matlab练习程序(生成加密p文件)
- matlab生成VS可调用的dll文件
- matlab生成C++文件mcc命令
- matlab 生成EXE文件命令
- 生成和导入Xilinx ROM/RAM的初始化文件.COE(ZT)
- matlab生成可执行文件
- matlab生成vs可以调用文件 的输入命令
- c++与matlab联合编程,调用Deploytool 生成exe文件和dll文件
- matlab的excel的读和写(生成脚本m文件)
- matlab生成opencv需要的xml文件
- MATLAB读取txt文件,批量生成txt文件
- Matlab生成视频文件
- 用MATLAB编写VIVADO的coe文件
- MATLAB生成正态样本以及正态矩阵、从文件读入矩阵