在做FPGA图像处理时,可以先用testbench仿真。
这时,tb需要一个激励,也就是图像。这个图像也可从电脑中的文件读取出来。
但是Altera的ROM支持mif文件,Xilinx只支持coe文件,他们都不支持图片文件,如:png、jpg、gif等。
Tcl脚本的Tk库提供了读取png图片的命令。
那么,我们可以使用Tcl脚本把png图片转成mif或coe文件,让FPGA从ROM中读出,再经过算法处理。
先介绍该脚本如何使用,再给出源代码。
1、设置图片。
把文件名设置好,该png图片需要和该Tcl脚本处于同一目录下。
由于Tcl脚本给出的命令只支持png和gif文件,所以,这里使用png图片。
2、设置输出文件。
outMifCoe为1时,输出mif文件。outMifCoe为其它值时,输出coe文件。
3、其它问题。
若图片像素不足2的N次方时,该Tcl脚本会自动填充0。
一个像素为24位宽的16进制数。只输出16进制的mif或coe文件。
该脚本需要用TK解释器也就是wish.exe,因为只有TK才有读取图片的命令,而TCL没有。
如果使用sublime编译器,可以使用以下编译命令(具体路径需要视wish的安装目录而定)。
{
"cmd": ["C:\\Tcl\\bin\\wish.exe", "${file_path}/${file_name}"],
"file_regex": "^(..[^:]*):([0-9]+):?([0-9]+)?:? (.*)$",
"selector": "source.tcl, source.TCL"
}
以下为该脚本的源代码。
# use tk compile to run this tk script
# this tk script converts .png or .gif to .mif or .coe
set fileName "test.png"
# outMifCoe = 1,output .mif; outMifCoe = others,output .coe;
set outMifCoe 1
#log2() function
namespace eval math {
proc log2 {x} {
set i 0
while {$x > 1} {
set x [expr $x/2]
incr i
}
return $i
}
}
# get .png rgb info
set img [image create photo -file $fileName]
set imgWidth [image width $img]
set imgHeight [image height $img]
set pixel [expr $imgHeight * $imgWidth]
set exp [math::log2 $imgWidth*$imgHeight]
set depth [expr 2**[expr $exp+1]]
proc pic2mif {} {
global depth img imgWidth imgHeight pixel
set content "DEPTH = $depth;\nWIDTH = 24;\nADDRESS_RAIDX = HEX;\nDATA_RADIX = HEX;\n"
append content "CONTENT\nBEGIN\n"
for {set x 0} {$x < $imgWidth} {incr x} {
for {set y 0} {$y < $imgHeight} {incr y} {
set color [$img get $x $y]
#change data to hex
set rgb [format {%02x%02x%02x} {*}$color]
set i [expr $x*$imgHeight + $y]
set hex_i [format "%X" $i]
#print address and data
append content "$hex_i : $rgb;\n"
}
}
# fill zero
if {$depth > $pixel} {
for {set i $pixel} {$i < $depth} {incr i} {
set hex_i [format "%X" $i]
#print address and data
append content "$hex_i : 0;\n"
}
}
append content "END ;\n"
#create mif and write content into it
set fd [open [pwd]/pic.mif w+]
puts $fd $content
close $fd
}
proc pic2coe {} {
global depth img imgWidth imgHeight pixel
set content "MEMORY_INITIALIZATION_RADIX=16;\n"
append content "MEMORY_INITIALIZATION_VECTOR="
for {set x 0} {$x < $imgWidth} {incr x} {
for {set y 0} {$y < $imgHeight} {incr y} {
set color [$img get $x $y]
#change data to hex
set rgb [format {%02x%02x%02x} {*}$color]
set i [expr $x*$imgHeight + $y]
#print address and data
if {$i == [expr $depth - 1]} {
append content "$rgb"
} else {
append content "$rgb,"
}
}
}
# fill zero
if {$depth > $pixel} {
for {set i $pixel} {$i < $depth} {incr i} {
if {$i == [expr $depth - 1]} {
append content "0"
} else {
append content "0,"
}
}
}
append content ";\n"
set fd [open [pwd]/pic.coe w+]
puts $fd $content
close $fd
}
if {$outMifCoe==1} {
pic2mif
} else {
pic2coe
}