XU.J.P

利用matlab进行ROM初始化mif文件方法

0
阅读(4893)

工具使用版本:Quartus II 13.0+Matlab2012d

撰写人:Strive_JP

关于FPGA中ROM初始化,最近学会了利用matlab强大的数据处理能力来初始化ROM当中的数据。

先简单介绍下FPGA内部的RAM。这里为了简单起见,以EP4CE10为例,先来看下资源情况。

EP4CE10内部有414Kbits的存储容量。有EP4CE10的片内存储器内存为M9K。这样,可以计算出EP4CE10内部的M9K有46片。再看看handbook里面介绍的配置特性。

由上图可以看出FPGA虽然内部拥有一定数量的M9K,但配置深度和配置位宽均有一定的限制。

介绍完上述那些,言归正传,这里提出一种利用matlab文件来初始化ROM内部数据的方式,即对.mif文件进行配置。

假设一组图像数据,现在想将其写入ROM中,以供后续的工程调用。图像数据保存在.txt文件中,格式类型如下所示:

这里只显示了部分图像数据,实际数据有几千上万行。咋办?总不能一点点地敲入ROM的初始化文件中去吧。别人介绍的软件处理方法也没提过这种情况。这时候,想到是否可以利用matlab强大的数据处理能力,来对.txt文件进行处理,再修改为.mif文件保存后直接让quartusII读取呢。

思路是有了,接下来看看一个可供quartusII识别的.mif文件内部是什么结构。此时以txt文档打开一个简单配置完成的文件来看看。

.mif文件中的内容包括以下几个重要方面:

WIDTH=8; //数据位宽为8

DEPTH=256; //存储深度为256

ADDRESS_RADIX=UNS; //地址类型为无符号整型

DATA_RADIX=UNS; //数据类型为无符号整型

CONTENT BEGIN

0:1; //地址0的存储器内容为1

1:3; //地址为1的存储器内容的3

[2:255]:0;//地址为2~255的存储器内容为0

END;

这样,即可利用matlab构造类似的文件存储方式。利用matlab将上述的图像数据转换成.mif。代码如下所示:

clear; clc; close all; fid=fopen('data_8bits.txt');%打开待转换数据的.txt文件 temp=fscanf(fid,'%x');%扫描文件 n=1024; fid=fopen('convert_data.mif','w');%打开待写入的.mif文件 fprintf(fid,'WIDTH=8;\n');%写入存储位宽8位 fprintf(fid,'DEPTH=1024;\n');%写入存储深度1024 fprintf(fid,'ADDRESS_RADIX=UNS;\n');%写入地址类型为无符号整型 fprintf(fid,'DATA_RADIX=HEX;');%写入数据类型为16进制 fprintf(fid,'CONTENT BEGIN\n');%起始内容 for i=0:n-1 fprintf(fid,'\t%d:%x;\n',i,temp(i+1));
        
end fprintf(fid,'END;\n'); fclose(fid);%关闭文件

这样将data_8bits.txt文件转换后文件convert_data.mif打开后以及利用quartusII打开.mif文件如下所示:

完全没有任何问题。

针对这种.txt文档其实更直接的方法是采用EXCEL表,将数据做成符合.mif文件格式。这样或许也会比较简单。

除此以外,针对某些算法,同样也可以用matlab仿真,然后生成.mif文件在FPGA当中做算法处理。例如,通常的gamma矫正。借鉴黑金里面的范例,来简单说明下。

剔除那些必要的描述,这里直接列出gamma矫正的公式:


利用matlab来进行代码验证,之后再生产.mif文件,代码如下所示:

x=0:1:255; y=uint8(256*((x/256).^(0.95)));%gamma = 0.95 fid=fopen('gamma_data.txt','wt+'); fprintf(fid,'WIDTH=8;\n'); fprintf(fid,'DEPTH=256;\n'); fprintf(fid,'ADDRESS_RADIX=UNS;\n'); fprintf(fid,'DATA_RADIX=UNS;'); fprintf(fid,'CONTENT BEGIN\n'); for i = 0 : 255 fprintf(fid,'\t%d : %d;\n',i,y(i+1)); end fprintf(fid,'END;\n'); fclose(fid); plot(x,y);

生成的ROM内部初始化文件.mif,将地址作为输入数据,相应的内容作为gamma矫正后的像素值。这样即可完成gamma矫正。这Bingo的开发板平台上,编写verilog代码如下:

`timescale 1ns/1ns module gamma ( input clk, input rst_n, input per_frame_vsync, input per_frame_href, input per_frame_clken, input [7:0] per_img_data, output post_frame_vsync, output post_frame_href, output post_frame_clken, output [7:0] post_img_data, ); wire [7:0] img_data Ram256_8_gamma_data ram256_8_gamma_data_rom( .data (), .rdaddress (per_img_data), .rdclock (clk), .wraddress (), .wrclock (), .wren (), .q (img_data) ); reg [1:0] per_frame_vsync_r; reg [1:0] per_frame_href_r; reg [1:0] per_frame_clken_r; always@(posedge clk or negedge rst_n) begin if(!rst_n) begin per_frame_vsync_r <= 0; per_frame_href_r <= 0; per_frame_clken_r <= 0; end else begin per_frame_vsync_r <= {per_frame_vsync_r[0], per_frame_vsync}; per_frame_href_r <= {per_frame_href_r[0], per_frame_href}; per_frame_clken_r <= {per_frame_clken_r[0], per_frame_clken}; end end assign post_frame_vsync = per_frame_vsync_r[1]; assign post_frame_href = per_frame_href_r[1]; assign post_frame_clken = per_frame_clken_r[1]; assign post_img_data = post_frame_href ? img_data : 8'd0; endmodule

这样的思想我不知道是否正确,因为从实验结果显示的图像来看,效果很差,实在难以理解,希望哪天有人能和我详细讲解下。

事实证明,采用以上方法做gamma矫正,会破坏图像的相关度。是不行滴,找时间试试对RGB转换成YCRCB图像,对亮度信息做gamma矫正。





Baidu
map