Zynqnet(五) fpga_top解析(一) https://blog.csdn.net/crazyeden/article/details/86654922
按照算法流程图,将会进行以下模块的计算,按照 y->x-> ch_in->ch_out->window_compute.
以下用保留主要演示代码:
// Y Loop
for (y = 0; y < layer.height; y++) {
// X Loop
for (x = 0; x < layer.width; x++) {
ImageCache::preloadPixelFromDRAM(SHARED_DRAM);
//宽度方向上,每移动1,就会加载输入特征读入ch_in个,按照输入特征的通道,一个个读入。
// Input Channel Loop
for (ci = 0; ci < layer.channels_in; ci++) {
ProcessingElement::processInputChannel(y, x, ci, layer.channels_out);
}// end L_CH_IN. Pixel (Y,X) is finished.
LOG("All CI, CO done for pixel(%d,%d)\n", (int)y, (int)x);
// = Postprocess =
LOG("Postprocess Pixel(%d,%d)\n", (int)y, (int)x);
// Calculate Output Pixel Coordinates
dimension_t y_out = (layer.stride == 2) ? (int)y / 2 : (int)y;
dimension_t x_out = (layer.stride == 2) ? (int)x / 2 : (int)x;
MemoryController::setupPixelWriteback(y_out, x_out);
weightaddr_t ci_offset =
WeightsCache::precalcInputOffset(layer.channels_in);
L_POSTPROCESS:
for (co = 0; co < layer.channels_out; co++) {
// Postprocess
data_t processed = ProcessingElement::postprocess(co, ci_offset);
// Writeback to DRAM
MemoryController::writeBackOutputChannel(SHARED_DRAM, co, processed);
GPoolCache::accumulateChannel(co, processed);
}//L_POSTPROCESS
}// L_X
}// L_Y
if (layer.global_pool == true) {
MemoryController::writeBackResult(SHARED_DRAM);
}
从循环顺序,先是高度方向,然后是宽度方向上,X方向上每移动一次,都会调用一次 ImageCache::preloadPixelFromDRAM(SHARED_DRAM)函数,该函数就会加载一个像素位置&#