Skip to content

Commit

Permalink
Merge pull request #27 from ErickOF/dev
Browse files Browse the repository at this point in the history
Integrating the the interface of DE and TDF
  • Loading branch information
ErickOF authored Jul 23, 2024
2 parents fe80709 + 5e02840 commit cd22d5d
Show file tree
Hide file tree
Showing 12 changed files with 649 additions and 54 deletions.
12 changes: 9 additions & 3 deletions modules/adc/include/adc.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,15 +29,21 @@ SCA_TDF_MODULE(adc)
// Input analog voltage
sca_tdf::sca_in<double> in;
// Output digital code
sca_tdf::sca_out<sc_dt::sc_uint<BITS> > out;
sca_tdf::sca_de::sca_out<sc_dt::sc_uint<BITS> > out;

/**
* @brief Construct a new adc object
*
*/
SCA_CTOR(adc) : in("in"), out("out") {
SCA_CTOR(adc) : in("in"), out("out")
{
}

void set_attributes()
{
// Propagation time from input to output
set_timestep(sca_core::sca_time(0.1, sc_core::SC_US));
set_timestep(sca_core::sca_time(1, sc_core::SC_NS));
this->out.set_delay(13);
}

/**
Expand Down
20 changes: 15 additions & 5 deletions modules/adc/include/seq_item_adc.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,23 +7,33 @@
/**
* @brief This class is used to generate the analog signal for the test
*
* @tparam N
* @tparam N - the number of output bits of the digital code
* @tparam VMIN - lowest voltage value
* @tparam VMAX - highest voltage value
* @tparam VU - voltage unit based on VUnit
*/
template <unsigned int N>
template <unsigned int N = 8, int VMIN = 0, int VMAX = 5, VUnit VU = VUnit::v>
SCA_TDF_MODULE(seq_item_adc)
{
protected:
// Min voltage value based on the voltage units
const double V_MIN = static_cast<double>(VMIN) / static_cast<double>(VU);
// Max voltage value based on the voltage units
const double V_MAX = static_cast<double>(VMAX) / static_cast<double>(VU);
// Max digital output code
const int MAX_CODE = (1 << N);
public:
sca_tdf::sca_out<double> o_ana;
const int MAX_CODE = (1 << N);

SCA_CTOR(seq_item_adc)
{
set_timestep(sca_core::sca_time(0.1, sc_core::SC_US));
set_timestep(sca_core::sca_time(13, sc_core::SC_NS));
}

void processing()
{
this->o_ana.write(static_cast<double>(rand() % MAX_CODE) / MAX_CODE);
const double NORM_ANA = static_cast<double>(rand() % MAX_CODE) / MAX_CODE;
this->o_ana.write((V_MAX + V_MIN) * NORM_ANA + V_MIN);
}
};

Expand Down
8 changes: 5 additions & 3 deletions modules/adc/src/tb_adc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
#include "seq_item_adc.hpp"

#define N 8
#define VOLTAGE_MIN 0
#define VOLTAGE_MAX 3300


int sc_main(int, char*[])
Expand All @@ -15,12 +17,12 @@ int sc_main(int, char*[])
sca_tdf::sca_signal<sc_dt::sc_uint<N> > s_dig_out;

// DUT
adc<N> ips_adc("ips_adc");
adc<N, VOLTAGE_MIN, VOLTAGE_MAX, VUnit::mv> ips_adc("ips_adc");
ips_adc.in(s_ana);
ips_adc.out(s_dig_out);

// Sequence item generator for ADC
seq_item_adc<N> ips_seq_item_adc("ips_seq_item_adc");
seq_item_adc<N, VOLTAGE_MIN, VOLTAGE_MAX, VUnit::mv> ips_seq_item_adc("ips_seq_item_adc");
ips_seq_item_adc.o_ana(s_ana);

// Dump waveform
Expand All @@ -32,7 +34,7 @@ int sc_main(int, char*[])
std::cout << "@" << sc_time_stamp() << std::endl;

// Run test
sc_start(MAX_SEQ_ITEMS * 0.1, SC_US);
sc_start(MAX_SEQ_ITEMS * 13, SC_NS);

// End time
std::cout << "@" << sc_time_stamp() << std::endl;
Expand Down
30 changes: 30 additions & 0 deletions modules/ams/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# Include common Makefile
include ../Makefile

SRCDIR+=../adc/src ../dac/src ../vga/src ../utils/src
INCDIR+=-I$(SYSTEMC_AMS_HOME)/include -I../adc/include -I../dac/include -I../vga/include -I../utils/include
LIBDIR+=-L$(SYSTEMC_AMS_HOME)/lib-linux64
LIBS+=-lsystemc-ams

SOURCES:=$(foreach DIR, $(SRCDIR), $(wildcard $(DIR)/*.cpp))
INCLUDES:=$(foreach DIR, $(INCDIR), $(wildcard $(DIR)/*.hpp))

# Defining preprocessor directive for debug
ifdef IPS_DEBUG_EN
CFLAGS += -DIPS_DEBUG_EN
LFLAGS += -DIPS_DEBUG_EN
endif # IPS_DEBUG_EN

# Defining preprocessor directive for dumping enable
ifdef IPS_DUMP_EN
CFLAGS += -DIPS_DUMP_EN
LFLAGS += -DIPS_DUMP_EN
endif # IPS_DUMP_EN

# Run the compiled file
run:
@./$(TARGET)

# Show waveform
waveform:
@gtkwave ips_ams.vcd
42 changes: 42 additions & 0 deletions modules/ams/include/memory.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
#ifndef IPS_MEMORY_HPP
#define IPS_MEMORY_HPP
#include <systemc.h>

template <unsigned int SIZE>
SC_MODULE(memory)
{
protected:
int *mem;

public:
sc_core::sc_in<bool> clk;
sc_core::sc_in<bool> we;
sc_core::sc_in<unsigned long long int> address;
sc_core::sc_in<sc_uint<24>> wdata;
sc_core::sc_out<sc_uint<24>> rdata;

// Constructor for memory
SC_CTOR(memory)
{
this->mem = new int[SIZE];

SC_METHOD(run);
sensitive << clk.pos();
}

void run()
{
if (clk.read())
{
const unsigned long long int ADDR = static_cast<unsigned long long int>(this->address.read());

if (we.read())
{
this->mem[ADDR] = this->wdata.read();
}

this->rdata.write(this->mem[ADDR]);
}
}
};
#endif // IPS_MEMORY_HPP
136 changes: 136 additions & 0 deletions modules/ams/include/seq_item_ams.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
#ifndef IPS_SEQ_ITEM_AMS_HPP
#define IPS_SEQ_ITEM_AMS_HPP

#define int64 systemc_int64
#define uint64 systemc_uint64
#include <systemc.h>
#include <systemc-ams.h>
#undef int64
#undef uint64
#define int64 opencv_int64
#define uint64 opencv_uint64
#include <opencv2/opencv.hpp>
#undef int64
#undef uint64

// Image path
#define IPS_IMG_PATH_TB "../../tools/datagen/src/imgs/car_rgb_noisy_image.jpg"

/**
* @brief This class is used to generate the data for the AMS test
*
* @tparam N - the number of output bits of the digital pixel
* @tparam H_ACTIVE - output horizontal active video pixels
* @tparam H_FP - wait after the display period before the sync
* horizontal pulse
* @tparam H_SYNC_PULSE - assert HSYNC
* @tparam H_BP - wait after the sync horizontal pulse before starting
* the next display period
* @tparam V_ACTIVE - output vertical active video pixels
* @tparam V_FP - wait after the display period before the sync
* vertical pulse
* @tparam V_SYNC_PULSE - assert VSYNC
* @tparam V_BP - wait after the sync vertical pulse before starting
* the next display period
*/
template <
unsigned int N = 8,
unsigned int H_ACTIVE = 640,
unsigned int H_FP = 16,
unsigned int H_SYNC_PULSE = 96,
unsigned int H_BP = 48,
unsigned int V_ACTIVE = 480,
unsigned int V_FP = 10,
unsigned int V_SYNC_PULSE = 2,
unsigned int V_BP = 33
>
SC_MODULE(seq_item_ams)
{
protected:
cv::Mat tx_img;

public:
// Input clock
sc_core::sc_in<bool> clk;
// Counters
sc_core::sc_in<unsigned int> hcount;
sc_core::sc_in<unsigned int> vcount;
// Output pixel
sc_core::sc_out<sc_uint<N> > o_red;
sc_core::sc_out<sc_uint<N> > o_green;
sc_core::sc_out<sc_uint<N> > o_blue;

SC_CTOR(seq_item_ams)
{
// Read image
const std::string img_path = IPS_IMG_PATH_TB;

cv::Mat read_img = cv::imread(img_path, cv::IMREAD_COLOR);

// CV_8UC3 Type: 8-bit unsigned, 3 channels (e.g., for a color image)
read_img.convertTo(this->tx_img, CV_8UC3);

#ifdef IPS_DEBUG_EN
std::cout << "Loading image: " << img_path << std::endl;
#endif // IPS_DEBUG_EN

// Check if the image is loaded successfully
if (this->tx_img.empty())
{
std::cerr << "Error: Could not open or find the image!" << std::endl;
exit(EXIT_FAILURE);
}

#ifdef IPS_DEBUG_EN
std::cout << "TX image info: ";
std::cout << "rows = " << this->tx_img.rows;
std::cout << " cols = " << this->tx_img.cols;
std::cout << " channels = " << this->tx_img.channels() << std::endl;
#endif // IPS_DEBUG_EN

SC_METHOD(run);
sensitive << clk.pos();
}

void run()
{
if (this->clk.read())
{
const int IMG_ROW = static_cast<int>(this->vcount.read()) - (V_SYNC_PULSE + V_BP);
const int IMG_COL = static_cast<int>(this->hcount.read()) - (H_SYNC_PULSE + H_BP);

#ifdef IPS_DEBUG_EN
std::cout << "TX image: ";
std::cout << "row = " << IMG_ROW;
std::cout << " col = " << IMG_COL;
#endif // IPS_DEBUG_EN

if ((IMG_ROW < 0) || (IMG_COL < 0) || (IMG_ROW >= static_cast<int>(V_ACTIVE)) || (IMG_COL >= static_cast<int>(H_ACTIVE)))
{
this->o_red.write(0);
this->o_green.write(0);
this->o_blue.write(0);

#ifdef IPS_DEBUG_EN
std::cout << " dpixel = (0,0,0) " << std::endl;
#endif // IPS_DEBUG_EN
}
else
{
cv::Vec3b pixel = tx_img.at<cv::Vec3b>(IMG_ROW, IMG_COL, 0);

this->o_red.write(static_cast<sc_uint<8>>(pixel[0]));
this->o_green.write(static_cast<sc_uint<8>>(pixel[1]));
this->o_blue.write(static_cast<sc_uint<8>>(pixel[2]));

#ifdef IPS_DEBUG_EN
std::cout << " ipixel = (" << static_cast<int>(pixel[0]) << ","
<< static_cast<int>(pixel[1]) << "," << static_cast<int>(pixel[2])
<< ")" << std::endl;
#endif // IPS_DEBUG_EN
}
}
}
};

#endif // IPS_SEQ_ITEM_AMS_HPP
Loading

0 comments on commit cd22d5d

Please sign in to comment.