finish isp testbench but still have some errors waiting to be deat with

This commit is contained in:
SikongJueluo 2024-05-15 16:35:17 +08:00
parent e29dce1d7e
commit 0f7ba1a48a
No known key found for this signature in database
GPG Key ID: D2D3D29A993716EA
5 changed files with 165 additions and 43 deletions

View File

@ -1,6 +1,4 @@
module crop #( module crop #(
parameter IN_WIDTH = 1936 - 2,
parameter IN_HEIGHT = 1088 - 2,
parameter OFFSET_X = 8, parameter OFFSET_X = 8,
parameter OFFSET_Y = 4, parameter OFFSET_Y = 4,
parameter OUT_WIDTH = 640, parameter OUT_WIDTH = 640,
@ -11,10 +9,10 @@ module crop #(
input reset, input reset,
input in_en, input in_en,
output in_que, output reg in_que,
input [3 * COLOR_DEPTH - 1:0] data_in, input [3 * COLOR_DEPTH - 1:0] data_in,
output out_en, output reg out_en,
output reg [3 * COLOR_DEPTH - 1:0] data_out output reg [3 * COLOR_DEPTH - 1:0] data_out
); );
localparam READ_DATA = 0; localparam READ_DATA = 0;
@ -36,9 +34,9 @@ module crop #(
// 下一状态更新 // 下一状态更新
always @(*) begin always @(*) begin
case (state) case (state)
READ_DATA: nextState <= (in_que && in_en) ? HANDLE_DATA : READ_DATA; READ_DATA: nextState = (in_que && in_en) ? HANDLE_DATA : READ_DATA;
HANDLE_DATA: nextState <= SEND_DATA; HANDLE_DATA: nextState = SEND_DATA;
SEND_DATA: nextState <= READ_DATA; SEND_DATA: nextState = READ_DATA;
endcase endcase
end end

View File

@ -58,9 +58,12 @@ module chanels_to_RGB #(
.winc(fifo_en), .winc(fifo_en),
.wdata(fifo_in), .wdata(fifo_in),
/* verilator lint_off PINCONNECTEMPTY */
.wfull(), .wfull(),
/* verilator lint_off PINCONNECTEMPTY */
.awfull(), .awfull(),
/* verilator lint_off PINCONNECTEMPTY */
.arempty(), .arempty(),
.rempty(fifo_empty), .rempty(fifo_empty),
.rdata(data_out), .rdata(data_out),

View File

@ -39,11 +39,13 @@ module RGB_to_RAM #(
.winc(in_en), .winc(in_en),
.wdata(fifo_data), .wdata(fifo_data),
.wfull(fifo_full), .wfull(fifo_full),
/* verilator lint_off PINCONNECTEMPTY */
.awfull(), .awfull(),
.rinc(write_en), .rinc(write_en),
.rdata(data_write), .rdata(data_write),
.rempty(fifo_empty), .rempty(fifo_empty),
/* verilator lint_off PINCONNECTEMPTY */
.arempty() .arempty()
); );

25
isp.v
View File

@ -9,21 +9,20 @@ module isp #(
parameter RAW_TYPE = 3 // 0:grbg 1:rggb 2:bggr 3:gbrg parameter RAW_TYPE = 3 // 0:grbg 1:rggb 2:bggr 3:gbrg
) ( ) (
// 基本信号 // 基本信号
input clk, input wire clk,
input reset, input wire reset,
// 数据输入信号 // 数据输入信号
input data_en, input wire data_en,
input [15:0] data_in [2:0], // 数据输入线012分别表示第一三行 input reg [15:0] data_in [2:0], // 数据输入线012分别表示第一三行
output reg data_que, // 数据请求线高电平请求三个数据直到读取完才拉低 output reg data_que, // 数据请求线高电平请求三个数据直到读取完才拉低
output out_clk, output wire out_clk,
output out_en, output wire out_en,
output [31:0] data_out output reg [3 * COLOR_DEPTH - 1:0] data_out
); );
// 三通道合成RGB图像 // 三通道合成RGB图像
wire rgb_en; wire rgb_en;
wire [15:0] im_red, im_green, im_blue;
// 任意比例缩放图像 // 任意比例缩放图像
reg scale_in_en; reg scale_in_en;
@ -35,11 +34,13 @@ module isp #(
// wire RAM_in_que; // RAM 请求数据 // wire RAM_in_que; // RAM 请求数据
// wire [3 * COLOR_DEPTH - 1:0] RAM_in_data; // wire [3 * COLOR_DEPTH - 1:0] RAM_in_data;
assign out_clk = clk; always @(clk)
out_clk <= clk;
demosaic2 #( demosaic2 #(
.IM_WIDTH(1936), .IM_WIDTH(1936),
.IM_HEIGHT(1088), .IM_HEIGHT(1088),
.RAW_TYPE(RAW_TYPE)
) CFA ( ) CFA (
.clk(clk), .clk(clk),
.reset(reset), .reset(reset),
@ -63,7 +64,11 @@ module isp #(
.data_out(scale_in_data) .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), .clk(clk),
.reset(reset), .reset(reset),

