У меня есть процессор riscv и процессор расширения, который можно программировать. Другими словами, расширение имеет свою уникальную ISA.
Я вставлю в это расширение инструкцию для выполнения свертки программой, работающей на процессоре riscv. Другими словами, если я запускаю следующие коды, процессор riscv вставляет инструкцию lw в это расширение на каждой итерации. k соответствует номеру регистра, а kernel_pointer — адресу SRAM.
for(int k = 0; k < input_channel_size; k++){lw_encode(k, kernel_pointer);kernel_pointer++;}
Это расширение имеет собственную DRAM и SRAM, которыми нужно управлять вручную. У меня проблемы с управлением памятью. В моей ситуации емкость DRAM бесконечна, а емкость SRAM составляет 1024 слова. Я могу получить доступ к DRAM только с 32-байтовым выровненным доступом, и его доступ должен передавать несколько 32 байтов.
Учитывая, что каждый пиксель имеет длину 32 бита, как вы знаете, поскольку в почти ситуации полное изображение и ядро не могут быть загружены в SRAM, поэтому мне приходится извлекать изображения только в небольших количествах и вычислять их с помощью итерации. Но поскольку DRAM разрешает доступ только к адресу с выравниванием по 32 байтам, а не по адресу с выравниванием по 32 битам, и поскольку она должна извлекать 32 байта, а не 32 бита, во многих случаях мне приходится извлекать ненужные или следующие пиксели операнда.
Для адреса SRAM я назначу адрес от 0 до 255 для входного изображения, от 256 до 511 для фильтра и от 512 до 755 для адреса назначения, и я хочу зарезервировать 756-1023 для дальнейшего расширения. Конечно, эта адресация является произвольной и может быть предварительно изменена.
В этой ситуации, например, пусть изображение[32][32][6] и фильтр[3][3][6] и если я рассматриваю умножение и сложение с точки зрения фильтра[0][0][0:6 ], мне нужно получить изображение[0:30][0:30][0:6]. А так как наименьший размер пикселя извлеченного изображения равен 8, то изображение [0][0] невозможно, так как оно имеет только 6 пикселей, что означает, что 2 пикселя не нужны. Я пытаюсь решить эту проблему, введя концепцию циклической очереди, но не знаю, как справиться с этой ситуацией. А что, если будут извлечены пиксели вне области видимости? Например, изображение[31][31][0:6] может быть получено из-за свойства доступа к DRAM.
Вот фрагмент кода для простоты понимания моей ситуации. Я думаю, что этот код не будет работать, так как он пытается получить доступ к адресу DRAM, который не выровнен по 32 байтам.
if(input_channel_size < 16){ // weight_stationary_case
dram_read_wrapping(kernel_pointer, dram_kernel, 9 * input_channel_size, k_corner, false);
for(int m = 0; m < 9; m++){
for(int k = 0; k < input_channel_size; k++){
lw_encode(k, kernel_pointer);
kernel_pointer++;
}
for(int i = 0; i < size_of_output * size_of_output;){
f_num = dram_read_wrapping(feature_pointer, dram_feature, input_channel_size, f_corner, true);
for(int j = 0; j < f_num; j++){
if(((j + 1) % size_of_output) == 0){
feature_pointer += 2 * input_channel_size;
feature_pointer = feature_pointer % 0x100;
destination_end += 2;
if(destination_end >= 0x300) dram_write_wrapping(destination_start, dram_result, destination_end, d_corner);
j++;
continue;
}
for(int k = 0; k < input_channel_size; k++){
lw_encode(k, feature_pointer);
feature_pointer++;
feature_pointer = feature_pointer % 0x100 ;
}
// mac_reserve();
for(int k = 0; k < 3; k ++){
mac_encode(31, 1 + k, 4 + k);
}
// mac_reserve();
sw_encode(31, destination_end++);
if(destination_address == 0x300) dram_write_wrapping(destination_start, dram_result, destination_end, d_corner);
}
i += f_num;
}
if(m == 2 || m == 5) dram_feature += 2 * input_channel_size;
else dram_feature++;
}
}
Есть ли какая-нибудь идея, которая поможет в этой ситуации? Спасибо. Кроме того, если есть неясный контекст, сообщите мне, чтобы я обновил описание.