update software sim

This commit is contained in:
SikongJueluo 2024-05-18 18:56:32 +08:00
parent 1ad504cb9f
commit caa0588b9b
No known key found for this signature in database
GPG Key ID: D2D3D29A993716EA
12 changed files with 271 additions and 45 deletions

2
.gitignore vendored
View File

@ -12,3 +12,5 @@
*.dat *.dat
*.png *.png
!im.tif !im.tif
*.bmp
*.out

View File

@ -1,6 +1,6 @@
module crop #( module crop #(
parameter IN_WIDTH = 1936, parameter IN_WIDTH = 1934,
parameter IN_HEIGHT = 1088, parameter IN_HEIGHT = 1086,
parameter OFFSET_X = 8, parameter OFFSET_X = 8,
parameter OFFSET_Y = 4, parameter OFFSET_Y = 4,
parameter OUT_WIDTH = 640, parameter OUT_WIDTH = 640,
@ -60,15 +60,15 @@ module crop #(
end end
HANDLE_DATA: begin HANDLE_DATA: begin
if (OFFSET_Y <= cnt_y && cnt_y < (OFFSET_Y + OUT_HEIGHT)) begin if (OFFSET_Y <= cnt_y && cnt_y < (OFFSET_Y + OUT_HEIGHT - 1)) begin
if (OFFSET_X <= cnt_x && cnt_x < (OFFSET_X + OUT_WIDTH)) begin if (OFFSET_X <= cnt_x && cnt_x < (OFFSET_X + OUT_WIDTH - 1)) begin
out_en <= 1; out_en <= 1;
end end
end end
if (cnt_x >= IN_WIDTH) begin if (cnt_x >= IN_WIDTH - 1) begin
cnt_x <= 0; cnt_x <= 0;
if (cnt_y >= IN_HEIGHT) begin if (cnt_y >= IN_HEIGHT - 1) begin
cnt_y <= 0; cnt_y <= 0;
end end
else begin else begin

View File

@ -152,13 +152,14 @@ module demosaic2 #(
pos_y <= pos_y + 1; pos_y <= pos_y + 1;
if (pos_y >= IM_HEIGHT - 2 - 1) begin if (pos_y >= IM_HEIGHT - 2 - 1) begin
pos_y <= 0; pos_y <= 0;
case (RAW_TYPE)
0: raw_type <= 2;
1: raw_type <= 3;
2: raw_type <= 0;
3: raw_type <= 1;
endcase
end end
// 换行后切换Bayer格式
case (RAW_TYPE)
0: raw_type <= 2;
1: raw_type <= 3;
2: raw_type <= 0;
3: raw_type <= 1;
endcase
end end
else begin else begin
cnt_data <= 2; cnt_data <= 2;

8
isp.v
View File

