Writing the main program of a D flip-flop - systemc

I'm new to systemC programming i'm writing a D flip-flop but i couldn't find a way to write the main program and to enter signals (din , clock and dout in my case) :
this is my code :
#include "systemc.h"
SC_MODULE(d_ff) { // on déclare le module à l'aide de la macro SC_MODULE.
sc_in<bool> din; // signal d'entrée
sc_in<bool> clock;// définition de l'horlogue
sc_out<bool> dout;// signal de sortie
void doit() { // La fonction qui assure le traitement de la bascule D
dout = din; // Affectation de la valeur du port d'entrée dans le port de sortie
cout << dout;
};
SC_CTOR(d_ff) { //le constructeur du module d_ff
SC_METHOD(doit); //On enregistre la fonction doit comme un processus
sensitive_pos << clock; }
int sc_main (int argc , char *argv[]) {
d_ff obj();
din<=true;
clock<=false;
obj.doit();
return 0;
}};

You have to install VCD Viewers to see simulation results in the form of waveforms.
I suppose that's what you want
I use this one http://www.iss-us.com/wavevcd/index.htm, but there are others.
Next you have to make some changes in you code. The changes will produce the vcd files:
I made this one:
// File dff.h
#include <iostream>
#include <systemc.h>
SC_MODULE (dff) {
sc_in <bool> clk;
sc_in <bool> din;
sc_out <bool> dout;
void dff_method();
SC_CTOR (dff) {
SC_METHOD (dff_method);
sensitive_pos << clk;
}
};
// File dff.cpp
#include "dff.h"
void dff:: dff_method (){
dout=din;
}
// File: main.cpp
#include <systemc.h>
#include "dff.h"
int sc_main(int argc, char* argv[])
{
sc_signal<bool> din, dout;
sc_clock clk("clk",10,SC_NS,0.5);
dff dff1("dff");
dff1.din(din);
dff1.dout(dout);
dff1.clk(clk);
// WAVE
sc_trace_file *fp; // VCD file
fp=sc_create_vcd_trace_file("wave");
fp->set_time_unit(100, SC_PS); // resolution (trace) ps
sc_trace(fp,clk,"clk"); // signals
sc_trace(fp,din,"din");
sc_trace(fp,dout,"dout");
//Inicialization
din=0;
//START
sc_start(31, SC_NS);
din=1;
cout << "Din=1" << endl;
cout << "Tempo: " << sc_time_stamp() << endl;
sc_start(31, SC_NS);
din=0;
cout << "Din=0" << endl;
cout << "Tempo: " << sc_time_stamp() << endl;
sc_start(31, SC_NS);
sc_close_vcd_trace_file(fp); // fecho(fp)
char myLine[100];
cin.getline(myLine, 100);
return 0;
}
I hope it will help

Does this page help any?
http://www.asic-world.com/systemc/first1.html
It's entitled "My first program in System C", so looks to be about where you are.
Some other useful links for new starters:
http://panoramis.free.fr/search.systemc.org/?doc=systemc/helloworld
http://www.ht-lab.com/howto/vh2sc_tut/vh2sc_tut1.html

Related

Does std::find use operator== for std::vector<std::pair<T, T>>?

