In this work I show how to build a reference model
in systemc using queues,
from C++ STD.
-
Link to the main page of this
work.
This page explains the monitor used in this project.
-
The monitor of this project has multiple functions. In small project like
this, I decided to have this monitor to collect data, calculate expected,
store results in a scoreboard and also check the data, which is output by
the DUT, after some latency (four clock cycles).
-
To implement a scoreboard,
I use queues from C++ STD.
The scoreboard is merely a queue (list in specman) of complex numbers,
represented as two-dimensional Cartesian coordinate.
class scoreboard {
public:
signed oa;
signed ob;
scoreboard(signed x, signed y) {//constructor
oa=x;
ob=y;
}
};
-
Same as the DUT uses sign extension, the monitor does it as well.
...
void sign_ext_p() {
while(true) {
sc_int<6> add_tmpa;
sc_int<6> add_tmpb;
sc_int<6> add_tmpc;
sc_int<6> add_tmpd;
a.read().range(7,7) == 0 ? add_tmpa=0 : add_tmpa=63;
b.read().range(7,7) == 0 ? add_tmpb=0 : add_tmpb=63;
c.read().range(7,7) == 0 ? add_tmpc=0 : add_tmpc=63;
d.read().range(7,7) == 0 ? add_tmpd=0 : add_tmpd=63;
ex_a.write( (add_tmpa, a.read()) );
ex_b.write( (add_tmpa, b.read()) );
ex_c.write( (add_tmpa, c.read()) );
ex_d.write( (add_tmpa, d.read()) );
wait();
}
}
...
-
The expected calculation as well as scoreboard operation is shown below:
...
void logic_p() {
while (!scbd_l.empty()) scbd_l.pop(); //clear after reset is de-asserted
//cout << "scbd_l was cleared " << " at " << sc_time_stamp() << endl;
while(true) {
sc_int<14> add_tmpa;
sc_int<14> add_tmpb;
add_tmpa = (ex_a.read()*ex_c.read()) - (ex_b.read()*ex_d.read());
add_tmpb = (ex_a.read()*ex_d.read()) + (ex_b.read()*ex_c.read());
//cout << "a=" << ex_a << " b=" << ex_b << " c=" << ex_c << " d=" << ex_d << " ";
//cout << add_tmpa << " " << add_tmpb << " at " << sc_time_stamp() << endl;
//add to scoreboard
scbd_tmp = new scoreboard((signed)add_tmpa, (signed)add_tmpb);
//
if(scbd_l.size() == 2) {
scoreboard *scbd_chk;
scbd_chk=&scbd_l.front();
e_oaq.write(scbd_chk->oa);
e_obq.write(scbd_chk->ob);
scbd_l.pop();
cmp_ok.write(1);
if(e_oaq.read() != oa.read()) {
cmp_ok.write(0);
cout << "a error exp " << e_oaq.read() << " got " << oa.read() << " at " << sc_time_stamp() << endl;
}
if(e_obq.read() != ob.read()) {
cmp_ok.write(0);
cout << "b error exp " << e_obq.read() << " got " << ob.read() << " at " << sc_time_stamp() << endl;
}
} else {
cmp_ok.write(1);
}
scbd_l.push(*scbd_tmp);
wait();
}
}
...
|