Skip to content

Commit 8721c3e

Browse files
authored
Merge branch 'dev' into unification
2 parents 011ab99 + 331b9a6 commit 8721c3e

File tree

9 files changed

+963
-15
lines changed

9 files changed

+963
-15
lines changed

.gitignore

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -228,3 +228,7 @@ modules/unification/*.png
228228
tools/datagen/src/imgs/*_grayscale_image*
229229
tools/datagen/src/imgs/*_noisy_image*
230230
tools/datagen/src/imgs/*_sobel_*
231+
232+
# Ignore VCD files
233+
*.vcd
234+
test

modules/Makefile

Lines changed: 7 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -20,26 +20,19 @@ LIBDIR=-L. -L$(SYSTEMC)/lib-linux64
2020
SOURCES := $(wildcard $(SRCDIR)/*.cpp)
2121
INCLUDES := $(wildcard $(INCDIR)/*.hpp)
2222
OBJECTS := $(SOURCES:$(SRCDIR)/%.cpp=$(OBJDIR)/%.o)
23-
FV_OBJECTS := $(SOURCES:$(SRCDIR)/%.cpp=$(OBJDIR)/%.i)
2423

25-
$(BINDIR)/$(TARGET): $(OBJECTS)
24+
$(BINDIR)/$(TARGET): clean $(OBJECTS)
2625
@$(LD) $(OBJECTS) $(LFLAGS) $(LIBS) $(LIBDIR) -o $@
27-
@echo "Linked $@ completed!"
2826

2927
$(OBJECTS): $(OBJDIR)/%.o : $(SRCDIR)/%.cpp
3028
@$(CC) $(CFLAGS) $(INCDIR) -c $< -o $@
31-
@echo "Compilation $< in $@"
32-
33-
fv_run: $(FV_OBJECTS)
34-
cbmc $(FV_OBJECTS) --function sc_main
35-
36-
$(FV_OBJECTS): $(OBJDIR)/%.i : $(SRCDIR)/%.cpp
37-
@$(CC) $(CFLAGS) $(INCDIR) -c $< -o $@
38-
@echo "FV compilation $< in $@"
3929

4030
.PHONY: clean
4131
clean:
42-
@rm -f $(OBJECTS)
43-
@echo "Clean done."
32+
@rm -rf obj
33+
@rm -f $(TARGET)
34+
@mkdir -p obj
35+
36+
compile: $(BINDIR)/$(TARGET)
4437

45-
all: $(BINDIR)/$(TARGET)
38+
all: compile run

modules/filter/Makefile

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
# Adding stb lib for image handling
2+
CFLAGS_OPENCV := $(shell pkg-config --cflags opencv4)
3+
LFLAGS_OPENCV := $(shell pkg-config --libs opencv4)
4+
5+
# Include common Makefile
6+
include ../Makefile
7+
8+
# Include stb lib for compilation
9+
CFLAGS += $(CFLAGS_OPENCV)
10+
LFLAGS += $(LFLAGS_OPENCV)
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+
# Defining preprocessor directive for test modes
25+
ifdef TEST_MODE_IMAGE
26+
CFLAGS += -DTEST_MODE_IMAGE
27+
LFLAGS += -DTEST_MODE_IMAGE
28+
else
29+
ifdef TEST_MODE_ONE_WINDOW_RANDOM
30+
CFLAGS += -DTEST_MODE_ONE_WINDOW -DTEST_MODE_ONE_WINDOW_RANDOM
31+
LFLAGS += -DTEST_MODE_ONE_WINDOW -DTEST_MODE_ONE_WINDOW_RANDOM
32+
else
33+
ifdef TEST_MODE_ONE_WINDOW_NORMAL
34+
CFLAGS += -DTEST_MODE_ONE_WINDOW -DTEST_MODE_ONE_WINDOW_NORMAL
35+
LFLAGS += -DTEST_MODE_ONE_WINDOW -DTEST_MODE_ONE_WINDOW_NORMAL
36+
endif # TEST_MODE_ONE_WINDOW_NORMAL
37+
endif # TEST_MODE_ONE_WINDOW_RANDOM
38+
endif # TEST_MODE_IMAGE
39+
40+
# Defining preprocessor directive for model - by default PV model
41+
ifdef IPS_FILTER_LT_EN
42+
CFLAGS += -DIPS_FILTER_LT_EN
43+
LFLAGS += -DIPS_FILTER_LT_EN
44+
else # IPS_FILTER_AT_EN
45+
ifdef IPS_FILTER_AT_EN
46+
CFLAGS += -DIPS_FILTER_AT_EN
47+
LFLAGS += -DIPS_FILTER_AT_EN
48+
else # IPS_FILTER_CA_EN
49+
ifdef IPS_FILTER_CA_EN
50+
CFLAGS += -DIPS_FILTER_CA_EN
51+
LFLAGS += -DIPS_FILTER_CA_EN
52+
else # IPS_FILTER_PV_EN
53+
CFLAGS += -DIPS_FILTER_PV_EN
54+
LFLAGS += -DIPS_FILTER_PV_EN
55+
endif # IPS_FILTER_CA_EN
56+
endif # IPS_FILTER_AT_EN
57+
endif # IPS_FILTER_LT_EN
58+
59+
# Run the compiled file
60+
run:
61+
@./test
62+
63+
# Show waveform
64+
waveform:
65+
@gtkwave ips_filter.vcd

modules/filter/README.md

Lines changed: 71 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,73 @@
11
# **Filter Module**
22

3-
Add compilation instructions
3+
## **Filter Algorithm: Mean Filter**
4+
The mean filter algorithm replaces each pixel value with the average of all
5+
pixel values in an N by N window (N = 3, 5, 7, etc), where the pixel to
6+
replace is the centering pixel. Assuming that the centering pixel is in (0, 0)
7+
position:
8+
9+
$
10+
img(row, col) = \sum_{i = -N/2}^{N/2} {\sum_{j = -N/2}^{-N/2} {img(row + i, col + j)}}
11+
$
12+
13+
Also, it can computed using a convolution like:
14+
15+
$
16+
img(row, col) = \begin{bmatrix}
17+
\frac{1}{N^{2}} & \dots & \frac{1}{N^{2}} \\
18+
\vdots & \ddots & \vdots \\
19+
\frac{1}{N^{2}} & \dots & \frac{1}{N^{2}}
20+
\end{bmatrix}
21+
\ast
22+
\begin{bmatrix}
23+
img(row - N/2, col - N/2) & \dots & img(row + N/2, col + N/2) \\
24+
\vdots & \ddots & \vdots \\
25+
img(row + N/2, col - N/2) & \dots & img(row + N/2, col + N/2)
26+
\end{bmatrix}
27+
$
28+
29+
30+
## **Usage**
31+
32+
A Makefile is used to compile the testbench and filter module. There are some
33+
Makefile targets to compile the different modules and tests. By default, the
34+
PV model is compiled. The available test options are:
35+
36+
* `TEST_MODE_ONE_WINDOW_NORMAL`: Runs only one window with fixed values.
37+
* `TEST_MODE_ONE_WINDOW_RANDOM`: Runs only one window with random values.
38+
39+
Some additional options can used to debug and dump the waveform:
40+
41+
* `IPS_DEBUG_EN`: Prints the kernel, each window value, and the result.
42+
* `IPS_DUMP_EN`: Creates a VCD file with each value of the window and kernel,
43+
and the result.
44+
45+
To compile a specific model, you can use the switches:
46+
47+
* `IPS_FILTER_PV_EN`: Programmer's View model.
48+
* `IPS_FILTER_LT_EN`: Loosely Timed model.
49+
* `IPS_FILTER_AT_EN`: Approximately Timed model.
50+
* `IPS_FILTER_CA_EN`: Cycle Approximate model (pending to be implemented).
51+
52+
### **Compilation**
53+
Runs the `make` command with the corresponding switches to compile.
54+
55+
For instance, to run only one window in debug mode and dump the signals:
56+
57+
```shell
58+
make TEST_MODE_ONE_WINDOW_RANDOM=1 IPS_DUMP_EN=1 IPS_DEBUG_EN=1
59+
```
60+
61+
### **Run**
62+
63+
```shell
64+
make run
65+
```
66+
67+
### **Open Waveform**
68+
69+
Since VCD is not generated, this command will not work for the PV model.
70+
71+
```shell
72+
make waveform
73+
```
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+
// Perform the convolution
102+
for (i = 0; i < N; ++i)
103+
for (j = 0; j < N; ++j)
104+
result_tmp += this->kernel[i * N + j] * ((OUT) img_window_tmp[i * N + j]);
105+
106+
this->result.write(result_tmp);
107+
}
108+
}
109+
110+
/**
111+
* @brief Filtering image
112+
*
113+
* @param img_window - image window to filter
114+
* @param result - resultant pixel
115+
*/
116+
template <typename IN, typename OUT, uint8_t N>
117+
void Filter<IN, OUT, N>::filter()
118+
{
119+
this->event.notify(DELAY_TIME, SC_NS);
120+
}
121+
122+
/**
123+
* @brief Initializes a kernel of N x N with default value of 1 / (N^2)
124+
*
125+
*/
126+
template <typename IN, typename OUT, uint8_t N>
127+
void Filter<IN, OUT, N>::init()
128+
{
129+
// Init a kernel of N x N with default value of 1 / (N * N)
130+
this->kernel = new OUT[N * N];
131+
std::fill_n(this->kernel, N * N, ((OUT) 1) / ((OUT) N * N));
132+
133+
#ifdef IPS_DEBUG_EN
134+
// Print the initialized kernel
135+
SC_REPORT_INFO(this->name(), "init result");
136+
size_t i, j;
137+
138+
for (i = 0; i < N; ++i)
139+
{
140+
for (j = 0; j < N; ++j)
141+
{
142+
std::cout << "[" << this->kernel[i * N + j] << "]";
143+
144+
#ifdef IPS_DUMP_EN
145+
// Adding the signals to the waveform
146+
std::ostringstream var_name;
147+
var_name << "kernel_" << i << "_" << j;
148+
sc_trace(this->wf, this->kernel[i * N + j], var_name.str());
149+
#endif // IPS_DUMP_EN
150+
}
151+
152+
std::cout << std::endl;
153+
}
154+
#else
155+
#ifdef IPS_DUMP_EN
156+
size_t i, j;
157+
158+
for (i = 0; i < N; ++i)
159+
{
160+
for (j = 0; j < N; ++j)
161+
{
162+
// Adding the signals to the waveform
163+
std::ostringstream var_name;
164+
var_name << "kernel_" << i << "_" << j;
165+
sc_trace(this->wf, this->kernel[i * N + j], var_name.str());
166+
}
167+
}
168+
#endif // IPS_DUMP_EN
169+
#endif // IPS_DEBUG_EN
170+
}
171+
#endif // IPS_FILTER_AT_MODEL_HPP

0 commit comments

Comments
 (0)