I have implemented a 4 bit adder with delay in its output port.
SC_MODULE(adder4){
sc_in<sc_uint<4>> A,B;
sc_out<sc_uint<4>> OUT;
sc_event ev;
sc_uint<4> val_a,val_b,val_s;
void add(){
val_a = A.read();
val_b = B.read();
val_s = val_a + val_b;
ev.notify(2,SC_NS);
}
void write(){
OUT.write(val_s);
ev.cancel();
}
SC_CTOR(adder4){
SC_METHOD(add);
dont_initialize();
sensitive<<A<<B;
SC_METHOD(write);
dont_initialize();
sensitive<<ev;
}
};
My question is:
This is an edited version of original answer that had an event dependency missing in the adder thread. This code has that dependency added.
Better is subjective I guess and is always subject to "better under what criteria". Here is an alternative method which is something like I would use. I say something like as it's all mushed into a bunch of templates but if you untangle them it comes out to something morally equivalent to the code below.
Since we are dealing with time I have added a system clock and a driver module to provide the inputs to the adder. I have also traced the signals to a vcd file so we can inspect the waveforms for correct delay against the system clock.
#include <systemc.h>
using data_t = sc_uint<4>;
const auto delay = sc_time(2.0, SC_NS);
// Asynchronous adder with output propagation delay
SC_MODULE(adder4){
sc_in<data_t> A,B;
sc_out<data_t> OUT;
void add(){
while(true){
wait(A.default_event() | B.default_event());
auto sum = A.read() + B.read(); //calculate sum
wait(delay); //wait delay
OUT.write(sum); //write sum after delay
}
}
SC_CTOR(adder4){
SC_THREAD(add) //thread instead of process
}
};
SC_MODULE(driver){
unsigned a,b; //internal data values
sc_in<bool> clk_in; //system clock input
sc_out<data_t> out_a, out_b; //driver data outputs
void proc(){
out_a.write(a);
out_b.write(b);
//change internal data to drive test device. just increment
a += 1;
b += 2;
}
SC_CTOR(driver){
a = b = 0;
SC_METHOD(proc);
sensitive << clk_in.pos();
dont_initialize();
}
};
using signal_t = sc_signal<data_t>;
int sc_main(int, char**){
sc_clock clk("clk", 5, SC_NS); //system clock
driver drv("driver"); //test case driver
adder4 adder("adder"); //device under test
//connect devices
signal_t s1, s2, s3;
drv.clk_in(clk);
drv.out_a(s1);
drv.out_b(s2);
adder.A(s1);
adder.B(s2);
adder.OUT(s3);
//trace signals to waveforms.vcd
sc_trace_file *tf = sc_create_vcd_trace_file("waveforms");
sc_trace(tf, clk, "clk");
sc_trace(tf, s1, "A");
sc_trace(tf, s2, "B");
sc_trace(tf, s3, "OUT");
sc_start(40, SC_NS);
sc_close_vcd_trace_file(tf);
return 0;
}
Executing this generates the vcd file "waveforms.vcd" which I have displayed in GTKViewer, an image of which is shown below. It can be clearly seen that the adder output is delayed by 2ns. Is this "the best" or "better"? I can't say but it is, more or less, a standard(ish) method of meeting your requirements. Leastwise it fulfills the requirement of being an alternative method as you asked. There are surely countably infinite ways of achieving the same result but, as I say, it's a standard(ish) method.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.