From 407dedd229ccc3866ba4176b572c96bf778c73dd Mon Sep 17 00:00:00 2001 From: SikongJueluo Date: Mon, 1 Jul 2024 21:51:00 +0800 Subject: [PATCH] create a different width of input and outpud SyncFIFO --- RAM/DiffWidthSyncFIFO.v | 68 ++++++++++++++++++++++++++++++++++++ RAM/tb_DiffWidthSyncFIFO.v | 65 +++++++++++++++++++++++++++++++++++ sim/sc_main.cpp | 70 +++++++++++++++++++++++++------------- 3 files changed, 180 insertions(+), 23 deletions(-) create mode 100644 RAM/DiffWidthSyncFIFO.v create mode 100644 RAM/tb_DiffWidthSyncFIFO.v diff --git a/RAM/DiffWidthSyncFIFO.v b/RAM/DiffWidthSyncFIFO.v new file mode 100644 index 0000000..83791e7 --- /dev/null +++ b/RAM/DiffWidthSyncFIFO.v @@ -0,0 +1,68 @@ +`timescale 1ns / 1ps + +module DiffWidthSyncFIFO #( + parameter reg [7:0] DATA_WIDTH = 8, + parameter reg [7:0] DATA_DEPTH = 12, + parameter reg [7:0] READ_DEPTH = 3, + parameter reg [7:0] WRITE_DEPTH = 4 +) ( + input wire clk, + input wire reset, + + input wire read_ready, + output reg read_en, + output reg [DATA_WIDTH * READ_DEPTH - 1 : 0] read_data, + + output reg write_ready, + input wire write_en, + input wire [DATA_WIDTH * WRITE_DEPTH - 1 : 0] write_data +); + reg [DATA_WIDTH - 1 : 0] data[DATA_DEPTH]; + wire [7:0] occupancy; + reg [7:0] cnt_read, cnt_write; + reg [7:0] wi, ri; + + assign occupancy = (cnt_write >= cnt_read) + ? (cnt_write - cnt_read) + : (cnt_write + DATA_DEPTH - cnt_read); + + // write data to fifo + always @(posedge clk or posedge reset) begin + if (reset) begin + write_ready <= 0; + cnt_write <= 0; + end else begin + if (write_en) begin + write_ready <= 0; + for (wi = 0; wi < WRITE_DEPTH; wi = wi + 1) begin + data[cnt_write] <= write_data[DATA_WIDTH*(wi+1)-1 : wi*DATA_WIDTH]; + + if (cnt_write < DATA_DEPTH - 1) cnt_write <= cnt_write + 1; + else cnt_write <= 0; + end + end else begin + write_ready <= 1; + end + end + end + + always @(posedge clk or posedge reset) begin + if (reset) begin + read_data <= 0; + cnt_read <= 0; + end else begin + if (read_ready) begin + read_en <= 1; + for (ri = 0; ri < READ_DEPTH; ri = ri + 1) begin + read_data[DATA_WIDTH*(ri+1)-1:ri*DATA_WIDTH] <= data[cnt_read]; + + if (cnt_read < DATA_DEPTH - 1) cnt_read <= cnt_read + 1; + else cnt_read <= 0; + end + end else begin + read_en <= 0; + end + end + end + +endmodule diff --git a/RAM/tb_DiffWidthSyncFIFO.v b/RAM/tb_DiffWidthSyncFIFO.v new file mode 100644 index 0000000..cb8c1ad --- /dev/null +++ b/RAM/tb_DiffWidthSyncFIFO.v @@ -0,0 +1,65 @@ +`timescale 1ns / 1ps +`include "DiffWidthSyncFIFO.v" +`default_nettype none + +module tb_DiffWidthSyncFIFO; + localparam reg [7:0] DATA_WIDTH = 8; + localparam reg [7:0] DATA_DEPTH = 12; + localparam reg [7:0] READ_DEPTH = 3; + localparam reg [7:0] WRITE_DEPTH = 4; + reg clk; + reg reset; + reg write_en; + reg [DATA_WIDTH * WRITE_DEPTH - 1 : 0] write_data; + + wire read_en, write_ready, read_ready; + wire [DATA_WIDTH * READ_DEPTH - 1 : 0] read_data; + + + DiffWidthSyncFIFO #( + .DATA_WIDTH (DATA_WIDTH), + .DATA_DEPTH (DATA_DEPTH), + .READ_DEPTH (READ_DEPTH), + .WRITE_DEPTH(WRITE_DEPTH) + ) inst_fifo ( + .clk (clk), + .reset(reset), + + .read_ready(read_ready), + .read_en(read_en), + .read_data(read_data), + + .write_ready(write_ready), + .write_en(write_en), + .write_data(write_data) + ); + + localparam CLK_PERIOD = 10; + always #(CLK_PERIOD / 2) clk = ~clk; + + initial begin + $dumpfile("tb_DiffWidthSyncFIFO.vcd"); + $dumpvars(0, tb_DiffWidthSyncFIFO); + end + + assign read_ready = read_en ? 0 : 1; + + initial begin + clk = 0; + reset = 0; + write_en = 0; + write_data = 0; + end + + integer i; + initial begin + for (i = 0; i < 10; i = i + 1) begin + + end + + $finish(10 * CLK_PERIOD); + end + + +endmodule +`default_nettype wire diff --git a/sim/sc_main.cpp b/sim/sc_main.cpp index fbc4e3b..6fd179b 100644 --- a/sim/sc_main.cpp +++ b/sim/sc_main.cpp @@ -33,10 +33,11 @@ struct color_gain { double red; double green; double blue; -} color_gain{1.1, 0.7, 1.3}; +} color_gain{1.1, 0.7, 1.3}, white_gain; static const double gamma_value = 2.2; static const double saturation_inc = 0.5; +static const double white_radio = 0.1; using namespace sc_core; using namespace sc_dt; @@ -143,7 +144,7 @@ int sc_main(int argc, char* argv[]) { std::ifstream in_image; std::ofstream out_image; in_image.open("./transform/test.bin", std::ios::in | std::ios::binary); - out_image.open("./transform/out.bin", std::ios::out | std::ios::binary); + // out_image.open("./transform/out.bin", std::ios::out | std::ios::binary); if (!in_image.is_open()) { std::cout << "Open image fail" << std::endl; exit(0); @@ -336,6 +337,8 @@ int sc_main(int argc, char* argv[]) { new uint8_t[OUT_WIDTH * OUT_HEIGHT * 3]; // RGB24格式像素数据 // software algorthms analyze + uint32_t red_total = 0, green_total = 0, blue_total = 0; + uint8_t red_max = 0, green_max = 0, blue_max = 0; 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; @@ -349,7 +352,13 @@ int sc_main(int argc, char* argv[]) { // green = 255 * std::pow(green / 255.0, 1 / gamma_value); // blue = 255 * std::pow(blue / 255.0, 1 / gamma_value); - // Adjust white balance + // Calculate white balance data + red_max = std::max(red_max, red); + green_max = std::max(green_max, green); + blue_max = std::max(blue_max, blue); + red_total += red; + green_total += green; + blue_total += blue; // Adjust vibrance // uint8_t max = std::max({red, green, blue}); @@ -379,7 +388,7 @@ int sc_main(int argc, char* argv[]) { // green = static_cast(L * 255 + // (green - L * 255) * (1 + // alpha)); - // blue = static_cast(L * 255 + + // blue = static_cast(L * 255 + // (blue - L * 255) * (1 + // alpha)); // } @@ -391,32 +400,47 @@ int sc_main(int argc, char* argv[]) { } } - // Save output image - std::cout << "Ready to save raw RGB image" << std::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.close(); - - // save to image + // Adjust White Balance : Grey World Color Correction + double K = static_cast(red_total + green_total + blue_total) / (3 * OUT_SIZE); + white_gain.red = static_cast(K * OUT_SIZE) / red_total; + white_gain.green = static_cast(K * OUT_SIZE) / green_total; + white_gain.blue = static_cast(K * OUT_SIZE) / blue_total; + printf("Gain: red = %f, green = %f, blue = %f", white_gain.red, + white_gain.green, white_gain.blue); 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 = data[index + 0]; - uint8_t green = data[index + 1]; - uint8_t blue = data[index + 2]; - - 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] = + static_cast(white_gain.red * data[index + 0]); + data[index + 1] = + static_cast(white_gain.green * data[index + 1]); + data[index + 2] = + static_cast(white_gain.blue * data[index + 2]); } } + // save to bin + std::cout << "Ready to save raw RGB image" << std::endl; + // 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 = data[index + 0]; + // uint8_t green = data[index + 1]; + // uint8_t blue = data[index + 2]; + + // 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); + // } + // } + + // save to bmp write_bmp("test.bmp", data, OUT_WIDTH, OUT_HEIGHT); delete[] data;