I tried to overload operator== for std::pair<int, int> so that only the first element of the pair would matter. Then, I'd like to use std::find to look for a particular element in std::vector<std::pair<int, int>>, using the overloaded operator==. But, it seems that, std::find is not using my overloaded operator==, though it is working in a simple comparison statement.
I expect the following code to output:
1
1
1
but I get:
1
1
0
Run on Linux, gcc 11.3:
#include <iostream>
#include <algorithm>
#include <vector>
#include <utility>
using namespace std;
typedef pair<int, int> p_int_t;
bool operator==(const p_int_t& p1, const p_int_t& p2)
{
return p1.first == p2.first;
}
int main()
{
vector<p_int_t> v;
v.push_back({1, 2});
v.push_back({1, 3});
p_int_t p(1, 4);
cout << (v[0] == p) << endl;
cout << (v[1] == p) << endl;
cout << (find(v.begin(), v.end(), p) != v.end()) << endl;
return 0;
}
The compiler does not select the free standing comparison operator because the type p_int_t is an alias, and it is not defined in the std namespace as std:: pair is. In other words, the compiler is looking for an operator with this signature: std::operator==(const std::pair<int, int>&, const std::pair<int, int>&); and finds it in algorithm.
You could declare your operator in the std namespace, which works, but is not recommended, or define p_int_t as a class, as in:
#include <algorithm>
#include <iostream>
#include <utility>
#include <vector>
using namespace std;
struct p_int_t : pair<int, int> {
using pair<int, int>::pair; // for c++=11 and later
p_int_t() : pair() {} // for c++98
p_int_t(int x, int y) : pair(x, y) {} // for c++98
friend bool operator==(const p_int_t& p1, const p_int_t& p2) {
return p1.first == p2.first;
}
};
int main() {
vector<p_int_t> v;
v.push_back({1, 2});
v.push_back({1, 3});
p_int_t p(1, 4);
cout << (v[0] == p) << endl;
cout << (v[1] == p) << endl;
cout << (find(v.begin(), v.end(), p) != v.end()) << endl;
return 0;
}
Code can be found here: https://godbolt.org/z/5dfPaaoMz
Having to redefine constructors is quite cumbersome, but you can also use std::find_if(), as in:
#include <algorithm>
#include <iostream>
#include <utility>
#include <vector>
using namespace std;
typedef pair<int, int> p_int_t;
struct compare_first {
p_int_t p;
compare_first(p_int_t x) : p(x) {}
bool operator()(const p_int_t& x) { return x.first == p.first; }
};
int main() {
vector<p_int_t> v;
v.push_back({1, 2});
v.push_back({1, 3});
p_int_t p(1, 4);
cout << (find_if(v.begin(), v.end(), compare_first(p)) != v.end()) << endl;
// or for c++11 or later...
cout << (find_if(v.begin(), v.end(), [&p](const p_int_t& x) { return p.first == x.first; }) != v.end()) << endl;
return 0;
}
Code here: https://godbolt.org/z/r87hdrrK9

Refine mesh obtained with CGAL::Advancing_front_surface_reconstruction

I reconstruct a 3D surface mesh using the advancing front surface reconstruction and would like to refine it. How can I achieve this?
This is part of the code used for surface reconstruction with refinement by passing through a file:
#include <CGAL/Advancing_front_surface_reconstruction.h>
#include <CGAL/compute_average_spacing.h>
#include <CGAL/Delaunay_triangulation_3.h>
#include <CGAL/Triangulation_data_structure_3.h>
#include <CGAL/Polyhedron_3.h>
#include <CGAL/Surface_mesh.h>
#include <CGAL/IO/Polyhedron_iostream.h>
#include <CGAL/Polygon_mesh_processing/refine.h>
#include <CGAL/Polygon_mesh_processing/fair.h>
typedef CGAL::Advancing_front_surface_reconstruction<> Reconstruction;
typedef Reconstruction::Triangulation_3 Triangulation_3;
typedef Reconstruction::Triangulation_data_structure_2 TDS_2;
typedef Reconstruction::Outlier_range Outlier_range;
typedef Reconstruction::Boundary_range Boundary_range;
typedef Reconstruction::Vertex_on_boundary_range Vertex_on_boundary_range;
typedef Reconstruction::Vertex_handle Vertex_handle;
typedef CGAL::Polyhedron_3<CGALMesher::Kernel> Polyhedron;
typedef CGAL::Surface_mesh<CGALMesher::Point> Mesh;
typedef CGAL::cpp11::array<std::size_t,3> Facet;
struct Construct {
Mesh& mesh;
template<typename PointIterator>
Construct(Mesh& mesh, PointIterator b, PointIterator e) : mesh(mesh) {
for (; b != e; ++b) {
boost::graph_traits<Mesh>::vertex_descriptor v;
v = add_vertex(mesh);
mesh.point(v) = *b;
}
}
Construct& operator=(const Facet f) {
typedef boost::graph_traits<Mesh>::vertex_descriptor vertex_descriptor;
typedef boost::graph_traits<Mesh>::vertices_size_type size_type;
mesh.add_face(vertex_descriptor(static_cast<size_type>(f[0])),
vertex_descriptor(static_cast<size_type>(f[1])),
vertex_descriptor(static_cast<size_type>(f[2])));
return *this;
}
Construct&
operator*() {
return *this;
}
Construct&
operator++() {
return *this;
}
Construct operator++(int) {
return *this;
}
};
void CGALMesher::AdvancingFrontMesher(std::vector<Point>& points) {
Mesh m;
Construct construct(m,points.begin(),points.end());
CGAL::advancing_front_surface_reconstruction(points.begin(), points.end(), construct);
std::ofstream mesh_off("mesh.off");
mesh_off << m;
mesh_off.close();
std::ifstream input("mesh.off");
Polyhedron poly;
if ( !input || !(input >> poly) || poly.empty() ) {
std::cerr << "Not a valid off file." << std::endl;
}
input.close();
std::vector<Polyhedron::Facet_handle> new_facets;
std::vector<Polyhedron::Vertex_handle> new_vertices;
CGAL::Polygon_mesh_processing::refine(poly,
faces(poly),
std::back_inserter(new_facets),
std::back_inserter(new_vertices),
CGAL::Polygon_mesh_processing::parameters::density_control_factor(3));
std::ofstream refined_off("refined.off");
refined_off << poly;
refined_off.close();
std::cout << "Refinement added " << new_vertices.size() << " vertices." << std::endl;
}
Once you extracted a polyhedral surface out of the reconstruction algorithm, you can use the refine() function from the polygon mesh processing package. There is also the possibility to use the fair().
More drastically, you can use remeshing algorithm like this one. In CGAL 4.8, there will also be the function isotropic_remeshing() that is already available in the master branch.