@ -1,10 +1,10 @@
`timescale 1ns/1ps `timescale 1ns/1ps
module isp #( module isp #(
parameter IN_WIDTH = 700, parameter IN_WIDTH = 1936,
parameter IN_HEIGHT = 500, parameter IN_HEIGHT = 1088,
parameter OUT_WIDTH = 640, parameter OUT_WIDTH = 1920,
parameter OUT_HEIGHT = 480, parameter OUT_HEIGHT = 1080,
parameter COLOR_DEPTH = 8, parameter COLOR_DEPTH = 8,
parameter RAW_TYPE = 3 // 0:grbg 1:rggb 2:bggr 3:gbrg parameter RAW_TYPE = 3 // 0:grbg 1:rggb 2:bggr 3:gbrg
) ( ) (

View File

@ -56,7 +56,7 @@ VERILATOR_FLAGS += --assert
TOP_MODULE = isp TOP_MODULE = isp
VERILATOR_FLAGS += -top $(TOP_MODULE) VERILATOR_FLAGS += -top $(TOP_MODULE)
# Input files for Verilator # Input files for Verilator
VERILATOR_INPUT = ../isp.v sc_main.cpp ../Demosaic/demosaic2.v ../Crop/*.v ../FIFO/*.v ../Merge/*.v ../RAM/*.v VERILATOR_INPUT = ../isp.v *.cpp ../Demosaic/demosaic2.v ../Crop/*.v ../FIFO/*.v ../Merge/*.v ../RAM/*.v
# Check if SC exists via a verilator call (empty if not) # Check if SC exists via a verilator call (empty if not)
SYSTEMC_EXISTS := $(shell $(VERILATOR) --get-supported SYSTEMC) SYSTEMC_EXISTS := $(shell $(VERILATOR) --get-supported SYSTEMC)
@ -88,9 +88,10 @@ run:
@echo @echo
@echo "-- RUN ---------------------" @echo "-- RUN ---------------------"
@rm -rf logs # @rm -rf logs
@mkdir -p logs # @mkdir -p logs
obj_dir/V$(TOP_MODULE) +trace # obj_dir/V$(TOP_MODULE) +trace
obj_dir/V$(TOP_MODULE)
# @echo # @echo
# @echo "-- COVERAGE ----------------" # @echo "-- COVERAGE ----------------"

46
sim/bmp.cpp Normal file
View File

@ -0,0 +1,46 @@
#include "bmp.hpp"
#include <fstream>
#include <iostream>
// 将RGB24格式像素数据封装为BMP图像
bool write_bmp(const char* filename, uint8_t* data, int32_t width,
int32_t height) {
BMPFileHeader file_header = {0};
BMPInfoHeader info_header = {0};
std::ofstream ofs(filename, std::ios::binary);
if (!ofs) {
std::cerr << "Failed to create file: " << filename << std::endl;
return false;
}
// BMP文件头
file_header.type = 0x4D42; // BM
file_header.size =
sizeof(BMPFileHeader) + sizeof(BMPInfoHeader) + width * height * 3;
file_header.offset = sizeof(BMPFileHeader) + sizeof(BMPInfoHeader);
ofs.write(reinterpret_cast<char*>(&file_header), sizeof(file_header));
// BMP位图信息头
info_header.size = sizeof(BMPInfoHeader);
info_header.width = width;
info_header.height = height;
info_header.planes = 1;
info_header.bit_count = 24;
info_header.size_image = width * height * 3;
ofs.write(reinterpret_cast<char*>(&info_header), sizeof(info_header));
// 像素数据
int32_t row_size = (((width + 1) * 3) / 4) * 4; // 行字节数必须为4的倍数
uint8_t* row_data = new uint8_t[row_size];
for (int32_t y = height - 1; y >= 0; --y) { // BMP图像的行是从下往上存储的
for (int32_t x = 0; x < width; ++x) {
row_data[x * 3 + 2] = data[(y * width + x) * 3 + 0]; // B
row_data[x * 3 + 1] = data[(y * width + x) * 3 + 1]; // G
row_data[x * 3 + 0] = data[(y * width + x) * 3 + 2]; // R
}
ofs.write(reinterpret_cast<char*>(row_data), row_size);
}
delete[] row_data;
ofs.close();
return true;
}

35
sim/bmp.hpp Normal file
View File

@ -0,0 +1,35 @@
#ifndef __BMP_H__
#define __BMP_H__
#include <stdint.h>
#pragma pack(push, 1) // 1字节对齐
// BMP文件头结构体
struct BMPFileHeader {
uint16_t type; // 文件类型,必须为"BM"
uint32_t size; // 文件大小,单位为字节
uint16_t reserved1; // 保留字段必须为0
uint16_t reserved2; // 保留字段必须为0
uint32_t offset; // 像素数据起始位置,单位为字节
};
// BMP位图信息头结构体
struct BMPInfoHeader {
uint32_t size; // 信息头大小必须为40
int32_t width; // 图像宽度,单位为像素
int32_t height; // 图像高度,单位为像素
uint16_t planes; // 颜色平面数必须为1
uint16_t bit_count; // 每个像素的位数必须为24
uint32_t compression; // 压缩方式必须为0
uint32_t size_image; // 像素数据大小,单位为字节
int32_t x_pels_per_meter; // X方向像素数/米
int32_t y_pels_per_meter; // Y方向像素数/米
uint32_t clr_used; // 使用的颜色数必须为0
uint32_t clr_important; // 重要的颜色数必须为0
};
#pragma pack(pop)
bool write_bmp(const char* filename, uint8_t* data, int32_t width, int32_t height);
#endif

View File

@ -16,12 +16,13 @@
// Handle file // Handle file
#include <fstream> #include <fstream>
#include <iostream> #include <iostream>
#include "bmp.hpp"
#define IN_WIDTH 700 #define IN_WIDTH 1936
#define IN_HEIGHT 500 #define IN_HEIGHT 1088
#define IN_SIZE (IN_WIDTH * IN_HEIGHT) #define IN_SIZE (IN_WIDTH * IN_HEIGHT)
#define OUT_WIDTH 640 #define OUT_WIDTH 1920
#define OUT_HEIGHT 480 #define OUT_HEIGHT 1080
#define OUT_SIZE (OUT_WIDTH * OUT_HEIGHT) #define OUT_SIZE (OUT_WIDTH * OUT_HEIGHT)
using namespace std; using namespace std;
@ -41,7 +42,7 @@ SC_MODULE (TB_ISP) {
sc_in<uint32_t> im_data; sc_in<uint32_t> im_data;
sc_out<bool> is_done; sc_out<bool> is_done;
unique_ptr<uint16_t[]> image; unique_ptr<uint16_t[]> image = make_unique<uint16_t[]>(IN_SIZE);
unique_ptr<uint32_t[]> out = make_unique<uint32_t[]>(OUT_SIZE); unique_ptr<uint32_t[]> out = make_unique<uint32_t[]>(OUT_SIZE);
SC_CTOR (TB_ISP) { SC_CTOR (TB_ISP) {
@ -69,7 +70,7 @@ SC_MODULE (TB_ISP) {
wait(1); wait(1);
data_en.write(0); data_en.write(0);
if (pos_x++ >= IN_WIDTH) { if (++pos_x >= IN_WIDTH) {
pos_x = 0; pos_x = 0;
pos_y++; pos_y++;
} }
@ -100,7 +101,7 @@ SC_MODULE (TB_ISP) {
if (last_data == im_data.read()) { if (last_data == im_data.read()) {
cnt++; cnt++;
if (cnt >= 100) { if (cnt >= 10000) {
is_done.write(1); is_done.write(1);
} }
} else { } else {
@ -129,7 +130,6 @@ int sc_main(int argc, char* argv[]) {
// Read image // Read image
auto buf = make_unique<uint8_t[]>(2 * IN_SIZE); auto buf = make_unique<uint8_t[]>(2 * IN_SIZE);
// vector<vector<uint8_t>> buf(IN_HEIGHT, vector<uint8_t>(IN_WIDTH, 0));
in_image.read((char*)buf.get(), IN_SIZE * 2); in_image.read((char*)buf.get(), IN_SIZE * 2);
in_image.close(); in_image.close();
// Reshape data // Reshape data
@ -259,10 +259,35 @@ int sc_main(int argc, char* argv[]) {
// Save output image // Save output image
cout << "Ready to save raw RGB image" << endl; cout << "Ready to save raw RGB image" << endl;
for (int y = 0; y < OUT_HEIGHT; y++) // for (int y = 0; y < OUT_HEIGHT; y++)
for(int x = 0; x < OUT_WIDTH; x++) // for(int x = 0; x < OUT_WIDTH; x++)
out_image.write((const char *)&tb_isp.out[y * OUT_WIDTH + x], sizeof(tb_isp.out[0])); // out_image.write((const char *)&tb_isp.out[y * OUT_WIDTH + x], sizeof(tb_isp.out[0]));
out_image.close(); // out_image.close();
// save to image
uint8_t* data = new uint8_t[OUT_WIDTH * OUT_HEIGHT * 3]; // RGB24格式像素数据
for (int32_t y = 0; y < OUT_HEIGHT; ++y) {
for (int32_t x = 0; x < OUT_WIDTH; ++x) {
int32_t index = (y * OUT_WIDTH + x) * 3;
uint8_t red = ( tb_isp.out[y * OUT_WIDTH + x] & 0x00ff0000 ) >> 16;
uint8_t green = ( tb_isp.out[y * OUT_WIDTH + x] & 0x0000ff00 ) >> 8;
uint8_t blue = ( tb_isp.out[y * OUT_WIDTH + x] & 0x000000ff );
out_image.write((const char *)&red, sizeof(red));
out_image.write((const char *)&green, sizeof(green));
out_image.write((const char *)&blue, sizeof(blue));
printf("x=%4d, y=%4d, red=0x%02x, green=0x%02x, blue=0x%02x\n", x, y, red, green, blue);
data[index + 0] = red; // R
data[index + 1] = green; // G
data[index + 2] = blue; // B
}
}
write_bmp("test.bmp", data, OUT_WIDTH, OUT_HEIGHT);
delete[] data;
// Return good completion status // Return good completion status
return 0; return 0;

126
sim/software/demosaic.cpp Normal file
View File

@ -0,0 +1,126 @@
#include <fstream>
#include <iostream>
#include <vector>
#include "bmp.hpp"
const int IN_WIDTH = 1920;
const int IN_HEIGHT = 1080;
const int IN_SIZE = IN_WIDTH * IN_HEIGHT;
const int OUT_WIDTH = 1280;
const int OUT_HEIGHT = 720;
const int OUT_SIZE = OUT_WIDTH * OUT_HEIGHT;
const int RAW_TYPE = 3;
int main() {
std::ifstream in_image;
in_image.open("./test.RAW", std::ios::in | std::ios::binary);
auto image = std::vector<std::vector<uint16_t>>(
IN_HEIGHT, std::vector<uint16_t>(IN_WIDTH, 0));
for (int y = 0; y < IN_HEIGHT; y++)
for (int x = 0; x < IN_WIDTH; x++) {
uint8_t buf[2] = {0};
in_image.read((char*)buf, sizeof(buf));
image[y][x] = buf[0] + (buf[1] << 8);
}
int raw_type = RAW_TYPE;
uint8_t* data =
new uint8_t[OUT_WIDTH * OUT_HEIGHT * 3]; // RGB24格式像素数据
for (int32_t y = 0; y < OUT_HEIGHT; ++y) {
for (int32_t x = 0; x < OUT_WIDTH; ++x) {
int32_t index = (y * OUT_WIDTH + x) * 3;
uint16_t red = 0, green = 0, blue = 0;
uint16_t data_cache[3][3] = {
{image[y][x], image[y][x + 1], image[y][x + 2]},
{image[y + 1][x], image[y + 1][x + 1], image[y + 1][x + 2]},
{image[y + 2][x], image[y + 2][x + 1], image[y + 2][x + 2]},
};
switch (raw_type) {
case 0: // Missing B, R on G
blue = (data_cache[1][0] + data_cache[1][2]) / 2;
red = (data_cache[0][1] + data_cache[2][1]) / 2;
green = data_cache[1][1];
break;
case 1: // Missing G, R on B
green = (data_cache[0][1] + data_cache[1][0] +
data_cache[1][2] + data_cache[2][1]) /
4;
red = (data_cache[0][0] + data_cache[0][2] +
data_cache[2][0] + data_cache[2][2]) /
4;
blue = data_cache[1][1];
break;
case 2: // Missing G, B on R
green = (data_cache[0][1] + data_cache[1][0] +
data_cache[1][2] + data_cache[2][1]) /
4;
blue = (data_cache[0][0] + data_cache[0][2] +
data_cache[2][0] + data_cache[2][2]) /
4;
red = data_cache[1][1];
break;
case 3: // Missing B, R on G
red = (data_cache[1][0] + data_cache[1][2]) / 2;
blue = (data_cache[0][1] + data_cache[2][1]) / 2;
green = data_cache[1][1];
break;
}
printf("x=%4d, y=%4d, red=0x%03x, green=0x%03x, blue=0x%03x, raw_type=%d\n", x,
y, red, green, blue, raw_type);
switch (raw_type) {
case 0:
raw_type = 1;
break;
case 1:
raw_type = 0;
break;
case 2:
raw_type = 3;
break;
case 3:
raw_type = 2;
break;
}
// data[index + 0] = red * 8 / 12; // R
data[index + 1] = green * 8 / 12; // G
// data[index + 2] = blue * 8 / 12; // B
data[index + 0] = 0; // R
// data[index + 1] = 0; // G
data[index + 2] = 0; // B
}
if (y % 2) {
raw_type = RAW_TYPE;
} else {
switch (RAW_TYPE) {
case 0:
raw_type = 2;
break;
case 1:
raw_type = 3;
break;
case 2:
raw_type = 0;
break;
case 3:
raw_type = 1;
break;
}
}
}
write_bmp("test.bmp", data, OUT_WIDTH, OUT_HEIGHT);
delete[] data;
return 0;
}

BIN
sim/software/test.RAW Normal file

Binary file not shown.

View File

@ -1,8 +1,8 @@
import imageio import imageio
import numpy as np import numpy as np
cut_width = 700 cut_width = 1936
cut_height = 500 cut_height = 1088
if __name__ == '__main__': if __name__ == '__main__':
# txt = open('./test.dat', 'w') # txt = open('./test.dat', 'w')

View File

@ -1,10 +0,0 @@
import imageio
import numpy as np
im_width = 640
im_height = 480
if __name__ == '__main__':
raw = np.fromfile('./out.bin', dtype=np.int32)
image = raw.reshape((im_height, im_width))
imageio.imsave("./out.png", image)