finish sim
This commit is contained in:
		
							
								
								
									
										3
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										3
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							@@ -10,4 +10,5 @@
 | 
			
		||||
*.tif
 | 
			
		||||
*.bin
 | 
			
		||||
*.dat
 | 
			
		||||
*.png
 | 
			
		||||
*.png
 | 
			
		||||
!im.tif
 | 
			
		||||
@@ -1,114 +0,0 @@
 | 
			
		||||
######################################################################
 | 
			
		||||
#
 | 
			
		||||
# DESCRIPTION: Verilator Example: Small Makefile
 | 
			
		||||
#
 | 
			
		||||
# This calls the object directory makefile.  That allows the objects to
 | 
			
		||||
# be placed in the "current directory" which simplifies the Makefile.
 | 
			
		||||
#
 | 
			
		||||
# This file ONLY is placed under the Creative Commons Public Domain, for
 | 
			
		||||
# any use, without warranty, 2020 by Wilson Snyder.
 | 
			
		||||
# SPDX-License-Identifier: CC0-1.0
 | 
			
		||||
#
 | 
			
		||||
######################################################################
 | 
			
		||||
# Check for sanity to avoid later confusion
 | 
			
		||||
 | 
			
		||||
ifneq ($(words $(CURDIR)),1)
 | 
			
		||||
 $(error Unsupported: GNU Make cannot build in directories containing spaces, build elsewhere: '$(CURDIR)')
 | 
			
		||||
endif
 | 
			
		||||
 | 
			
		||||
######################################################################
 | 
			
		||||
# Set up variables
 | 
			
		||||
 | 
			
		||||
# If $VERILATOR_ROOT isn't in the environment, we assume it is part of a
 | 
			
		||||
# package install, and verilator is in your path. Otherwise find the
 | 
			
		||||
# binary relative to $VERILATOR_ROOT (such as when inside the git sources).
 | 
			
		||||
ifeq ($(VERILATOR_ROOT),)
 | 
			
		||||
VERILATOR = verilator
 | 
			
		||||
VERILATOR_COVERAGE = verilator_coverage
 | 
			
		||||
else
 | 
			
		||||
export VERILATOR_ROOT
 | 
			
		||||
VERILATOR = $(VERILATOR_ROOT)/bin/verilator
 | 
			
		||||
VERILATOR_COVERAGE = $(VERILATOR_ROOT)/bin/verilator_coverage
 | 
			
		||||
endif
 | 
			
		||||
 | 
			
		||||
VERILATOR_FLAGS =
 | 
			
		||||
# Generate SystemC in executable form
 | 
			
		||||
VERILATOR_FLAGS += -sc --exe
 | 
			
		||||
# Generate makefile dependencies (not shown as complicates the Makefile)
 | 
			
		||||
#VERILATOR_FLAGS += -MMD
 | 
			
		||||
# Optimize
 | 
			
		||||
# VERILATOR_FLAGS += -x-assign fast
 | 
			
		||||
# Warn abount lint issues; may not want this on less solid designs
 | 
			
		||||
VERILATOR_FLAGS += -Wall
 | 
			
		||||
# Make waveforms
 | 
			
		||||
VERILATOR_FLAGS += --trace
 | 
			
		||||
# Check SystemVerilog assertions
 | 
			
		||||
VERILATOR_FLAGS += --assert
 | 
			
		||||
# Generate coverage analysis
 | 
			
		||||
# VERILATOR_FLAGS += --coverage
 | 
			
		||||
# Run Verilator in debug mode
 | 
			
		||||
#VERILATOR_FLAGS += --debug
 | 
			
		||||
# Add this trace to get a backtrace in gdb
 | 
			
		||||
#VERILATOR_FLAGS += --gdbbt
 | 
			
		||||
# Specify top module
 | 
			
		||||
TOP_MODULE = demosaic2
 | 
			
		||||
VERILATOR_FLAGS += -top $(TOP_MODULE)
 | 
			
		||||
 | 
			
		||||
# Input files for Verilator
 | 
			
		||||
VERILATOR_INPUT = ../demosaic2.v sc_demosaic.cpp
 | 
			
		||||
 | 
			
		||||
# Check if SC exists via a verilator call (empty if not)
 | 
			
		||||
SYSTEMC_EXISTS := $(shell $(VERILATOR) --get-supported SYSTEMC)
 | 
			
		||||
 | 
			
		||||
######################################################################
 | 
			
		||||
 | 
			
		||||
ifneq ($(SYSTEMC_EXISTS),)
 | 
			
		||||