Need help in getting the process name based on the pid in aix

I need to write a C program in AIX environment which will give me the process name.
I can get the pid but not the process name based on the pid. Any specific system calls available in aix environment??
Thanks
getprocs is likely what you want. I created this under AIX 5.x.
I have a little routine that cycles thru all processes and dumps their information.
while ((numproc = getprocs(pinfo, sizeof(struct procsinfo),
NULL,
0,
&index,
MAXPROCS)) > 0 ) {
for (i = 0;i < numproc; i++) {
/* skip zombie processes */
if (pinfo[i].pi_state==SZOMB)
continue;
printf("%-6d %-4d %-10d %-16s\n", pinfo[i].pi_pid, pinfo[i].pi_uid, pinfo[i].pi_start, pinfo[i].pi_comm);
}
}
....
I realize this is an old question.
But, to convert the #CoreyStup answer into a function that more closely addresses the OP, I offer this: (tested on AIX 6.1, using: g++ -o pn pn.cc)
--- pn.cc ---
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string>
#include <iostream>
#include <procinfo.h>
#include <sys/types.h>
using namespace std;
string getProcName(int pid)
{
struct procsinfo pinfo[16];
int numproc;
int index = 0;
while((numproc = getprocs(pinfo, sizeof(struct procsinfo), NULL, 0, &index, 16)) > 0)
{
for(int i=0; i<numproc; ++i)
{
// skip zombies
if (pinfo[i].pi_state == SZOMB)
continue;
if (pid == pinfo[i].pi_pid)
{
return pinfo[i].pi_comm;
}
}
}
return "";
}
int main(int argc, char** argv)
{
for(int i=1; i<argc; ++i)
{
int pid = atoi(argv[i]);
string name = getProcName(pid);
cout << "pid: " << pid << " == '" << name << "'" << endl;
}
return 0;
}

printing lines from files

I'm trying to print the first line from each file but I think its outputting the address instead.
#include <fstream>
#include <iostream>
#include <cstdlib>
using namespace std;
void FirstLineFromFile(ifstream files[], size_t count)
{
const int BUFSIZE = 511;
char buf[BUFSIZE];
ifstream *end, *start;
for (start = files, end = files + count; start < end; start++)
{
cout << start->getline(buf, sizeof(buf)) << '\n';
}
}
streams should not be passed by value. This code passes an array of streams by value. You can try to pass a vector instead and interate over them.
void FirstLineFromFile(vector<ifstream*> files) {
for (int i=0; i<files.size(); ++i) {
string s;
getline(*files[i], s);
cout << s << endl;
}
}
ifstream->getline does not return a string as its return value. You need to print out the buffer that it has filled in a separate line.
for (start = files, end = files + count; start < end; start++)
{
start->getline(buf, sizeof(buf));
cout << buf << '\n';
}

DBus client and server in the same process

