Skip to content

Commit cd22d5d

Browse files
authored
Merge pull request #27 from ErickOF/dev
Integrating the the interface of DE and TDF
2 parents fe80709 + 5e02840 commit cd22d5d

File tree

12 files changed

+649
-54
lines changed

12 files changed

+649
-54
lines changed

modules/adc/include/adc.hpp

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,15 +29,21 @@ SCA_TDF_MODULE(adc)
2929
// Input analog voltage
3030
sca_tdf::sca_in<double> in;
3131
// Output digital code
32-
sca_tdf::sca_out<sc_dt::sc_uint<BITS> > out;
32+
sca_tdf::sca_de::sca_out<sc_dt::sc_uint<BITS> > out;
3333

3434
/**
3535
* @brief Construct a new adc object
3636
*
3737
*/
38-
SCA_CTOR(adc) : in("in"), out("out") {
38+
SCA_CTOR(adc) : in("in"), out("out")
39+
{
40+
}
41+
42+
void set_attributes()
43+
{
3944
// Propagation time from input to output
40-
set_timestep(sca_core::sca_time(0.1, sc_core::SC_US));
45+
set_timestep(sca_core::sca_time(1, sc_core::SC_NS));
46+
this->out.set_delay(13);
4147
}
4248

4349
/**

modules/adc/include/seq_item_adc.hpp

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,23 +7,33 @@
77
/**
88
* @brief This class is used to generate the analog signal for the test
99
*
10-
* @tparam N
10+
* @tparam N - the number of output bits of the digital code
11+
* @tparam VMIN - lowest voltage value
12+
* @tparam VMAX - highest voltage value
13+
* @tparam VU - voltage unit based on VUnit
1114
*/
12-
template <unsigned int N>
15+
template <unsigned int N = 8, int VMIN = 0, int VMAX = 5, VUnit VU = VUnit::v>
1316
SCA_TDF_MODULE(seq_item_adc)
1417
{
18+
protected:
19+
// Min voltage value based on the voltage units
20+
const double V_MIN = static_cast<double>(VMIN) / static_cast<double>(VU);
21+
// Max voltage value based on the voltage units
22+
const double V_MAX = static_cast<double>(VMAX) / static_cast<double>(VU);
23+
// Max digital output code
24+
const int MAX_CODE = (1 << N);
1525
public:
1626
sca_tdf::sca_out<double> o_ana;
17-
const int MAX_CODE = (1 << N);
1827

1928
SCA_CTOR(seq_item_adc)
2029
{
21-
set_timestep(sca_core::sca_time(0.1, sc_core::SC_US));
30+
set_timestep(sca_core::sca_time(13, sc_core::SC_NS));
2231
}
2332

2433
void processing()
2534
{
26-
this->o_ana.write(static_cast<double>(rand() % MAX_CODE) / MAX_CODE);
35+
const double NORM_ANA = static_cast<double>(rand() % MAX_CODE) / MAX_CODE;
36+
this->o_ana.write((V_MAX + V_MIN) * NORM_ANA + V_MIN);
2737
}
2838
};
2939

modules/adc/src/tb_adc.cpp

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
#include "seq_item_adc.hpp"
44

55
#define N 8
6+
#define VOLTAGE_MIN 0
7+
#define VOLTAGE_MAX 3300
68

79

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

1719
// DUT
18-
adc<N> ips_adc("ips_adc");
20+
adc<N, VOLTAGE_MIN, VOLTAGE_MAX, VUnit::mv> ips_adc("ips_adc");
1921
ips_adc.in(s_ana);
2022
ips_adc.out(s_dig_out);
2123

2224
// Sequence item generator for ADC
23-
seq_item_adc<N> ips_seq_item_adc("ips_seq_item_adc");
25+
seq_item_adc<N, VOLTAGE_MIN, VOLTAGE_MAX, VUnit::mv> ips_seq_item_adc("ips_seq_item_adc");
2426
ips_seq_item_adc.o_ana(s_ana);
2527

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

3436
// Run test
35-
sc_start(MAX_SEQ_ITEMS * 0.1, SC_US);
37+
sc_start(MAX_SEQ_ITEMS * 13, SC_NS);
3638

3739
// End time
3840
std::cout << "@" << sc_time_stamp() << std::endl;

modules/ams/Makefile

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
# Include common Makefile
2+
include ../Makefile
3+
4+
SRCDIR+=../adc/src ../dac/src ../vga/src ../utils/src
5+
INCDIR+=-I$(SYSTEMC_AMS_HOME)/include -I../adc/include -I../dac/include -I../vga/include -I../utils/include
6+
LIBDIR+=-L$(SYSTEMC_AMS_HOME)/lib-linux64
7+
LIBS+=-lsystemc-ams
8+
9+
SOURCES:=$(foreach DIR, $(SRCDIR), $(wildcard $(DIR)/*.cpp))
10+
INCLUDES:=$(foreach DIR, $(INCDIR), $(wildcard $(DIR)/*.hpp))
11+
12+
# Defining preprocessor directive for debug
13+
ifdef IPS_DEBUG_EN
14+
CFLAGS += -DIPS_DEBUG_EN
15+
LFLAGS += -DIPS_DEBUG_EN
16+
endif # IPS_DEBUG_EN
17+
18+
# Defining preprocessor directive for dumping enable
19+
ifdef IPS_DUMP_EN
20+
CFLAGS += -DIPS_DUMP_EN
21+
LFLAGS += -DIPS_DUMP_EN
22+
endif # IPS_DUMP_EN
23+
24+
# Run the compiled file
25+
run:
26+
@./$(TARGET)
27+
28+
# Show waveform
29+
waveform:
30+
@gtkwave ips_ams.vcd

modules/ams/include/memory.hpp

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
#ifndef IPS_MEMORY_HPP
2+
#define IPS_MEMORY_HPP
3+
#include <systemc.h>
4+
5+
template <unsigned int SIZE>
6+
SC_MODULE(memory)
7+
{
8+
protected:
9+
int *mem;
10+
11+
public:
12+
sc_core::sc_in<bool> clk;
13+
sc_core::sc_in<bool> we;
14+
sc_core::sc_in<unsigned long long int> address;
15+
sc_core::sc_in<sc_uint<24>> wdata;
16+
sc_core::sc_out<sc_uint<24>> rdata;
17+
18+
// Constructor for memory
19+
SC_CTOR(memory)
20+
{
21+
this->mem = new int[SIZE];
22+
23+
SC_METHOD(run);
24+
sensitive << clk.pos();
25+
}
26+
27+
void run()
28+
{
29+
if (clk.read())
30+
{
31+
const unsigned long long int ADDR = static_cast<unsigned long long int>(this->address.read());
32+
33+
if (we.read())
34+
{
35+
this->mem[ADDR] = this->wdata.read();
36+
}
37+
38+
this->rdata.write(this->mem[ADDR]);
39+
}
40+
}
41+
};
42+
#endif // IPS_MEMORY_HPP

modules/ams/include/seq_item_ams.hpp

Lines changed: 136 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,136 @@
1+
#ifndef IPS_SEQ_ITEM_AMS_HPP
2+
#define IPS_SEQ_ITEM_AMS_HPP
3+
4+
#define int64 systemc_int64
5+
#define uint64 systemc_uint64
6+
#include <systemc.h>
7+
#include <systemc-ams.h>
8+
#undef int64
9+
#undef uint64
10+
#define int64 opencv_int64
11+
#define uint64 opencv_uint64
12+
#include <opencv2/opencv.hpp>
13+
#undef int64
14+
#undef uint64
15+
16+
// Image path
17+
#define IPS_IMG_PATH_TB "../../tools/datagen/src/imgs/car_rgb_noisy_image.jpg"
18+
19+
/**
20+
* @brief This class is used to generate the data for the AMS test
21+
*
22+
* @tparam N - the number of output bits of the digital pixel
23+
* @tparam H_ACTIVE - output horizontal active video pixels
24+
* @tparam H_FP - wait after the display period before the sync
25+
* horizontal pulse
26+
* @tparam H_SYNC_PULSE - assert HSYNC
27+
* @tparam H_BP - wait after the sync horizontal pulse before starting
28+
* the next display period
29+
* @tparam V_ACTIVE - output vertical active video pixels
30+
* @tparam V_FP - wait after the display period before the sync
31+
* vertical pulse
32+
* @tparam V_SYNC_PULSE - assert VSYNC
33+
* @tparam V_BP - wait after the sync vertical pulse before starting
34+
* the next display period
35+
*/
36+
template <
37+
unsigned int N = 8,
38+
unsigned int H_ACTIVE = 640,
39+
unsigned int H_FP = 16,
40+
unsigned int H_SYNC_PULSE = 96,
41+
unsigned int H_BP = 48,
42+
unsigned int V_ACTIVE = 480,
43+
unsigned int V_FP = 10,
44+
unsigned int V_SYNC_PULSE = 2,
45+
unsigned int V_BP = 33
46+
>
47+
SC_MODULE(seq_item_ams)
48+
{
49+
protected:
50+
cv::Mat tx_img;
51+
52+
public:
53+
// Input clock
54+
sc_core::sc_in<bool> clk;
55+
// Counters
56+
sc_core::sc_in<unsigned int> hcount;
57+
sc_core::sc_in<unsigned int> vcount;
58+
// Output pixel
59+
sc_core::sc_out<sc_uint<N> > o_red;
60+
sc_core::sc_out<sc_uint<N> > o_green;
61+
sc_core::sc_out<sc_uint<N> > o_blue;
62+
63+
SC_CTOR(seq_item_ams)
64+
{
65+
// Read image
66+
const std::string img_path = IPS_IMG_PATH_TB;
67+
68+
cv::Mat read_img = cv::imread(img_path, cv::IMREAD_COLOR);
69+
70+
// CV_8UC3 Type: 8-bit unsigned, 3 channels (e.g., for a color image)
71+
read_img.convertTo(this->tx_img, CV_8UC3);
72+
73+
#ifdef IPS_DEBUG_EN
74+
std::cout << "Loading image: " << img_path << std::endl;
75+
#endif // IPS_DEBUG_EN
76+
77+
// Check if the image is loaded successfully
78+
if (this->tx_img.empty())
79+
{
80+
std::cerr << "Error: Could not open or find the image!" << std::endl;
81+
exit(EXIT_FAILURE);
82+
}
83+
84+
#ifdef IPS_DEBUG_EN
85+
std::cout << "TX image info: ";
86+
std::cout << "rows = " << this->tx_img.rows;
87+
std::cout << " cols = " << this->tx_img.cols;
88+
std::cout << " channels = " << this->tx_img.channels() << std::endl;
89+
#endif // IPS_DEBUG_EN
90+
91+
SC_METHOD(run);
92+
sensitive << clk.pos();
93+
}
94+
95+
void run()
96+
{
97+
if (this->clk.read())
98+
{
99+
const int IMG_ROW = static_cast<int>(this->vcount.read()) - (V_SYNC_PULSE + V_BP);
100+
const int IMG_COL = static_cast<int>(this->hcount.read()) - (H_SYNC_PULSE + H_BP);
101+
102+
#ifdef IPS_DEBUG_EN
103+
std::cout << "TX image: ";
104+
std::cout << "row = " << IMG_ROW;
105+
std::cout << " col = " << IMG_COL;
106+
#endif // IPS_DEBUG_EN
107+
108+
if ((IMG_ROW < 0) || (IMG_COL < 0) || (IMG_ROW >= static_cast<int>(V_ACTIVE)) || (IMG_COL >= static_cast<int>(H_ACTIVE)))
109+
{
110+
this->o_red.write(0);
111+
this->o_green.write(0);
112+
this->o_blue.write(0);
113+
114+
#ifdef IPS_DEBUG_EN
115+
std::cout << " dpixel = (0,0,0) " << std::endl;
116+
#endif // IPS_DEBUG_EN
117+
}
118+
else
119+
{
120+
cv::Vec3b pixel = tx_img.at<cv::Vec3b>(IMG_ROW, IMG_COL, 0);
121+
122+
this->o_red.write(static_cast<sc_uint<8>>(pixel[0]));
123+
this->o_green.write(static_cast<sc_uint<8>>(pixel[1]));
124+
this->o_blue.write(static_cast<sc_uint<8>>(pixel[2]));
125+
126+
#ifdef IPS_DEBUG_EN
127+
std::cout << " ipixel = (" << static_cast<int>(pixel[0]) << ","
128+
<< static_cast<int>(pixel[1]) << "," << static_cast<int>(pixel[2])
129+
<< ")" << std::endl;
130+
#endif // IPS_DEBUG_EN
131+
}
132+
}
133+
}
134+
};
135+
136+
#endif // IPS_SEQ_ITEM_AMS_HPP

0 commit comments

Comments
 (0)