前言
本人想使用簡單的中值濾波進行verilog相關算法的硬件實現,由於HDL設計軟件不能直接處理圖像,大部分過程都是可以將圖像按照一定的順序保存到TXT文檔中,經過Modelsim仿真后,處理的數據再經過matlab顯示圖像;圖像首先通過matlab或者C語言保存在TXT文檔中,生成測試向量文件,然后在仿真軟件中進行仿真處理,把處理后的數據保存為TXT格式,最后用matlab顯示,觀察結果。一般都是先創建MIF文件,將圖像中的像素信息用一個ROM儲存起來,然后調用ROM里面的地址進行處理,相當於制作了一個ROM查找表。
用Quartus II創建並仿真ROM的步驟:
1.在Quatus工程下生成一個ROM
2.編寫.mif文件,作為ROM的初始化文件
3.將.mif文件拷貝到Modelsim工程下
4.進行Modelsim仿真
圖像保存的步驟:
1.使用matlab將圖像生成txt文。
%將256位的BMP灰度圖像128*128大小生成TXT文檔,再生成mif文件;
clc
clear all
close all
I_rgb = imread('lena.jpg');
subplot(2, 2, 1), imshow(I_rgb), title('lena-rgb')
I_gray = rgb2gray(I_rgb);
subplot(2, 2, 2), imshow(I_gray), title('lena-gray')
I = imresize(I_gray, 0.25);
subplot(2, 2, 3), imshow(I), title('lena-qtr')
fid = fopen('./lena.txt','wt');
for i = 1 : size(I, 1)
for j = 1 : size(I, 2)
fprintf(fid, '%d ', I(i, j));%每個數據之間用空格分開%
end
fprintf(fid, '\n');
end
fid = fclose(fid);
I_data = load('./lena.txt');
2.創建mif文件(Memory Initialization File):使用mif生成器、C語言或者matlab語言來生成;
選擇直接使用matlab生成mif文件gray_image.mif;
%mcode to create a mif file
src = imread('lena.jpg');
gray = rgb2gray(src);
[m,n] = size( gray ); % m行 n列
N = m*n; %%數據的長度,即存儲器深度。
word_len = 8; %%每個單元的占據的位數,需自己設定
data = reshape(gray', 1, N);% 1行N列
%fid=fopen('gray_image.mif', 'w'); %打開文件
fid=fopen('gray_image.mif', 'w'); %打開文件
fprintf(fid, 'DEPTH=%d;\n', N);
fprintf(fid, 'WIDTH=%d;\n', word_len);
fprintf(fid, 'ADDRESS_RADIX = UNS;\n'); %% 指定地址為十進制
fprintf(fid, 'DATA_RADIX = HEX;\n'); %% 指定數據為十六進制
fprintf(fid, 'CONTENT\t');
fprintf(fid, 'BEGIN\n');
for i = 0 : N-1
fprintf(fid, '\t%d\t:\t%x;\n',i, data(i+1));
end
fprintf(fid, 'END;\n'); %%輸出結尾
fclose(fid); %%關閉文件
生成的mif文件如下圖所示:
3.調用mif文件生成ROM(verilog文件即.v文件)
這個是Altera的方法,因為本人電腦上只安裝了Xilinx軟件,所以這一步沒有進行實際操作。
使用Xilinx創建並仿真ROM的步驟:
1.編寫.coe文件,作為ROM的初始化文件,.coe文件的格式和內容如代碼所示:
%mcode to create a coe file
%生成的數據是一行行進行讀取的
src = imread('lena.jpg');
gray = rgb2gray(src);
[m,n] = size( gray ); % m行 n列
N = m*n; %%數據的長度,即存儲器深度。
word_len = 8; %%每個單元的占據的位數,需自己設定
data = reshape(gray', 1, N);% 1行N列
%fid=fopen('gray_image.mif', 'w'); %打開文件
fid=fopen('lena.coe', 'wt'); %打開文件
fprintf(fid, 'MEMORY_INITIALIZATION_RADIX=16;\n');
fprintf(fid, 'MEMORY_INITIALIZATION_VECTOR=\n');
for i = 1 : N-1
fprintf(fid, '%x,\n', data(i));%使用%x表示十六進制數
end
fprintf(fid, '%x;\n', data(N)); %%輸出結尾,每個數據后面用逗號或者空格或者換行符隔開,最后一個數據后面加分號
fclose(fid); %%關閉文件
2.生成的.coe文件格式如下圖所示:
3.使用Xilinx中的Core Generator完成ROM的例化(生成的.coe文件的圖像數據是一行行進行讀取的)。
打開ISE,右鍵單擊New Source,如下圖所示:
單擊之后選擇IP_Core_Generator,
單擊Next選項,選擇Memories&Storage Elements->RAMs&ROMs->,選擇塊式存儲或者分布式存儲(這里根據存儲數據的大小進行選擇,較小的可以選擇塊式存儲)。
點擊Next,然后Finish。然后就出現了下面的界面,一直點擊Next進行ROM屬性的一些設置,直至完成:
然后就要選擇所需要的ROM的大小
portA 表示輸出要不要時鍾打拍輸出,這個是在mux里實現的;
在添加初始化文件的時候,將之前matlab生成的.coe文件添加到ROM IP核中去。
一直next下去,就可以得到初始化好的ROM IP核,可以在./ipcore_dir目錄下查看ROM文件,從而可以在頂層模塊中對ROM進行例化。
生成的ROM文件的輸入輸出變量如下:
modulerom_512by512(
clka,
addra,
douta
);inputclka;input [17 : 0] addra;output [7 : 0] douta;
View Code
在頂層模塊中對ROM進行例化如下:
wire [7:0] rom_data;wire [17:0] rom_addr;
rom_512by512 U1
(
.clka(CLK),//input clka;
.addra( rom_addr), //input
.douta(rom_data) //output
);
View Code
4.使用CoreGenerator完成ROM的例化后會生成一個.mif文件,這是Modelsim進行ROM仿真時需要的初始化文件,將.mif文件復制到Modelsim工程下進行仿真。
5.查看ROM模塊中的初始化數據,雙擊Rom模塊,出現如下圖的界面,點擊show按鈕,即可查看數據;
完