When I create a D-Bus server (via g_bus_own_name()) and the client to it (using g_dbus_proxy_new()) in the same process and then call g_dbus_proxy_call_sync(), it never returns. However, if server and client are in separate processes, everything is ok.
The following code illustrates my problem (I am using giomm C++ bindings here):
file main.cc:
#include <giomm.h>
#include <thread>
int server_main();
int client_main();
int main() {
Gio::init();
std::thread thr_server([](){ server_main(); });
sleep(1); // give some time to server to register
std::thread thr_client([](){ client_main(); });
sleep(10); // wait for the client to finish
}
file server.cc:
#include <giomm.h>
#include <iostream>
namespace {
static Glib::RefPtr<Gio::DBus::NodeInfo> introspection_data;
static Glib::ustring introspection_xml =
"<node name='/org/glibmm/DBusExample'>"
" <interface name='org.glibmm.DBusExample'>"
" <method name='Method'>"
" </method>"
" </interface>"
"</node>";
guint registered_id = 0;
}
static void on_method_call(const Glib::RefPtr<Gio::DBus::Connection>& /* connection */,
const Glib::ustring& /* sender */, const Glib::ustring& /* object_path */,
const Glib::ustring& /* interface_name */, const Glib::ustring& method_name,
const Glib::VariantContainerBase& parameters,
const Glib::RefPtr<Gio::DBus::MethodInvocation>& invocation)
{
if(method_name == "Method") {
std::cout << "Method was called\n";
}
}
const Gio::DBus::InterfaceVTable interface_vtable(sigc::ptr_fun(&on_method_call));
void on_bus_acquired(const Glib::RefPtr<Gio::DBus::Connection>& connection, const Glib::ustring& /* name */)
{
std::cout << "on_bus_acquired\n";
try {
registered_id = connection->register_object("/org/glibmm/DBusExample",
introspection_data->lookup_interface(),
interface_vtable);
}
catch(const Glib::Error& ex) {
std::cerr << "Registration of object failed." << std::endl;
}
return;
}
void on_name_acquired(const Glib::RefPtr<Gio::DBus::Connection>& /* connection */, const Glib::ustring& /* name */)
{}
void on_name_lost(const Glib::RefPtr<Gio::DBus::Connection>& connection, const Glib::ustring& /* name */) {
connection->unregister_object(registered_id);
}
int server_main()
{
try {
introspection_data = Gio::DBus::NodeInfo::create_for_xml(introspection_xml);
}
catch(const Glib::Error& ex) {
std::cerr << "Unable to create introspection data: " << ex.what() <<
"." << std::endl;
return 1;
}
const guint id = Gio::DBus::own_name(Gio::DBus::BUS_TYPE_SESSION,
"org.glibmm.DBusExample",
sigc::ptr_fun(&on_bus_acquired),
sigc::ptr_fun(&on_name_acquired),
sigc::ptr_fun(&on_name_lost));
//Keep the service running
auto loop = Glib::MainLoop::create();
loop->run();
Gio::DBus::unown_name(id);
return EXIT_SUCCESS;
}
file client.cc:
#include <giomm.h>
#include <iostream>
Glib::RefPtr<Glib::MainLoop> loop;
// A main loop idle callback to quit when the main loop is idle.
bool on_main_loop_idle() {
std::cout << "loop_idle\n";
loop->quit();
return false;
}
void on_dbus_proxy_available(Glib::RefPtr<Gio::AsyncResult>& result)
{
auto proxy = Gio::DBus::Proxy::create_finish(result);
if(!proxy) {
std::cerr << "The proxy to the user's session bus was not successfully "
"created." << std::endl;
loop->quit();
return;
}
try {
std::cout << "Calling...\n";
proxy->call_sync("Method");
std::cout << "It works!\n";
}
catch(const Glib::Error& error) {
std::cerr << "Got an error: '" << error.what() << "'." << std::endl;
}
// Connect an idle callback to the main loop to quit when the main loop is
// idle now that the method call is finished.
Glib::signal_idle().connect(sigc::ptr_fun(&on_main_loop_idle));
}
int client_main() {
loop = Glib::MainLoop::create();
auto connection =
Gio::DBus::Connection::get_sync(Gio::DBus::BUS_TYPE_SESSION);
if(!connection) {
std::cerr << "The user's session bus is not available." << std::endl;
return 1;
}
// Create the proxy to the bus asynchronously.
Gio::DBus::Proxy::create(connection, "org.glibmm.DBusExample",
"/org/glibmm/DBusExample", "org.glibmm.DBusExample",
sigc::ptr_fun(&on_dbus_proxy_available));
loop->run();
return EXIT_SUCCESS;
}
I compile the test with g++ -O2 -std=c++0x main.cc server.cc client.cc -o test $(pkg-config --cflags --libs giomm-2.4) and run:
./test
on_bus_acquired
Calling...
<it hangs>
However, when I change main.cc:
#include <giomm.h>
int server_main();
int client_main();
int main() {
Gio::init();
auto childid = fork();
if (childid == 0) {
server_main();
} else {
sleep(1);
client_main();
}
}
I get:
./test
on_bus_acquired
Calling...
Method was called
It works!
So call_sync() returns successfully.
I tried to exclude loops from server and client, and use a single-threaded main.cc:
#include <giomm.h>
#include <thread>
int server_main();
int client_main();
int main() {
Gio::init();
server_main();
client_main();
auto loop = Glib::MainLoop::create();
loop->run();
}
Nothing helps. The question is, what am I doing wrong? I want to use my d-bus server and client in one process.
I figured it out, the trick is to execute
Glib::VariantContainerBase result;
invocation->return_value(result);
in the end of on_method_call.