default: run
 | 
			
		||||
else
 | 
			
		||||
default: nosc
 | 
			
		||||
endif
 | 
			
		||||
 | 
			
		||||
run:
 | 
			
		||||
	@echo
 | 
			
		||||
	@echo "-- Verilator tracing example"
 | 
			
		||||
 | 
			
		||||
	@echo
 | 
			
		||||
	@echo "-- VERILATE ----------------"
 | 
			
		||||
	$(VERILATOR) $(VERILATOR_FLAGS) $(VERILATOR_INPUT)
 | 
			
		||||
 | 
			
		||||
	@echo
 | 
			
		||||
	@echo "-- COMPILE -----------------"
 | 
			
		||||
# To compile, we can either
 | 
			
		||||
# 1. Pass --build to Verilator by editing VERILATOR_FLAGS above.
 | 
			
		||||
# 2. Or, run the make rules Verilator does:
 | 
			
		||||
#	$(MAKE) -j -C obj_dir -f Vtop.mk
 | 
			
		||||
# 3. Or, call a submakefile where we can override the rules ourselves:
 | 
			
		||||
	$(MAKE) -j -C obj_dir -f V$(TOP_MODULE).mk
 | 
			
		||||
 | 
			
		||||
	@echo
 | 
			
		||||
	@echo "-- RUN ---------------------"
 | 
			
		||||
	@rm -rf logs
 | 
			
		||||
	@mkdir -p logs
 | 
			
		||||
	obj_dir/V$(TOP_MODULE) +trace
 | 
			
		||||
 | 
			
		||||
	@echo
 | 
			
		||||
	@echo "-- DONE --------------------"
 | 
			
		||||
	@echo "To see waveforms, open vlt_dump.vcd in a waveform viewer"
 | 
			
		||||
	@echo
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
######################################################################
 | 
			
		||||
# Other targets
 | 
			
		||||
 | 
			
		||||
nosc:
 | 
			
		||||
	@echo
 | 
			
		||||
	@echo "%Skip: SYSTEMC_INCLUDE not in environment"
 | 
			
		||||
	@echo "(If you have SystemC see the README, and rebuild Verilator)"
 | 
			
		||||
	@echo
 | 
			
		||||
 | 
			
		||||
show-config:
 | 
			
		||||
	$(VERILATOR) -V
 | 
			
		||||
 | 
			
		||||
maintainer-copy::
 | 
			
		||||
clean mostlyclean distclean maintainer-clean::
 | 
			
		||||
	-rm -rf obj_dir logs *.log *.dmp *.vpd coverage.dat core
 | 
			
		||||
@@ -1,208 +0,0 @@
 | 
			
		||||
// For std::unique_ptr
 | 
			
		||||
#include <memory>
 | 
			
		||||
 | 
			
		||||
// SystemC global header
 | 
			
		||||
#include <systemc>
 | 
			
		||||
 | 
			
		||||
// Include common routines
 | 
			
		||||
#include <sys/stat.h>  // mkdir
 | 
			
		||||
#include <verilated.h>
 | 
			
		||||
#include <verilated_vcd_sc.h>
 | 
			
		||||
 | 
			
		||||
// Include model header, generated from Verilating "demo.v"
 | 
			
		||||
#include "Vdemosaic2.h"
 | 
			
		||||
 | 
			
		||||
// Handle file
 | 
			
		||||
#include <fstream>
 | 
			
		||||
#include <iostream>
 | 
			
		||||
 | 
			
		||||
#define IM_WIDTH 512
 | 
			
		||||
#define IM_HEIGHT 256
 | 
			
		||||
#define IM_SIZE (IM_WIDTH * IM_HEIGHT)
 | 
			
		||||
 | 
			
		||||
using namespace std;
 | 
			
		||||
using namespace sc_core;
 | 
			
		||||
using namespace sc_dt;
 | 
			
		||||
 | 
			
		||||