View File

@ -13,10 +13,109 @@
// Include model header, generated from Verilating "isp.v" // Include model header, generated from Verilating "isp.v"
#include "Visp.h" #include "Visp.h"
// Handle file
#include <fstream>
#include <iostream>
#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_core;
using namespace sc_dt; using namespace sc_dt;
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> im_clk;
sc_in<bool> im_en;
sc_in<uint32_t> 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[]) { 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. // 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 // 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 // Define clocks
sc_clock clk{"clk", 10, SC_NS, 0.5, 3, SC_NS, true}; 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 // Define interconnect
sc_signal<bool> reset_l; sc_signal<bool> reset;
sc_signal<uint32_t> in_small;
sc_signal<uint64_t> in_quad; sc_signal<bool> data_en;
sc_signal<sc_bv<70>> in_wide; sc_signal<bool> data_que;
sc_signal<uint32_t> out_small; sc_signal<uint32_t> data_in[3];
sc_signal<uint64_t> out_quad;
sc_signal<sc_bv<70>> out_wide; sc_signal<bool> out_clk;
sc_signal<bool> out_en;
sc_signal<uint32_t> data_out;
// Construct the Verilated model, from inside Visp.h // 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"}}; const std::unique_ptr<Visp> isp{new Visp{"isp"}};
// Attach Visp's signals to this upper model // Attach Visp's signals to this upper model
isp->clk(clk); isp->clk(clk);
isp->fastclk(fastclk); isp->reset(reset);
isp->reset_l(reset_l); isp->data_en(data_en);
isp->in_small(in_small); isp->data_que(data_que);
isp->in_quad(in_quad); isp->data_in[0](data_in[0]);
isp->in_wide(in_wide); isp->data_in[1](data_in[1]);
isp->out_small(out_small); isp->data_in[2](data_in[2]);
isp->out_quad(out_quad); isp->out_clk(out_clk);
isp->out_wide(out_wide); 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 // You must do one evaluation before enabling waves, in order to allow
// SystemC to interconnect everything for testing. // SystemC to interconnect everything for testing.
@ -91,10 +205,10 @@ int sc_main(int argc, char* argv[]) {
if (tfp) tfp->flush(); if (tfp) tfp->flush();
// Apply inputs // Apply inputs
if (sc_time_stamp() > sc_time(1, SC_NS) && sc_time_stamp() < sc_time(10, SC_NS)) { if (sc_time_stamp() < sc_time(10, SC_NS)) {
reset_l = !1; // Assert reset reset.write(1); // Assert reset
} else { } else {
reset_l = !0; // Deassert reset reset.write(0); // Deassert reset
} }
// Simulate 1ns // Simulate 1ns
@ -110,11 +224,11 @@ int sc_main(int argc, char* argv[]) {
tfp = nullptr; tfp = nullptr;
} }
// Coverage analysis (calling write only after the test is known to pass) // Save output image
#if VM_COVERAGE for (int y = 0; y < IM_HEIGHT; y++)
Verilated::mkdir("logs"); for(int x = 0; x < IM_WIDTH; x++)
VerilatedCov::write("logs/coverage.dat"); out_image.write((const char *)&tb_isp.out[y * IM_WIDTH + x], sizeof(tb_isp.out[0]));
#endif out_image.close();
// Return good completion status // Return good completion status
return 0; return 0;