Skip to content

Commit 86fcc0b

Browse files
committed
Adding AT model for the filter module
- Adding the AT model version of the filter module - Updating the testbench to test the AT model too
1 parent fbe4ac0 commit 86fcc0b

File tree

2 files changed

+186
-1
lines changed

2 files changed

+186
-1
lines changed
Lines changed: 171 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,171 @@
1+
#ifndef IPS_FILTER_AT_MODEL_HPP
2+
#define IPS_FILTER_AT_MODEL_HPP
3+
#ifdef IPS_DEBUG_EN
4+
#include <iostream>
5+
#endif // IPS_DEBUG_ENi
6+
#ifdef IPS_DUMP_EN
7+
#include <sstream>
8+
#endif // IPS_DUMP_EN
9+
#include <systemc.h>
10+
11+
12+
/**
13+
* @brief Filter module.
14+
* It takes care of filtering a image/kernel using a median filter or an
15+
* equivalent convolution like:
16+
* | 1/N^2 ... 1/N^2 | | img(row - N/2, col - N/2) ... img(row + N/2, col + N/2) |
17+
* img(row, col) = | ... ... .... | * | ... ... ... |
18+
* | 1/N^2 ... 1/N^2 | | img(row + N/2, col - N/2) ... img(row + N/2, col + N/2) |
19+
*
20+
* @tparam IN - data type of the inputs
21+
* @tparam OUT - data type of the outputs
22+
* @tparam N - size of the kernel
23+
*/
24+
template <typename IN = sc_uint<8>, typename OUT = sc_uint<8>, uint8_t N = 3>
25+
SC_MODULE(Filter)
26+
{
27+
protected:
28+
//----------------------------Internal Variables----------------------------
29+
#ifdef IPS_DUMP_EN
30+
sc_trace_file* wf;
31+
#endif // IPS_DUMP_EN
32+
OUT* kernel;
33+
34+
// Event to trigger the filter execution
35+
sc_event event;
36+
37+
//-----------------------------Internal Methods-----------------------------
38+
void exec_filter();
39+
void init();
40+
41+
public:
42+
sc_in<IN* > img_window;
43+
sc_out<OUT > result;
44+
/**
45+
* @brief Default constructor for Filter
46+
*/
47+
SC_HAS_PROCESS(Filter);
48+
#ifdef IPS_DUMP_EN
49+
/**
50+
* @brief Construct a new Filter object
51+
*
52+
* @param name - name of the module
53+
* @param wf - waveform file pointer
54+
*/
55+
Filter(sc_core::sc_module_name name, sc_core::sc_trace_file* wf)
56+
: sc_core::sc_module(name), wf(wf)
57+
#else
58+
/**
59+
* @brief Construct a new Filter object
60+
*
61+
* @param name - name of the module
62+
*/
63+
Filter(sc_core::sc_module_name name) : sc_core::sc_module(name)
64+
#endif // IPS_DUMP_EN
65+
{
66+
// Calling this method by default since it is no time consumer
67+
// It is assumed that this kernel is already loaded in the model
68+
// Kernel does not change after synthesis
69+
SC_METHOD(init);
70+
// Thread waiting for the request
71+
SC_THREAD(exec_filter);
72+
}
73+
74+
//---------------------------------Methods---------------------------------
75+
void filter();
76+
};
77+
78+
/**
79+
* @brief Execute the image filtering
80+
*
81+
*/
82+
template <typename IN, typename OUT, uint8_t N>
83+
void Filter<IN, OUT, N>::exec_filter()
84+
{
85+
size_t i;
86+
size_t j;
87+
88+
OUT result_tmp;
89+
90+
while (true)
91+
{
92+
// Wait to peform the convolution
93+
wait(this->event);
94+
95+
// Default value for the result depending on the output datatype
96+
result_tmp = (OUT) 0;
97+
98+
// Getting the image window to filter
99+
IN* img_window_tmp = this->img_window.read();
100+
101+
#ifdef IPS_DEBUG_EN
102+
std::cout << "Performing convolution" << std::endl;
103+
#endif // IPS_DEBUG_EN
104+
105+
// Perform the convolution
106+
for (i = 0; i < N; ++i)
107+
for (j = 0; j < N; ++j)
108+
{
109+
#ifdef IPS_DEBUG_EN
110+
std::cout << "Starting [" << i << "][" << j << "]" << std::endl;
111+
#endif // IPS_DEBUG_EN
112+
result_tmp += this->kernel[i * N + j] * ((OUT) img_window_tmp[i * N + j]);
113+
#ifdef IPS_DEBUG_EN
114+
std::cout << "Done [" << i << "][" << j << "]" << std::endl;
115+
#endif // IPS_DEBUG_EN
116+
}
117+
118+
#ifdef IPS_DEBUG_EN
119+
std::cout << "Convolution result is done" << std::endl;
120+
#endif // IPS_DEBUG_EN
121+
this->result.write(result_tmp);
122+
}
123+
}
124+
125+
/**
126+
* @brief Filtering image
127+
*
128+
* @param img_window - image window to filter
129+
* @param result - resultant pixel
130+
*/
131+
template <typename IN, typename OUT, uint8_t N>
132+
void Filter<IN, OUT, N>::filter()
133+
{
134+
this->event.notify(DELAY_TIME, SC_NS);
135+
}
136+
137+
/**
138+
* @brief Initializes a kernel of N x N with default value of 1 / (N^2)
139+
*
140+
*/
141+
template <typename IN, typename OUT, uint8_t N>
142+
void Filter<IN, OUT, N>::init()
143+
{
144+
// Init a kernel of N x N with default value of 1 / (N * N)
145+
this->kernel = new OUT[N * N];
146+
std::fill_n(this->kernel, N * N, ((OUT) 1) / ((OUT) N * N));
147+
148+
#ifdef IPS_DEBUG_EN
149+
// Print the initialized kernel
150+
SC_REPORT_INFO(this->name(), "init result");
151+
size_t i, j;
152+
153+
for (i = 0; i < N; ++i)
154+
{
155+
for (j = 0; j < N; ++j)
156+
{
157+
std::cout << "[" << this->kernel[i * N + j] << "]";
158+
159+
#ifdef IPS_DUMP_EN
160+
// Adding the signals to the waveform
161+
std::ostringstream var_name;
162+
var_name << "kernel_" << i << "_" << j;
163+
sc_trace(this->wf, this->kernel[i * N + j], var_name.str());
164+
#endif // IPS_DUMP_EN
165+
}
166+
167+
std::cout << std::endl;
168+
}
169+
#endif // IPS_DEBUG_EN
170+
}
171+
#endif // IPS_FILTER_AT_MODEL_HPP

