finish reconstruction and pass simulation

This commit is contained in:
SikongJueluo
2024-06-28 19:38:36 +08:00
parent 85910958f9
commit c527835ff6
7 changed files with 372 additions and 310 deletions

View File

@@ -37,7 +37,7 @@ VERILATOR_FLAGS += -sc --exe
# Generate makefile dependencies (not shown as complicates the Makefile)
#VERILATOR_FLAGS += -MMD
# Optimize
# VERILATOR_FLAGS += -x-assign fast
VERILATOR_FLAGS += -x-assign fast
# Warn abount lint issues; may not want this on less solid designs
VERILATOR_FLAGS += -Wall
# Make waveforms
@@ -45,7 +45,7 @@ VERILATOR_FLAGS += --trace
# Check SystemVerilog assertions
VERILATOR_FLAGS += --assert
# Enable multithreading
# VERILATOR_FLAGS += --threads 4
VERILATOR_FLAGS += --threads 14
# Generate coverage analysis
# VERILATOR_FLAGS += --coverage
# Run Verilator in debug mode
@@ -56,7 +56,7 @@ VERILATOR_FLAGS += --assert
TOP_MODULE = isp
VERILATOR_FLAGS += -top $(TOP_MODULE)
# Input files for Verilator
VERILATOR_INPUT = ../isp.v *.cpp ../Demosaic/demosaic2.v ../Crop/*.v ../FIFO/*.v ../Merge/*.v ../RAM/*.v
VERILATOR_INPUT = ../isp.v *.cpp ../Demosaic/Demosaic2.v ../Crop/*.v ../ColorBlender/*.v ../RAM/*.v
# Check if SC exists via a verilator call (empty if not)
SYSTEMC_EXISTS := $(shell $(VERILATOR) --get-supported SYSTEMC)
@@ -64,15 +64,16 @@ SYSTEMC_EXISTS := $(shell $(VERILATOR) --get-supported SYSTEMC)
######################################################################
ifneq ($(SYSTEMC_EXISTS),)
default: run
default: build run
else
default: nosc
endif
run:
@echo
@echo "-- Verilator tracing example"
lint:
@echo "-- Verilator lint check ----"
$(VERILATOR) -sc --lint-only $(VERILATOR_INPUT)
build:
@echo
@echo "-- VERILATE ----------------"
$(VERILATOR) $(VERILATOR_FLAGS) $(VERILATOR_INPUT)
@@ -86,17 +87,21 @@ run:
# 3. Or, call a submakefile where we can override the rules ourselves:
$(MAKE) -j -C obj_dir -f V$(TOP_MODULE).mk
run:
@echo
@echo "-- RUN ---------------------"
# @rm -rf logs
# @mkdir -p logs
# obj_dir/V$(TOP_MODULE) +trace
obj_dir/V$(TOP_MODULE)
# @echo
# @echo "-- COVERAGE ----------------"
# @rm -rf logs/annotated
# $(VERILATOR_COVERAGE) --annotate logs/annotated logs/coverage.dat
# @echo
# @echo "-- COVERAGE ----------------"
# @rm -rf logs/annotated
# $(VERILATOR_COVERAGE) --annotate logs/annotated logs/coverage.dat
@echo "-- FINISH ------------------"
trace:
@rm -rf logs
@mkdir -p logs
obj_dir/V$(TOP_MODULE) +trace
@echo
@echo "-- DONE --------------------"

View File

@@ -5,51 +5,61 @@
#include <systemc>
// Include common routines
#include <sys/stat.h> // mkdir
#include <verilated.h>
#include <verilated_vcd_sc.h>
#include <sys/stat.h> // mkdir
// Include model header, generated from Verilating "isp.v"
#include "Visp.h"
// Handle file
#include <fstream>
#include <iostream>
// math
#include <cmath>
#include "bmp.hpp"
#define IN_WIDTH 1936
#define IN_HEIGHT 1088
static const uint16_t IN_WIDTH = 1936;
static const uint16_t IN_HEIGHT = 1088;
#define IN_SIZE (IN_WIDTH * IN_HEIGHT)
#define OUT_WIDTH 1920
#define OUT_HEIGHT 1080
static const uint16_t OUT_WIDTH = 1920;
static const uint16_t OUT_HEIGHT = 1080;
#define OUT_SIZE (OUT_WIDTH * OUT_HEIGHT)
// const float red_gain = 1.2f; // Adjust these values as necessary
// const float green_gain = 0.5f;
// const float blue_gain = 0.95f;
struct color_gain
{
double red;
double green;
double blue;
}color_gain {1.0, 0.5, 1.1};
using namespace std;
using namespace sc_core;
using namespace sc_dt;
SC_MODULE (TB_ISP) {
SC_MODULE(TB_ISP) {
sc_in_clk clk;
sc_in<bool> reset;
sc_in<bool> data_que;
sc_out<bool> data_en;
sc_out<uint32_t> data_out[3];
sc_in<bool> in_ready;
sc_in<bool> in_receive;
sc_out<bool> out_en;
sc_out<uint32_t> out_data[3];
sc_in<bool> im_clk;
sc_in<bool> im_en;
sc_out<bool> out_ready;
sc_out<bool> out_receceive;
sc_in<uint32_t> im_data;
sc_out<bool> is_done;
unique_ptr<uint16_t[]> image = make_unique<uint16_t[]>(IN_SIZE);
unique_ptr<uint32_t[]> out = make_unique<uint32_t[]>(OUT_SIZE);
SC_CTOR (TB_ISP) {
SC_CTOR(TB_ISP) {
SC_CTHREAD(send_Data, clk.pos());
reset_signal_is(reset, true);
@@ -58,56 +68,63 @@ SC_MODULE (TB_ISP) {
void send_Data(void) {
uint16_t pos_x = 0, pos_y = 0;
while (true)
{
if (data_que.read() && pos_y < IN_HEIGHT - 2) {
data_en.write(1);
while (true) {
if (in_ready.read() && pos_y < IN_HEIGHT - 2) {
out_en.write(1);
printf("x=%4d, y=%4d, data=0x%04x\t", pos_x, pos_y, image[( pos_y + 0 ) * IN_WIDTH + pos_x]);
printf("x=%4d, y=%4d, data=0x%04x\t", pos_x, pos_y, image[( pos_y + 1 ) * IN_WIDTH + pos_x]);
printf("x=%4d, y=%4d, data=0x%04x\n", pos_x, pos_y, image[( pos_y + 2 ) * IN_WIDTH + pos_x]);
printf("x=%4d, y=%4d, data=0x%04x\t", pos_x, pos_y,
image[(pos_y + 0) * IN_WIDTH + pos_x]);
printf("x=%4d, y=%4d, data=0x%04x\t", pos_x, pos_y,
image[(pos_y + 1) * IN_WIDTH + pos_x]);
printf("x=%4d, y=%4d, data=0x%04x\n", pos_x, pos_y,
image[(pos_y + 2) * IN_WIDTH + pos_x]);
data_out[0].write(image[( pos_y + 0 ) * IN_WIDTH + pos_x]);
data_out[1].write(image[( pos_y + 1 ) * IN_WIDTH + pos_x]);
data_out[2].write(image[( pos_y + 2 ) * IN_WIDTH + pos_x]);
out_data[0].write(image[(pos_y + 0) * IN_WIDTH + pos_x]);
out_data[1].write(image[(pos_y + 1) * IN_WIDTH + pos_x]);
out_data[2].write(image[(pos_y + 2) * IN_WIDTH + pos_x]);
wait(1);
data_en.write(0);
// wait(1);
// out_en.write(0);
if (++pos_x >= IN_WIDTH) {
pos_x = 0;
pos_y++;
}
} else {
data_en.write(0);
out_en.write(0);
}
wait();
}
}
void read_Data(void) {
is_done.write(0);
uint16_t pos_x = 0, pos_y = 0;
uint32_t last_data = 0;
uint16_t cnt = 0;
while (true)
{
uint32_t cnt = 0;
while (true) {
if (im_en.read()) {
out_ready.write(false);
out_receceive.write(true);
out[pos_y * OUT_WIDTH + pos_x] = im_data.read();
if (pos_x++ >= OUT_WIDTH) {
pos_x = 0;
pos_y++;
}
} else {
out_ready.write(true);
out_receceive.write(false);
}
// when data didn't change some time, it end
if (last_data == im_data.read()) {
cnt++;
if (cnt >= 10000) {
if (cnt >= 100000L) {
is_done.write(1);
printf("x=%d, y=%d\n",pos_x, pos_y);
printf("x=%d, y=%d\n", pos_x, pos_y);
}
} else {
cnt = 0;
@@ -142,13 +159,15 @@ int sc_main(int argc, char* argv[]) {
uint32_t i = 0;
for (int y = 0; y < IN_HEIGHT; y++) {
for (int x = 0; x < IN_WIDTH; x++) {
image[y * IN_WIDTH + x] = (uint16_t)buf[i] + ((uint16_t)buf[i + 1] << 8);
image[y * IN_WIDTH + x] =
(uint16_t)buf[i] + ((uint16_t)buf[i + 1] << 8);
i += 2;
}
}
cout << "Finish Reading data" << endl;
// This is a more complicated example, please also see the simpler examples/make_hello_c.
// This is a more complicated example, please also see the simpler
// examples/make_hello_c.
// Create logs/ directory in case we have traces to put under it
Verilated::mkdir("logs");
@@ -161,7 +180,8 @@ int sc_main(int argc, char* argv[]) {
// May be overridden by commandArgs argument parsing
Verilated::randReset(2);
// Before any evaluation, need to know to calculate those signals only used for tracing
// Before any evaluation, need to know to calculate those signals only used
// for tracing
Verilated::traceEverOn(true);
// Pass arguments so Verilated code can see them, e.g. $value$plusargs
@@ -176,49 +196,68 @@ int sc_main(int argc, char* argv[]) {
// Define interconnect
sc_signal<bool> reset;
sc_signal<bool> data_en;
sc_signal<bool> data_que;
sc_signal<uint32_t> data_in[3];
sc_signal<bool> in_en;
sc_signal<bool> in_ready;
sc_signal<bool> in_receive;
sc_signal<uint32_t> in_data[3];
sc_signal<bool> out_clk;
sc_signal<bool> out_en;
sc_signal<uint32_t> data_out;
sc_signal<bool> out_ready;
sc_signal<bool> out_receive;
sc_signal<uint32_t> out_data;
sc_signal<bool> color_correction;
sc_signal<uint32_t> gain_red;
sc_signal<uint32_t> gain_green;
sc_signal<uint32_t> gain_blue;
sc_signal<bool> flag_done;
// Construct the Verilated model, from inside Visp.h
// Using unique_ptr is similar to "Visp* isp = new Visp" then deleting at end
// Using unique_ptr is similar to "Visp* isp = new Visp" then deleting at
// end
const std::unique_ptr<Visp> isp{new Visp{"isp"}};
// Attach Visp's signals to this upper model
isp->clk(clk);
isp->reset(reset);
isp->data_en(data_en);
isp->data_que(data_que);
isp->data_in[0](data_in[0]);
isp->data_in[1](data_in[1]);
isp->data_in[2](data_in[2]);
isp->in_en(in_en);
isp->in_ready(in_ready);
isp->in_receive(in_receive);
isp->in_data[0](in_data[0]);
isp->in_data[1](in_data[1]);
isp->in_data[2](in_data[2]);
isp->out_clk(out_clk);
isp->out_en(out_en);
isp->data_out(data_out);
isp->out_ready(out_ready);
isp->out_receive(out_receive);
isp->out_data(out_data);
isp->gain_red(gain_red);
isp->gain_green(gain_green);
isp->gain_blue(gain_blue);
isp->color_correction(color_correction);
color_correction.write(false); // enable color correction
color_correction.write(true); // enable color correction
gain_red.write((uint32_t)(color_gain.red * std::pow(2, 8)));
gain_green.write((uint32_t)(color_gain.green * std::pow(2, 8)));
gain_blue.write((uint32_t)(color_gain.blue * std::pow(2, 8)));
// Construct testbench module
TB_ISP tb_isp("tb_isp");
tb_isp.clk(clk);
tb_isp.reset(reset);
tb_isp.data_que(data_que);
tb_isp.data_en(data_en);
tb_isp.data_out[0](data_in[0]);
tb_isp.data_out[1](data_in[1]);
tb_isp.data_out[2](data_in[2]);
tb_isp.in_ready(out_ready);
tb_isp.in_receive(out_receive);
tb_isp.out_en(in_en);
tb_isp.out_ready(in_ready);
tb_isp.out_receceive(in_receive);
tb_isp.out_data[0](in_data[0]);
tb_isp.out_data[1](in_data[1]);
tb_isp.out_data[2](in_data[2]);
tb_isp.im_clk(out_clk);
tb_isp.im_en(out_en);
tb_isp.im_data(data_out);
tb_isp.im_data(out_data);
tb_isp.is_done(flag_done);
tb_isp.image = move(image);
@@ -251,8 +290,7 @@ int sc_main(int argc, char* argv[]) {
reset.write(0); // Deassert reset
}
if (flag_done.read())
break;
if (flag_done.read()) break;
// Simulate 1ns
sc_start(1, SC_NS);
@@ -271,30 +309,31 @@ int sc_main(int argc, char* argv[]) {
cout << "Ready to save raw RGB image" << endl;
// for (int y = 0; y < OUT_HEIGHT; y++)
// 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();
// save to image
uint8_t* data = new uint8_t[OUT_WIDTH * OUT_HEIGHT * 3]; // RGB24格式像素数据
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 );
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));
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);
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
data[index + 0] = red; // R
data[index + 1] = green; // G
data[index + 2] = blue; // B
}
}