int sc_main(int argc, char* argv[]) {
 | 
			
		||||
    // Open image
 | 
			
		||||
    ifstream in_image;
 | 
			
		||||
    ofstream out_image;
 | 
			
		||||
    in_image.open("./transform/test.bin", ios::in | ios::binary);
 | 
			
		||||
    out_image.open("./transform/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);
 | 
			
		||||
    // for (uint32_t i = 0; i < IM_SIZE * 2; i++)
 | 
			
		||||
    //     printf("0x%02x\t", buf[i]);
 | 
			
		||||
    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++;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // 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");
 | 
			
		||||
 | 
			
		||||
    // Set debug level, 0 is off, 9 is highest presently used
 | 
			
		||||
    // May be overridden by commandArgs argument parsing
 | 
			
		||||
    Verilated::debug(0);
 | 
			
		||||
 | 
			
		||||
    // Randomization reset policy
 | 
			
		||||
    // May be overridden by commandArgs argument parsing
 | 
			
		||||
    Verilated::randReset(2);
 | 
			
		||||
 | 
			
		||||
    // 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
 | 
			
		||||
    // This needs to be called before you create any model
 | 
			
		||||
    Verilated::commandArgs(argc, argv);
 | 
			
		||||
 | 
			
		||||
    // General logfile
 | 
			
		||||
    std::ios::sync_with_stdio();
 | 
			
		||||
 | 
			
		||||
    // Define clocks
 | 
			
		||||
    sc_clock clk{"clk", 10, SC_NS, 0.5, 3, SC_NS, true};
 | 
			
		||||
 | 
			
		||||
    // Define interconnect
 | 
			
		||||
    sc_signal<bool> reset;
 | 
			
		||||
 | 
			
		||||
    sc_signal<bool> in_en;
 | 
			
		||||
    sc_signal<bool> in_que;
 | 
			
		||||
    sc_signal<uint32_t> data_in[3];
 | 
			
		||||
 | 
			
		||||
    sc_signal<bool> out_en;
 | 
			
		||||
    sc_signal<uint32_t> out_r, out_g, out_b;
 | 
			
		||||
 | 
			
		||||
    // Construct the Verilated model, from inside Vtop.h
 | 
			
		||||
    // Using unique_ptr is similar to "Vtop* top = new Vtop" then deleting at
 | 
			
		||||
    // end
 | 
			
		||||
    const std::unique_ptr<Vdemosaic2> demo{new Vdemosaic2{"demo"}};
 | 
			
		||||
 | 
			
		||||
    // Attach Vtop's signals to this upper model
 | 
			
		||||
    demo->clk(clk);
 | 
			
		||||
    demo->reset(reset);
 | 
			
		||||
    demo->data_en(in_en);
 | 
			
		||||
    demo->data_que(in_que);
 | 
			
		||||
    demo->data_in[0](data_in[0]);
 | 
			
		||||
    demo->data_in[1](data_in[1]);
 | 
			
		||||
    demo->data_in[2](data_in[2]);
 | 
			
		||||
    demo->out_en(out_en);
 | 
			
		||||
    demo->out_r(out_r);
 | 
			
		||||
    demo->out_g(out_g);
 | 
			
		||||
    demo->out_b(out_b);
 | 
			
		||||
 | 
			
		||||
    // You must do one evaluation before enabling waves, in order to allow
 | 
			
		||||
    // SystemC to interconnect everything for testing.
 | 
			
		||||
    sc_start(SC_ZERO_TIME);
 | 
			
		||||
 | 
			
		||||
    // If verilator was invoked with --trace argument,
 | 
			
		||||
    // and if at run time passed the +trace argument, turn on tracing
 | 
			
		||||
    VerilatedVcdSc* tfp = nullptr;
 | 
			
		||||
    const char* flag = Verilated::commandArgsPlusMatch("trace");
 | 
			
		||||
    if (flag && 0 == std::strcmp(flag, "+trace")) {
 | 
			
		||||
        std::cout << "Enabling waves into logs/vlt_dump.vcd...\n";
 | 
			
		||||
        tfp = new VerilatedVcdSc;
 | 
			
		||||
        demo->trace(tfp, 99);  // Trace 99 levels of hierarchy
 | 
			
		||||
        Verilated::mkdir("logs");
 | 
			
		||||
        tfp->open("logs/vlt_dump.vcd");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Simulate until $finish
 | 
			
		||||
    bool flag_posedge = 0;
 | 
			
		||||
    bool clk_last = 0, clk_now = 0;
 | 
			
		||||
    uint16_t pos_x = 0, pos_y = 0;
 | 
			
		||||
    uint16_t out[IM_SIZE] = {0};
 | 
			
		||||
    uint32_t out_head = 0;
 | 
			
		||||
    while (!Verilated::gotFinish()) {
 | 
			
		||||
        // Flush the wave files each cycle so we can immediately see the output
 | 
			
		||||
        // Don't do this in "real" programs, do it in an abort() handler instead
 | 
			
		||||
        if (tfp) tfp->flush();
 | 
			
		||||
 | 
			
		||||
        // Apply inputs
 | 
			
		||||
        if (sc_time_stamp() < sc_time(10, SC_NS)) {
 | 
			
		||||
            reset.write(1);  // Assert reset
 | 
			
		||||
        } else {
 | 
			
		||||
            reset.write(0);  // Deassert reset
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // Clock posedge generatre
 | 
			
		||||
        clk_now = clk.read();
 | 
			
		||||
        if (!clk_last && clk_now)
 | 
			
		||||
            flag_posedge = 1;
 | 
			
		||||
        clk_last = clk_now;
 | 
			
		||||
 | 
			
		||||
        // Send image data and Read RGB image data
 | 
			
		||||
        if (sc_time_stamp() > sc_time(10, SC_NS) && flag_posedge) {
 | 
			
		||||
            flag_posedge = 0;
 | 
			
		||||
            // Send image data to demosaic
 | 
			
		||||
            if (in_que.read() && pos_y < IM_HEIGHT - 2) {
 | 
			
		||||
                in_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_in[0].write(image[pos_y + 0][pos_x++]);
 | 
			
		||||
                data_in[1].write(image[pos_y + 1][pos_x++]);
 | 
			
		||||
                data_in[2].write(image[pos_y + 2][pos_x++]);
 | 
			
		||||
 | 
			
		||||
                if (pos_x >= IM_WIDTH) {
 | 
			
		||||
                    pos_x = 0;
 | 
			
		||||
                    pos_y++;
 | 
			
		||||
                }
 | 
			
		||||
            } else {
 | 
			
		||||
                in_en.write(0);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            // Read image data
 | 
			
		||||
            if (out_en.read()) {
 | 
			
		||||
                out[out_head++] = ((uint8_t)(out_r.read() * 5 / 12) << 10) +
 | 
			
		||||
                                  ((uint8_t)(out_g.read() * 5 / 12) << 5) +
 | 
			
		||||
                                  ((uint8_t)(out_b.read() * 5 / 12) << 0);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (sc_time_stamp() > sc_time(2600, SC_US))
 | 
			
		||||
            break;
 | 
			
		||||
        // Simulate 1ns
 | 
			
		||||
        sc_start(1, SC_NS);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Final model cleanup
 | 
			
		||||
    demo->final();
 | 
			
		||||
 | 
			
		||||
    // Close trace if opened
 | 
			
		||||
    if (tfp) {
 | 
			
		||||
        tfp->close();
 | 
			
		||||
        tfp = nullptr;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Save final output image
 | 
			
		||||
    for (uint32_t i = 0; i < IM_SIZE; i++) {
 | 
			
		||||
        buf[i * 2] = (out[i] & 0xffff0000) >> 16;
 | 
			
		||||
        buf[i * 2 + 1] = (out[i] & 0x0000ffff);
 | 
			
		||||
    }
 | 
			
		||||
    out_image.write((const char*)buf, 2 * IM_SIZE);
 | 
			
		||||
    out_image.close();
 | 
			
		||||
 | 
			
		||||
    // Return good completion status
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
@@ -1,169 +0,0 @@
 | 
			
		||||
`timescale 1ns/10ps
 | 
			
		||||
`define End_CYCLE 100000000
 | 
			
		||||
`define cycle 40.0
 | 
			
		||||
 | 
			
		||||
`define PAT "./test.dat"  
 | 
			
		||||
`define OUT_F "./test.raw"
 | 
			
		||||
 | 
			
		||||
module tb_demosaic();
 | 
			
		||||
 | 
			
		||||
parameter WIDTH = 512;
 | 
			
		||||
parameter HEIGHT = 256;
 | 
			
		||||
parameter IMG_SIZE = WIDTH * HEIGHT;
 | 
			
		||||
 | 
			
		||||
integer out_f, i, in_count, cycle_count;
 | 
			
		||||
 | 
			
		||||
reg clk;
 | 
			
		||||
reg reset;
 | 
			
		||||
reg in_en;
 | 
			
		||||
reg flag;
 | 
			
		||||
wire wr_r, wr_g, wr_b;
 | 
			
		||||
wire done;
 | 
			
		||||
wire [13:0] addr_r, addr_g, addr_b;
 | 
			
		||||
wire [7:0] wdata_r, wdata_g, wdata_b;
 | 
			
		||||
reg [7:0] pixel, rdata_r, rdata_g, rdata_b;
 | 
			
		||||
 | 
			
		||||
reg	[7:0] PAT [0:IMG_SIZE-1];
 | 
			
		||||
reg [7:0] MEM_R [0:IMG_SIZE-1];
 | 
			
		||||
reg [7:0] MEM_G [0:IMG_SIZE-1];
 | 
			
		||||
reg [7:0] MEM_B [0:IMG_SIZE-1];
 | 
			
		||||
 | 
			
		||||
demosaic #(
 | 
			
		||||
    WIDTH,
 | 
			
		||||
    HEIGHT
 | 
			
		||||
) u_demosaic (
 | 
			
		||||
    .clk(clk),
 | 
			
		||||
    .reset(reset),
 | 
			
		||||
    .in_en(in_en),
 | 
			
		||||
    .data_in(pixel),
 | 
			
		||||
    .wr_r(wr_r),
 | 
			
		||||
    .addr_r(addr_r),
 | 
			
		||||
    .wdata_r(wdata_r),
 | 
			
		||||
    .rdata_r(rdata_r), 
 | 
			
		||||
    .wr_g(wr_g),
 | 
			
		||||
    .addr_g(addr_g),
 | 
			
		||||
    .wdata_g(wdata_g),
 | 
			
		||||
    .rdata_g(rdata_g),
 | 
			
		||||
    .wr_b(wr_b),
 | 
			
		||||
    .addr_b(addr_b),
 | 
			
		||||
    .wdata_b(wdata_b),
 | 
			
		||||
    .rdata_b(rdata_b),
 | 
			
		||||
    .done(done)
 | 
			
		||||
);
 | 
			
		||||
 | 
			
		||||
initial begin
 | 
			
		||||
	out_f = $fopen(`OUT_F, "wb");
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
initial begin  
 | 
			
		||||
	$readmemh(`PAT, PAT);
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
initial begin
 | 
			
		||||
	clk = 0;
 | 
			
		||||
	reset = 0;
 | 
			
		||||
	in_en = 0;
 | 
			
		||||
	in_count = 0;
 | 
			
		||||
	cycle_count = 0;
 | 
			
		||||
	pixel = 'hx;
 | 
			
		||||
	rdata_r = 'hx;
 | 
			
		||||
	rdata_g = 'hx;
 | 
			
		||||
	rdata_b = 'hx;
 | 
			
		||||
	flag = 0;
 | 
			
		||||
	for(i = 0; i < IMG_SIZE; i = i + 1) begin
 | 
			
		||||
		MEM_R[i] = 0;
 | 
			
		||||
		MEM_G[i] = 0;
 | 
			
		||||
		MEM_B[i] = 0;
 | 
			
		||||
	end
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
always #(`cycle/2) clk = ~clk;
 | 
			
		||||
 | 
			
		||||
initial begin
 | 
			
		||||
    $display("********************************************************************");
 | 
			
		||||
    $display("**                        Simulation Start                        **");
 | 
			
		||||
    $display("********************************************************************");
 | 
			
		||||
    @(posedge clk); #2 reset = 1'b1; 
 | 
			
		||||
    #(`cycle*2);  
 | 
			
		||||
    @(posedge clk); #2 reset = 1'b0;
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
initial begin    
 | 
			
		||||
	@(posedge clk);
 | 
			
		||||
	# (`cycle*3) flag = 1;
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
always @ (negedge clk or posedge reset) begin // send mosaic image
 | 
			
		||||
  	if(reset) begin
 | 
			
		||||
		pixel <= 0;
 | 
			
		||||
		in_en <= 0;
 | 
			
		||||
  	end
 | 
			
		||||
  	else begin
 | 
			
		||||
		if(flag) begin
 | 
			
		||||
			if(in_count <= IMG_SIZE-1) begin
 | 
			
		||||
				in_en <= 1;
 | 
			
		||||
				in_count <= in_count + 1;
 | 
			
		||||
				pixel <= PAT[in_count];
 | 
			
		||||
			end
 | 
			
		||||
			else begin 
 | 
			
		||||
				in_en <= 0;
 | 
			
		||||
				pixel <= 'hx;
 | 
			
		||||
			end
 | 
			
		||||
		end
 | 
			
		||||
	end
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
always @ (negedge clk) begin // read memory, send data to module
 | 
			
		||||
	if(!wr_r)
 | 
			
		||||
		rdata_r <= MEM_R[addr_r];
 | 
			
		||||
	else 
 | 
			
		||||
		rdata_r <= 'hx;
 | 
			
		||||
	if(!wr_g)
 | 
			
		||||
		rdata_g <= MEM_G[addr_g];
 | 
			
		||||
	else 
 | 
			
		||||
		rdata_g <= 'hx;
 | 
			
		||||
	if(!wr_b)
 | 
			
		||||
		rdata_b <= MEM_B[addr_b];
 | 
			
		||||
	else 
 | 
			
		||||
		rdata_b <= 'hx; 
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
always @ (negedge clk) begin // write memory, read data and save
 | 
			
		||||
	if(wr_r) begin
 | 
			
		||||
		MEM_R[addr_r] <= wdata_r;
 | 
			
		||||
	end
 | 
			
		||||
	if(wr_g) begin
 | 
			
		||||
		MEM_G[addr_g] <= wdata_g;
 | 
			
		||||
	end
 | 
			
		||||
	if(wr_b) begin
 | 
			
		||||
		MEM_B[addr_b] <= wdata_b;
 | 
			
		||||
	end
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
always @ (posedge clk) begin // count cycle
 | 
			
		||||
	cycle_count <= cycle_count + 1;
 | 
			
		||||
	if(cycle_count >= `End_CYCLE) begin
 | 
			
		||||
		$display("********************************************************************");
 | 
			
		||||
		$display("**                    Fail waiting done signal                    **");
 | 
			
		||||
		$display("**             You can increase END_CYCLE by yourself             **");
 | 
			
		||||
		$display("********************************************************************");
 | 
			
		||||
		$finish;
 | 
			
		||||
	end
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
always @ (posedge clk) begin // check result
 | 
			
		||||
	if(done) begin
 | 
			
		||||
		for(i = 0; i < IMG_SIZE; i = i + 1) begin
 | 
			
		||||
            $fwrite(out_f, "%c", MEM_R[i]);
 | 
			
		||||
            $fwrite(out_f, "%c", MEM_G[i]);
 | 
			
		||||
            $fwrite(out_f, "%c", MEM_B[i]);
 | 
			
		||||
		end
 | 
			
		||||
		$fclose(out_f);
 | 
			
		||||
		$display("********************************************************************");
 | 
			
		||||
		$display("**               Simulation completed successfully!               **");
 | 
			
		||||
		$display("********************************************************************");	
 | 
			
		||||
		$finish;
 | 
			
		||||
	end
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
endmodule
 | 
			
		||||
							
								
								
									
										6
									
								
								isp.v
									
									
									
									
									
								
							
							
						
						
									
										6
									
								
								isp.v
									
									
									
									
									
								
							@@ -1,8 +1,8 @@
 | 
			
		||||
`timescale 1ns/1ps
 | 
			
		||||
 | 
			
		||||
module isp #(
 | 
			
		||||
    parameter IN_WIDTH = 1936,
 | 
			
		||||
    parameter IN_HEIGHT = 1088,
 | 
			
		||||
    parameter IN_WIDTH = 700,
 | 
			
		||||
    parameter IN_HEIGHT = 500,
 | 
			
		||||
    parameter OUT_WIDTH = 640,
 | 
			
		||||
    parameter OUT_HEIGHT = 480,
 | 
			
		||||
    parameter COLOR_DEPTH = 8,
 | 
			
		||||
@@ -66,6 +66,8 @@ module isp #(
 | 
			
		||||
    );
 | 
			
		||||
 | 
			
		||||
    crop #(
 | 
			
		||||
        .IN_WIDTH(IN_WIDTH),
 | 
			
		||||
        .IN_HEIGHT(IN_HEIGHT),
 | 
			
		||||
        .OUT_WIDTH(OUT_WIDTH),
 | 
			
		||||
        .OUT_HEIGHT(OUT_HEIGHT),
 | 
			
		||||
        .COLOR_DEPTH(COLOR_DEPTH)
 | 
			
		||||
 
 | 
			
		||||
@@ -44,6 +44,8 @@ VERILATOR_FLAGS += -Wall
 | 
			
		||||
VERILATOR_FLAGS += --trace
 | 
			
		||||
# Check SystemVerilog assertions
 | 
			
		||||
VERILATOR_FLAGS += --assert
 | 
			
		||||
# Enable multithreading
 | 
			
		||||
# VERILATOR_FLAGS += --threads 4
 | 
			
		||||
# Generate coverage analysis
 | 
			
		||||
# VERILATOR_FLAGS += --coverage
 | 
			
		||||
# Run Verilator in debug mode
 | 
			
		||||
 
 | 
			
		||||
@@ -17,9 +17,12 @@
 | 
			
		||||
#include <fstream>
 | 
			
		||||
#include <iostream>
 | 
			
		||||
 | 
			
		||||
#define IM_WIDTH 1936
 | 
			
		||||
#define IM_HEIGHT 1088
 | 
			
		||||
#define IM_SIZE (IM_WIDTH * IM_HEIGHT)
 | 
			
		||||
#define IN_WIDTH 700
 | 
			
		||||
#define IN_HEIGHT 500
 | 
			
		||||
#define IN_SIZE (IN_WIDTH * IN_HEIGHT)
 | 
			
		||||
#define OUT_WIDTH 640
 | 
			
		||||
#define OUT_HEIGHT 480
 | 
			
		||||
#define OUT_SIZE (OUT_WIDTH * OUT_HEIGHT)
 | 
			
		||||
 | 
			
		||||
using namespace std;
 | 
			
		||||
using namespace sc_core;
 | 
			
		||||
@@ -37,11 +40,9 @@ SC_MODULE (TB_ISP) {
 | 
			
		||||
    sc_in<bool> im_en;
 | 
			
		||||
    sc_in<uint32_t> im_data;
 | 
			
		||||
 | 
			
		||||
    // uint16_t image[IM_HEIGHT][IM_WIDTH];
 | 
			
		||||
    // uint32_t out[IM_HEIGHT][IM_WIDTH];
 | 
			
		||||
    // uint32_t out_head = 0;
 | 
			
		||||
    unique_ptr<uint16_t[]> image = make_unique<uint16_t[]>(IM_SIZE);
 | 
			
		||||
    unique_ptr<uint32_t[]> out = make_unique<uint32_t[]>(IM_SIZE);
 | 
			
		||||
    sc_out<bool> is_done;
 | 
			
		||||
    unique_ptr<uint16_t[]> image;
 | 
			
		||||
    unique_ptr<uint32_t[]> out = make_unique<uint32_t[]>(OUT_SIZE);
 | 
			
		||||
 | 
			
		||||
    SC_CTOR (TB_ISP) {
 | 
			
		||||
        SC_CTHREAD(send_Data, clk.pos());
 | 
			
		||||
@@ -54,21 +55,21 @@ SC_MODULE (TB_ISP) {
 | 
			
		||||
        uint16_t pos_x = 0, pos_y = 0;
 | 
			
		||||
        while (true)
 | 
			
		||||
        {
 | 
			
		||||
            if (data_que.read() && pos_y < IM_HEIGHT - 2) {
 | 
			
		||||
            if (data_que.read() && pos_y < IN_HEIGHT - 2) {
 | 
			
		||||
                data_en.write(1);
 | 
			
		||||
 | 
			
		||||
                printf("x=%3d, y=%3d, data=0x%04x\t", pos_x, pos_y, image[( pos_y + 0 ) * IM_WIDTH + pos_x]);
 | 
			
		||||
                printf("x=%3d, y=%3d, data=0x%04x\t", pos_x, pos_y, image[( pos_y + 1 ) * IM_WIDTH + pos_x]);
 | 
			
		||||
                printf("x=%3d, y=%3d, data=0x%04x\n", pos_x, pos_y, image[( pos_y + 2 ) * IM_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 ) * IM_WIDTH + pos_x]);
 | 
			
		||||
                data_out[1].write(image[( pos_y + 1 ) * IM_WIDTH + pos_x]);
 | 
			
		||||
                data_out[2].write(image[( pos_y + 2 ) * IM_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]);
 | 
			
		||||
 | 
			
		||||
                wait(1);
 | 
			
		||||
                data_en.write(0);
 | 
			
		||||
 | 
			
		||||
                if (pos_x++ >= IM_WIDTH) {
 | 
			
		||||
                if (pos_x++ >= IN_WIDTH) {
 | 
			
		||||
                    pos_x = 0;
 | 
			
		||||
                    pos_y++;
 | 
			
		||||
                }
 | 
			
		||||
@@ -82,18 +83,31 @@ SC_MODULE (TB_ISP) {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    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)
 | 
			
		||||
        {
 | 
			
		||||
            if (im_en.read()) {
 | 
			
		||||
                out[pos_y * IM_WIDTH + pos_x] = im_data.read();
 | 
			
		||||
                out[pos_y * OUT_WIDTH + pos_x] = im_data.read();
 | 
			
		||||
 | 
			
		||||
                if (pos_x++ >= IM_WIDTH) {
 | 
			
		||||
                if (pos_x++ >= OUT_WIDTH) {
 | 
			
		||||
                    pos_x = 0;
 | 
			
		||||
                    pos_y++;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if (last_data == im_data.read()) {
 | 
			
		||||
                cnt++;
 | 
			
		||||
                if (cnt >= 100) {
 | 
			
		||||
                    is_done.write(1);
 | 
			
		||||
                }
 | 
			
		||||
            } else {
 | 
			
		||||
                cnt = 0;
 | 
			
		||||
            }
 | 
			
		||||
            last_data = im_data.read();
 | 
			
		||||
 | 
			
		||||
            wait();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
@@ -104,7 +118,7 @@ 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);
 | 
			
		||||
    in_image.open("./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;
 | 
			
		||||
@@ -114,18 +128,18 @@ int sc_main(int argc, char* argv[]) {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Read image
 | 
			
		||||
    // uint8_t buf[IM_SIZE * 2] = {0};
 | 
			
		||||
    auto buf = make_unique<uint8_t[]>(2 * IM_SIZE);
 | 
			
		||||
    // vector<vector<uint8_t>> buf(IM_HEIGHT, vector<uint8_t>(IM_WIDTH, 0));
 | 
			
		||||
    in_image.read((char*)buf.get(), IM_SIZE * 2);
 | 
			
		||||
    // uint8_t buf[IN_SIZE * 2] = {0};
 | 
			
		||||
    auto buf = make_unique<uint8_t[]>(2 * IN_SIZE);
 | 
			
		||||
    // vector<vector<uint8_t>> buf(IN_HEIGHT, vector<uint8_t>(IN_WIDTH, 0));
 | 
			
		||||
    in_image.read((char*)buf.get(), IN_SIZE * 2);
 | 
			
		||||
    in_image.close();
 | 
			
		||||
    // Reshape data
 | 
			
		||||
    // uint16_t image[IM_HEIGHT][IM_WIDTH] = {0};
 | 
			
		||||
    auto image = make_unique<uint16_t[]>(IM_SIZE);
 | 
			
		||||
    // uint16_t image[IN_HEIGHT][IN_WIDTH] = {0};
 | 
			
		||||
    auto image = make_unique<uint16_t[]>(IN_SIZE);
 | 
			
		||||
    uint32_t i = 0;
 | 
			
		||||
    for (int y = 0; y < IM_HEIGHT; y++) {
 | 
			
		||||
        for (int x = 0; x < IM_WIDTH; x++) {
 | 
			
		||||
            image[y * IM_WIDTH + x] = (uint16_t)buf[i] + ((uint16_t)buf[i + 1] << 8);
 | 
			
		||||
    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);
 | 
			
		||||
            i += 2;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
@@ -167,6 +181,8 @@ int sc_main(int argc, char* argv[]) {
 | 
			
		||||
    sc_signal<bool> out_en;
 | 
			
		||||
    sc_signal<uint32_t> data_out;
 | 
			
		||||
 | 
			
		||||
    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
 | 
			
		||||
@@ -195,6 +211,7 @@ int sc_main(int argc, char* argv[]) {
 | 
			
		||||
    tb_isp.im_clk(out_clk);
 | 
			
		||||
    tb_isp.im_en(out_en);
 | 
			
		||||
    tb_isp.im_data(data_out);
 | 
			
		||||
    tb_isp.is_done(flag_done);
 | 
			
		||||
    tb_isp.image = move(image);
 | 
			
		||||
 | 
			
		||||
    // You must do one evaluation before enabling waves, in order to allow
 | 
			
		||||
@@ -226,6 +243,9 @@ int sc_main(int argc, char* argv[]) {
 | 
			
		||||
            reset.write(0);  // Deassert reset
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (flag_done.read())
 | 
			
		||||
            break;
 | 
			
		||||
 | 
			
		||||
        // Simulate 1ns
 | 
			
		||||
        sc_start(1, SC_NS);
 | 
			
		||||
    }
 | 
			
		||||
@@ -240,9 +260,10 @@ int sc_main(int argc, char* argv[]) {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // 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]));
 | 
			
		||||
    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.close();
 | 
			
		||||
 | 
			
		||||
    // Return good completion status
 | 
			
		||||
 
 | 
			
		||||
@@ -1,8 +1,8 @@
 | 
			
		||||
import imageio
 | 
			
		||||
import numpy as np
 | 
			
		||||
 | 
			
		||||
cut_width = 1936
 | 
			
		||||
cut_height = 1088
 | 
			
		||||
cut_width = 700
 | 
			
		||||
cut_height = 500
 | 
			
		||||
 | 
			
		||||
if __name__ == '__main__':
 | 
			
		||||
    # txt = open('./test.dat', 'w')
 | 
			
		||||
		Reference in New Issue
	
	Block a user