diff --git a/Crop/crop.v b/Crop/crop.v index 200336e..8976825 100644 --- a/Crop/crop.v +++ b/Crop/crop.v @@ -1,6 +1,4 @@ module crop #( - parameter IN_WIDTH = 1936 - 2, - parameter IN_HEIGHT = 1088 - 2, parameter OFFSET_X = 8, parameter OFFSET_Y = 4, parameter OUT_WIDTH = 640, @@ -11,10 +9,10 @@ module crop #( input reset, input in_en, - output in_que, + output reg in_que, input [3 * COLOR_DEPTH - 1:0] data_in, - output out_en, + output reg out_en, output reg [3 * COLOR_DEPTH - 1:0] data_out ); localparam READ_DATA = 0; @@ -36,9 +34,9 @@ module crop #( // 下一状态更新 always @(*) begin case (state) - READ_DATA: nextState <= (in_que && in_en) ? HANDLE_DATA : READ_DATA; - HANDLE_DATA: nextState <= SEND_DATA; - SEND_DATA: nextState <= READ_DATA; + READ_DATA: nextState = (in_que && in_en) ? HANDLE_DATA : READ_DATA; + HANDLE_DATA: nextState = SEND_DATA; + SEND_DATA: nextState = READ_DATA; endcase end diff --git a/Merge/chanels_to_RGB.v b/Merge/chanels_to_RGB.v index 4ed4986..9bf9e6f 100644 --- a/Merge/chanels_to_RGB.v +++ b/Merge/chanels_to_RGB.v @@ -58,9 +58,12 @@ module chanels_to_RGB #( .winc(fifo_en), .wdata(fifo_in), + /* verilator lint_off PINCONNECTEMPTY */ .wfull(), + /* verilator lint_off PINCONNECTEMPTY */ .awfull(), + /* verilator lint_off PINCONNECTEMPTY */ .arempty(), .rempty(fifo_empty), .rdata(data_out), diff --git a/RAM/RGB_to_RAM.v b/RAM/RGB_to_RAM.v index 0aca79c..c129d60 100644 --- a/RAM/RGB_to_RAM.v +++ b/RAM/RGB_to_RAM.v @@ -39,11 +39,13 @@ module RGB_to_RAM #( .winc(in_en), .wdata(fifo_data), .wfull(fifo_full), + /* verilator lint_off PINCONNECTEMPTY */ .awfull(), .rinc(write_en), .rdata(data_write), .rempty(fifo_empty), + /* verilator lint_off PINCONNECTEMPTY */ .arempty() ); diff --git a/isp.v b/isp.v index 9816f07..fad4f1e 100644 --- a/isp.v +++ b/isp.v @@ -9,21 +9,20 @@ module isp #( parameter RAW_TYPE = 3 // 0:grbg 1:rggb 2:bggr 3:gbrg ) ( // 基本信号 - input clk, - input reset, + input wire clk, + input wire reset, // 数据输入信号 - input data_en, - input [15:0] data_in [2:0], // 数据输入线,0、1、2分别表示第一、二、三行 + input wire data_en, + input reg [15:0] data_in [2:0], // 数据输入线,0、1、2分别表示第一、二、三行 output reg data_que, // 数据请求线,高电平:请求三个数据,直到读取完才拉低 - output out_clk, - output out_en, - output [31:0] data_out + output wire out_clk, + output wire out_en, + output reg [3 * COLOR_DEPTH - 1:0] data_out ); // 三通道合成RGB图像 wire rgb_en; - wire [15:0] im_red, im_green, im_blue; // 任意比例缩放图像 reg scale_in_en; @@ -35,11 +34,13 @@ module isp #( // wire RAM_in_que; // RAM 请求数据 // wire [3 * COLOR_DEPTH - 1:0] RAM_in_data; - assign out_clk = clk; + always @(clk) + out_clk <= clk; demosaic2 #( .IM_WIDTH(1936), .IM_HEIGHT(1088), + .RAW_TYPE(RAW_TYPE) ) CFA ( .clk(clk), .reset(reset), @@ -63,7 +64,11 @@ module isp #( .data_out(scale_in_data) ); - crop crop_process ( + crop #( + .OUT_WIDTH(OUT_WIDTH), + .OUT_HEIGHT(OUT_HEIGHT), + .COLOR_DEPTH(COLOR_DEPTH) + ) crop_process ( .clk(clk), .reset(reset), diff --git a/sim/sc_main.cpp b/sim/sc_main.cpp index b0d98df..f550002 100644 --- a/sim/sc_main.cpp +++ b/sim/sc_main.cpp @@ -13,10 +13,109 @@ // Include model header, generated from Verilating "isp.v" #include "Visp.h" +// Handle file +#include +#include + +#define IM_WIDTH 1936 +#define IM_HEIGHT 1088 +#define IM_SIZE (IM_WIDTH * IM_HEIGHT) + +using namespace std; using namespace sc_core; using namespace sc_dt; +SC_MODULE (TB_ISP) { + sc_in_clk clk; + sc_in reset; + + sc_in data_que; + sc_out data_en; + sc_out data_out[3]; + + sc_in im_clk; + sc_in im_en; + sc_in im_data; + + uint16_t image[IM_HEIGHT][IM_WIDTH]; + uint32_t out[IM_SIZE] = {0}; + uint32_t out_head = 0; + + SC_CTOR (TB_ISP) { + SC_CTHREAD(send_Data, clk.pos()); + reset_signal_is(reset, true); + + SC_CTHREAD(read_Data, im_clk.pos()); + } + + void send_Data(void) { + uint16_t pos_x = 0, pos_y = 0; + while (true) + { + if (data_que.read() && pos_y < IM_HEIGHT - 2) { + data_en.write(1); + + printf("x=%3d, y=%3d, data=0x%04x\t", pos_x, pos_y, image[pos_y + 0][pos_x]); + printf("x=%3d, y=%3d, data=0x%04x\t", pos_x, pos_y, image[pos_y + 1][pos_x]); + printf("x=%3d, y=%3d, data=0x%04x\n", pos_x, pos_y, image[pos_y + 2][pos_x]); + + data_out[0].write(image[pos_y + 0][pos_x]); + data_out[1].write(image[pos_y + 1][pos_x]); + data_out[2].write(image[pos_y + 2][pos_x]); + + if (pos_x++ >= IM_WIDTH) { + pos_x = 0; + pos_y++; + } + } else { + data_en.write(0); + } + + wait(); + } + + } + + void read_Data(void) { + while (true) + { + if (im_en.read()) { + out[out_head++] = im_data.read(); + } + + wait(); + } + } +}; + int sc_main(int argc, char* argv[]) { + // Open image + ifstream in_image; + ofstream out_image; + in_image.open("./Demosaic/sim/transform/test.bin", ios::in | ios::binary); + out_image.open("./out.bin", ios::out | ios::binary); + if (!in_image.is_open()) { + cout << "Open image fail" << endl; + exit(0); + } else { + cout << "Ready to sim" << endl; + } + + // Read image + uint8_t buf[IM_SIZE * 2] = {0}; + in_image.read((char*)buf, IM_SIZE * 2); + in_image.close(); + // Reshape data + uint16_t image[IM_HEIGHT][IM_WIDTH] = {0}; + uint32_t i = 0; + for (int y = 0; y < IM_HEIGHT; y++) { + for (int x = 0; x < IM_WIDTH; x++) { + image[y][x] = (uint16_t)buf[i] + ((uint16_t)buf[i + 1] << 8); + i++; + } + } + cout << "Finish Reading data" << endl; + // 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 @@ -42,31 +141,46 @@ int sc_main(int argc, char* argv[]) { // Define clocks sc_clock clk{"clk", 10, SC_NS, 0.5, 3, SC_NS, true}; - sc_clock fastclk{"fastclk", 2, SC_NS, 0.5, 2, SC_NS, true}; - // Define interconnect - sc_signal reset_l; - sc_signal in_small; - sc_signal in_quad; - sc_signal> in_wide; - sc_signal out_small; - sc_signal out_quad; - sc_signal> out_wide; + sc_signal reset; + + sc_signal data_en; + sc_signal data_que; + sc_signal data_in[3]; + + sc_signal out_clk; + sc_signal out_en; + sc_signal data_out; + // Construct the Verilated model, from inside Visp.h // Using unique_ptr is similar to "Visp* isp = new Visp" then deleting at end const std::unique_ptr isp{new Visp{"isp"}}; - // Attach Visp's signals to this upper model isp->clk(clk); - isp->fastclk(fastclk); - isp->reset_l(reset_l); - isp->in_small(in_small); - isp->in_quad(in_quad); - isp->in_wide(in_wide); - isp->out_small(out_small); - isp->out_quad(out_quad); - isp->out_wide(out_wide); + 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->out_clk(out_clk); + isp->out_en(out_en); + isp->data_out(data_out); + + // 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.im_clk(out_clk); + tb_isp.im_en(out_en); + tb_isp.im_data(data_out); + memcpy(tb_isp.image, image, sizeof(image)); // You must do one evaluation before enabling waves, in order to allow // SystemC to interconnect everything for testing. @@ -91,10 +205,10 @@ int sc_main(int argc, char* argv[]) { if (tfp) tfp->flush(); // Apply inputs - if (sc_time_stamp() > sc_time(1, SC_NS) && sc_time_stamp() < sc_time(10, SC_NS)) { - reset_l = !1; // Assert reset + if (sc_time_stamp() < sc_time(10, SC_NS)) { + reset.write(1); // Assert reset } else { - reset_l = !0; // Deassert reset + reset.write(0); // Deassert reset } // Simulate 1ns @@ -110,11 +224,11 @@ int sc_main(int argc, char* argv[]) { tfp = nullptr; } - // Coverage analysis (calling write only after the test is known to pass) -#if VM_COVERAGE - Verilated::mkdir("logs"); - VerilatedCov::write("logs/coverage.dat"); -#endif + // Save output image + for (int y = 0; y < IM_HEIGHT; y++) + for(int x = 0; x < IM_WIDTH; x++) + out_image.write((const char *)&tb_isp.out[y * IM_WIDTH + x], sizeof(tb_isp.out[0])); + out_image.close(); // Return good completion status return 0;