finish reconstruction and pass simulation
This commit is contained in:
33
sim/Makefile
33
sim/Makefile
@@ -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 --------------------"
|
||||
|
||||
183
sim/sc_main.cpp
183
sim/sc_main.cpp
@@ -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
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user