update software sim
This commit is contained in:
parent
1ad504cb9f
commit
caa0588b9b
|
@ -12,3 +12,5 @@
|
||||||
*.dat
|
*.dat
|
||||||
*.png
|
*.png
|
||||||
!im.tif
|
!im.tif
|
||||||
|
*.bmp
|
||||||
|
*.out
|
12
Crop/crop.v
12
Crop/crop.v
|
@ -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
|
||||||
|
|
|
@ -152,6 +152,8 @@ 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;
|
||||||
|
end
|
||||||
|
// 换行后切换Bayer格式
|
||||||
case (RAW_TYPE)
|
case (RAW_TYPE)
|
||||||
0: raw_type <= 2;
|
0: raw_type <= 2;
|
||||||
1: raw_type <= 3;
|
1: raw_type <= 3;
|
||||||
|
@ -159,7 +161,6 @@ module demosaic2 #(
|
||||||
3: raw_type <= 1;
|
3: raw_type <= 1;
|
||||||
endcase
|
endcase
|
||||||
end
|
end
|
||||||
end
|
|
||||||
else begin
|
else begin
|
||||||
cnt_data <= 2;
|
cnt_data <= 2;
|
||||||
|
|
||||||
|
|
8
isp.v
8
isp.v
|
@ -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
|
||||||
) (
|
) (
|
||||||
|
|
|
@ -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 ----------------"
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
|
@ -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
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
Binary file not shown.
|
@ -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')
|
||||||
|
|
|
@ -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)
|
|
Loading…
Reference in New Issue