我正在Verilog的CNN项目上工作,但是我在使用3x3过滤器实现Image的卷积过程时遇到了一些问题。我为卷积模块编写了一个代码,但现在谈到卷积时,我必须从内存中读取值,其中包含图像的像素。问题是我必须按特定顺序读取这些值,因为卷积采用2个矩阵的点积,然后向右移动1。因此,如果图像是存储在存储器阵列中的5x5矩阵,那就让我们说吧
[a1 a2 a3 a4 a5
a6 a7 a8 a9 a10
a11 a12 a13 a14 a15] - 记忆Ram
如何按以下顺序读取内存值: a1然后a2然后是a3,然后是a6然后a7然后a8,最后一行a11 a12 a13,然后从a2,a3等开始跨步并重新开始直到我到达我的数组的末尾。请建议在这种情况下如何处理内存的任何解决方案,代码片段将受到高度赞赏。谢谢。
P.S。我的内存数组将包含大量数据,大约将是[400x300]的矩阵,其中过滤器为[3x3]。
答案 0 :(得分:1)
看起来像嵌套for循环的简单情况。这可以根据需要遍历16项内存:
for (start=0; start<3; start=start+1)
for(i=1; i<16; i=i+5)
for (j=0; j<3; j=j+1)
data = mem[start+i+j]; // C: printf("%d\n",start+i+j);
请注意,代码兼容C和Verilog,因此如果您愿意,可以在C编译器中测试序列。
如果您不喜欢for循环,可以将它们变成计数器。在HDL中,您总是颠倒顺序并从内循环开始:
if (j<3)
j <= j + 1;
else
begin
j <=0;
if (i<16) // should be 15 if you start from 0
i <= i + 5;
else
begin
i <= 1; // You sure it should not be zero?
if (start<3)
start <= start + 1;
else
begin
start <= 0;
all_done <= 1'b1
end // nd of start
end // end of j
end // end of i
在设计的不同部分,您现在可以使用start + i + j作为地址 最后:我会从索引0,1,2开始,因为你的图片可能是从内存地址0开始的。你需要更改'i'循环。
(HDL代码未编译或测试)