add demosaic testbench using verilator
This commit is contained in:
		@@ -89,7 +89,7 @@ run:
 | 
			
		||||
	@echo "-- RUN ---------------------"
 | 
			
		||||
	@rm -rf logs
 | 
			
		||||
	@mkdir -p logs
 | 
			
		||||
	obj_dir/Vtop +trace
 | 
			
		||||
	obj_dir/V$(TOP_MODULE) +trace
 | 
			
		||||
 | 
			
		||||
	@echo
 | 
			
		||||
	@echo "-- COVERAGE ----------------"
 | 
			
		||||
 
 | 
			
		||||
@@ -5,19 +5,53 @@
 | 
			
		||||
#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 "top.v"
 | 
			
		||||
// 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[]) {
 | 
			
		||||
    // This is a more complicated example, please also see the simpler examples/make_hello_c.
 | 
			
		||||
    // 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);
 | 
			
		||||
    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);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // 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");
 | 
			
		||||
@@ -30,7 +64,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
 | 
			
		||||
@@ -45,17 +80,33 @@ int sc_main(int argc, char* argv[]) {
 | 
			
		||||
 | 
			
		||||
    // Define interconnect
 | 
			
		||||
    sc_signal<bool> reset;
 | 
			
		||||
    sc_signal<uint32_t> in_small;
 | 
			
		||||
 | 
			
		||||
    sc_signal<bool> in_en;
 | 
			
		||||
    sc_signal<bool> in_que;
 | 
			
		||||
    sc_signal<bool> in_line;
 | 
			
		||||
    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> top{new Vdemosaic2{"top"}};
 | 
			
		||||
    // 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
 | 
			
		||||
    top->clk(clk);
 | 
			
		||||
    top->reset(reset);
 | 
			
		||||
 | 
			
		||||
    demo->clk(clk);
 | 
			
		||||
    demo->reset(reset);
 | 
			
		||||
    demo->data_en(in_en);
 | 
			
		||||
    demo->data_que(in_que);
 | 
			
		||||
    demo->data_line(in_line);
 | 
			
		||||
    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.
 | 
			
		||||
@@ -68,22 +119,49 @@ int sc_main(int argc, char* argv[]) {
 | 
			
		||||
    if (flag && 0 == std::strcmp(flag, "+trace")) {
 | 
			
		||||
        std::cout << "Enabling waves into logs/vlt_dump.vcd...\n";
 | 
			
		||||
        tfp = new VerilatedVcdSc;
 | 
			
		||||
        top->trace(tfp, 99);  // Trace 99 levels of hierarchy
 | 
			
		||||
        demo->trace(tfp, 99);  // Trace 99 levels of hierarchy
 | 
			
		||||
        Verilated::mkdir("logs");
 | 
			
		||||
        tfp->open("logs/vlt_dump.vcd");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Simulate until $finish
 | 
			
		||||
    uint16_t pos_x = 0, pos_y = 0;
 | 
			
		||||
    uint32_t out[IM_SIZE] = {0}, 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(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
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // Send image data and Read RGB image data
 | 
			
		||||
        if (sc_time_stamp() > sc_time(10, SC_NS) && clk.posedge()) {
 | 
			
		||||
            // Send image data to demosaic
 | 
			
		||||
            if (in_que.read() && pos_y < IM_HEIGHT) {
 | 
			
		||||
                in_en.write(1);
 | 
			
		||||
                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);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // Simulate 1ns
 | 
			
		||||
@@ -91,7 +169,7 @@ int sc_main(int argc, char* argv[]) {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Final model cleanup
 | 
			
		||||
    top->final();
 | 
			
		||||
    demo->final();
 | 
			
		||||
 | 
			
		||||
    // Close trace if opened
 | 
			
		||||
    if (tfp) {
 | 
			
		||||
@@ -104,6 +182,13 @@ int sc_main(int argc, char* argv[]) {
 | 
			
		||||
    Verilated::mkdir("logs");
 | 
			
		||||
    VerilatedCov::write("logs/coverage.dat");
 | 
			
		||||
#endif
 | 
			
		||||
    // 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;
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user