modules/filter/src/tb_filter.cpp

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
#ifndef IPS_FILTER_PV_EN
2020
// N * N * copy_pixel_to_mem_time + mult + redux + copy_pixel_to_mem_time
2121
// Image is copied pixel by pixel
22-
#define DELAY_TIME = (IPS_FILTER_KERNEL_SIZE * IPS_FILTER_KERNEL_SIZE * 1) + 4 + 2 + 1;
22+
#define DELAY_TIME (IPS_FILTER_KERNEL_SIZE * IPS_FILTER_KERNEL_SIZE * 1) + 4 + 2 + 1
2323
#endif // IPS_FILTER_PV_EN
2424

2525
#ifdef IPS_FILTER_AT_EN
@@ -55,6 +55,11 @@ void run_one_window()
5555
IPS_IN_TYPE_TB *img_window;
5656
IPS_OUT_TYPE_TB result;
5757

58+
#ifdef IPS_FILTER_AT_EN
59+
sc_signal<IPS_IN_TYPE_TB*> s_img_window;
60+
sc_signal<IPS_OUT_TYPE_TB> s_result;
61+
#endif // IPS_FILTER_AT_EN
62+
5863
// Initialize image window
5964
img_window = new IPS_IN_TYPE_TB[IPS_FILTER_KERNEL_SIZE * IPS_FILTER_KERNEL_SIZE];
6065

@@ -96,6 +101,12 @@ void run_one_window()
96101
#else
97102
Filter<IPS_IN_TYPE_TB, IPS_OUT_TYPE_TB, IPS_FILTER_KERNEL_SIZE> filter("filter");
98103
#endif // IPS_DEBUG_EN
104+
#ifdef IPS_FILTER_AT_EN
105+
s_img_window.write(img_window);
106+
107+
filter.img_window(s_img_window);
108+
filter.result(s_result);
109+
#endif // IPS_FILTER_AT_EN
99110

100111
sc_start();
101112

@@ -111,7 +122,10 @@ void run_one_window()
111122
filter.filter(img_window, &result);
112123
sc_start(DELAY_TIME + 10, SC_NS);
113124
#elif defined(IPS_FILTER_AT_EN)
125+
filter.filter();
114126
sc_start(DELAY_TIME + 10, SC_NS);
127+
128+
result = s_result.read();
115129
#endif // IPS_FILTER_XX_EN
116130

117131
#ifdef IPS_DEBUG_EN

0 commit comments

Comments
 (0)