/
verilog_ii_impl.cc
160 lines (141 loc) · 5.11 KB
/
verilog_ii_impl.cc
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
/* -*- c++ -*- */
/*
* Copyright 2019 <+YOU OR YOUR COMPANY+>.
*
* This is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3, or (at your option)
* any later version.
*
* This software is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this software; see the file COPYING. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street,
* Boston, MA 02110-1301, USA.
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <gnuradio/io_signature.h>
#include "verilog_ii_impl.h"
namespace gr {
namespace verilog {
verilog_ii::sptr
verilog_ii::make(const char *filename)
{
return gnuradio::get_initial_sptr
(new verilog_ii_impl(filename));
}
/*
* The private constructor
*/
verilog_ii_impl::verilog_ii_impl(const char *filename)
: gr::sync_block("verilog_ii",
gr::io_signature::make(1, 1, sizeof(ITYPE)),
gr::io_signature::make(1, 1, sizeof(OTYPE)))
{
/* Get module_name and module_path */
std::string filename_temp(filename);
std::size_t filename_pos = filename_temp.rfind(SLASH);
if (std::string::npos == filename_pos) {
/* TODO: raise_error() */
}
this->verilog_module_name = filename_temp.substr(filename_pos + 1);
this->verilog_module_path = filename_temp.substr(0, filename_pos + 1);
/* Initialize makefile_template_path and cpp_template_path */
// TODO: #define MAKEFILE_TEMPLATE_PATH "$(prefix)/gnuradio/gr-verilog/lib"
this->makefile_template_path = MAKEFILE_TEMPLATE_PATH;
// TODO: #define CPP_TEMPLATE_PATH "$(prefix)/gnuradio/gr-verilog/lib"
this->cpp_template_path = CPP_TEMPLATE_PATH;
/* Call Verilator (Makefile) to generate the cpp code */
// There will be a Shell_cmd object created in the function to
// run configure.sh
// configure.sh will copy the makefile template and modify it
// for the verilog module
// the Shell_cmd will run make at the verilog module path
try {
this->generate_verilator_file();
} catch (...) {
/* TODO: Handle the error */
}
/* Initialize port_map that stored in verilator_data */
// The port map is the structure of input/output ports of
// verilog module
// Verilog_data should have a method to parse the code(.cpp/.v) and
// extract the port structure of verilog module.
try {
this->init_port_map();
} catch (...) {
/* TODO: Handle the error */
}
/* Generate shared library and initialize verilog_module_so */
// There will be a Shell_cmd object created in the function to
// run make at the verilog module path
try {
this->generate_so();
} catch (...) {
/* TODO: Handle the error */
}
/* Load the shared library that generated above */
// The function should also initialize the external veriable
// in the shred library
// Call verilog_module_so.find_func(VERILOG_INIT_FUNC)
// Call verilog_module_so.find_func(VERILOG_RESET_FUNC)
// shared library function reset() should be defalt generated
// There would be a function called general_sim()
// general_sim() could accept input and output of all port with
// the help of port map stored in the verilog_data
try {
this->load_lib();
} catch (...) {
/* TODO: Handle the error */
}
/* Initialize sim */
this->sim = NULL;
}
/*
* Our virtual destructor.
*/
verilog_ii_impl::~verilog_ii_impl()
{
/* Release the shared library */
try {
this->release_lib();
} catch (...) {
/* TODO: Handle the error */
}
}
int
verilog_ii_impl::work(int noutput_items,
gr_vector_const_void_star &input_items,
gr_vector_void_star &output_items)
{
const ITYPE *in = (const ITYPE *) input_items[0];
OTYPE *out = (OTYPE *) output_items[0];
if (NULL == this->sim)
{
// TODO: #define VERILOG_SIMULATION_FUNC "$(the_name_of_the_function)"
try {
// Find the function of simulation in the shared library
sim = verilog_module_so.find_func(VERILOG_SIMULATION_FUNC);
} catch (...) {
/* TODO: Handle the error */
}
}
// Do <+signal processing+>
for (unsigned int i = 0; i < noutput_items; i++)
{
this->verilog_data.set_input(in[i]);
this->verilog_data.set_output(out[i]);
this->verilog_data.convert();
sim(verilog_data.get_input_addr(), verilog_data.get_output_addr());
}
// Tell runtime system how many output items we produced.
return noutput_items;
}
} /* namespace verilog */
} /* namespace gr */