CPE 626 The System C Language Aleksandar Milenkovic

  • Slides: 60
Download presentation
CPE 626 The System. C Language Aleksandar Milenkovic E-mail: Web: milenka@ece. uah. edu http:

CPE 626 The System. C Language Aleksandar Milenkovic E-mail: Web: milenka@ece. uah. edu http: //www. ece. uah. edu/~milenka

Outline Ø Ø Ø Introduction Data Types Modeling Combinational Logic Modeling Synchronous Logic Misc

Outline Ø Ø Ø Introduction Data Types Modeling Combinational Logic Modeling Synchronous Logic Misc A. Milenkovic 2

Introduction Ø Ø Ø What is System. C? Why System. C? Design Methodology Capabilities

Introduction Ø Ø Ø What is System. C? Why System. C? Design Methodology Capabilities System. C RTL A. Milenkovic 3

What is System. C An extension of C++ enabling modeling of hardware descriptions Ø

What is System. C An extension of C++ enabling modeling of hardware descriptions Ø System. C adds a class library to C++ Ø Mechanisms to model system architecture § Concurrency – multiple processes executed concurently § Timed events § Reactive behavior Ø Constructs to describe hardware § § Signals Modules Ports Processes Ø Simulation kernel A. Milenkovic 4

What is System. C Ø Provides methodology for describing § System level design §

What is System. C Ø Provides methodology for describing § System level design § Software algorithms § Hardware architecture Ø Design Flow § Create a system level model § Explore various algorithms o Simulate to validate model and optimize design § Create executable specifications o Hardware team and software team use the same specification Test input files A. Milenkovic 5

C++/System. C Development Environment Compiler Linker Debugger Source files in System. C (design +

C++/System. C Development Environment Compiler Linker Debugger Source files in System. C (design + testbenches) System. C Class Library and Simulation Kernel Make Simulator executable Run Test input files A. Milenkovic Test, log output files 6

Why System. C? Ø Designs become § Bigger in size § Faster in speed

Why System. C? Ø Designs become § Bigger in size § Faster in speed § Larger in complexity Ø Design description on higher levels of abstraction enables § Faster simulation § Hardware/software co-simulation § Architectural Exploration Fastest System RTL Chip A. Milenkovic Iteration Time Slowest 7

Why System. C? Ø Ø Ø System. C describes overall system System level design

Why System. C? Ø Ø Ø System. C describes overall system System level design Describing hardware architectures Describing software algorithms Verification IP exchange A. Milenkovic 8

Non-System. C Design Methodology System Designer Write conceptual C/C++ model RTL Designer Hand-over Understand

Non-System. C Design Methodology System Designer Write conceptual C/C++ model RTL Designer Hand-over Understand specification Partition design Verify against specification Write each block in HDL Write testbenches Reverify Synthesize To implementation A. Milenkovic 9

System. C Design Methodology System Designer Write conceptual C/C++ model RTL Designer Hand-over Understand

System. C Design Methodology System Designer Write conceptual C/C++ model RTL Designer Hand-over Understand specification Partition design Verify against specification Refine System. C model to RTL Write testbench Reverify Reuse testbench Synthesize To implementation A. Milenkovic 10

System Level Design Process System Level model Explore algorithms Verify against specifications Refine -

System Level Design Process System Level model Explore algorithms Verify against specifications Refine - Not synthesizable - Event driven - Abstract data types - Abstract communication -Untimed Timed model Explore architectures Do performance analysis Partition hardware / software Software RTOS - Synthesizable Hardware Behavioral model Refine Target code - Event driven RTL model - Algorithmic description - I/O cycle accurate - Clocked - Synthesizable - FSM - Clocked A. Milenkovic 11

System. C Capabilities Ø Modules § SC_MODULE class Ø Processes § SC_METHOD, SC_THREAD Ø

System. C Capabilities Ø Modules § SC_MODULE class Ø Processes § SC_METHOD, SC_THREAD Ø Ports: input, output, inout Ø Signals § resolved, unresolved § updates after a delta delay Ø Rich set of data types § 2 -value, 4 -value logic § fixed, arbitrary size Ø Clocks § built-in notion of clocks Event-base simulation Multiple abstraction levels Communication protocols Debugging support Waveform tracing § VCD: Value Change Dump (IEEE Std. 1364) § WIF: Waveform Interch. F. § ISDB: Integrated Signal Data Base Ø RTL synthesis flow Ø System and RTL modeling Ø Software and Hardware Ø Ø Ø A. Milenkovic 12

System. C Half Adder // File half_adder. h #include “systemc. h” // File half_adder.

System. C Half Adder // File half_adder. h #include “systemc. h” // File half_adder. cpp #include “half_adder. h” SC_MODULE(half_adder) { sc_in<bool> a, b; sc_out<bool> sum, carry; void half_adder: : prc_half_adder() { sum = a ^ b; carry = a & b; } void prc_half_adder(); SC_CTOR(half_adder) { SC_METHOD(prc_half_adder); sensitive << a << b; } }; A. Milenkovic 13

System. C Decoder 2/4 // File decoder 2 by 4. h #include “systemc. h”

System. C Decoder 2/4 // File decoder 2 by 4. h #include “systemc. h” // File decoder 2 by 4. cpp #include “decoder 2 by 4. h” SC_MODULE(decoder 2 by 4) { sc_in<bool> enable; sc_in<sc_uint<2> > select; sc_out<sc_uint<4> > z; void decoder 2 by 4: : prc_ decoder 2 by 4() { if (enable) { switch(select. read()) { case 0: z=0 x. E; break; case 1: z=0 x. D; break; case 2: z=0 x. B; break; case 3: z=0 x 7; break; } } else z=0 x. F; } void prc_decoder 2 by 4(); SC_CTOR(decoder 2 by 4) { SC_METHOD(prc_half_adder); sensitive(enable, select); } }; Note: Stream vs. Function notation sensitive << a << b; // Stream notation style sensitive(a, b); // Function notation style A. Milenkovic 14

Hierarchy: Building a full adder // a destructor ~full_adder() { delete ha 1_ptr; delete

Hierarchy: Building a full adder // a destructor ~full_adder() { delete ha 1_ptr; delete ha 2_ptr; } // File full_adder. h #include “systemc. h” SC_MODULE(full_adder) { sc_in<bool> a, b, carry_in; sc_out<bool> sum, carry_out; sc_signal<bool> c 1, s 1, c 2; void prc_or(); half_adder *ha 1_ptr, *ha 2_ptr; SC_CTOR(full_adder) { ha 1_ptr = new half_adder(“ha 1”); ha 1_ptr->a(a); ha 1_ptr->b(b); ha 1_ptr->sum(s 1); ha 1_ptr->carry(c 1); ha 2_ptr = new half_adder(“ha 2”); (*ha 2_ptr)(s 1, carry_in, sum, c 2); SC_METHOD(prc_or); sensitive << c 1 << c 2; } A. Milenkovic }; // File: full_adder. cpp #include “full_adder. h” void full_adder: : prc_or(){ carry_out = c 1 | c 2; } 15

Verifying the Functionality: Driver // File driver. h #include “systemc. h” // File: driver.

Verifying the Functionality: Driver // File driver. h #include “systemc. h” // File: driver. cpp #include “driver. h” SC_MODULE(driver) { sc_out<bool> d_a, d_b, d_cin; void driver: : prc_driver(){ sc_uint<3> pattern; pattern=0; void prc_driver(); while(1) { d_a=pattern[0]; d_b=pattern[1]; d_cin=pattern[2]; wait(5, SC_NS); pattern++; } SC_CTOR(driver) { SC_THREAD(prc_driver); } }; } A. Milenkovic 16

Verifying the Functionality: Monitor // File monitor. h #include “systemc. h” // File: monitor.

Verifying the Functionality: Monitor // File monitor. h #include “systemc. h” // File: monitor. cpp #include “monitor. h” SC_MODULE(monitor) { sc_in<bool> m_a, m_b, m_cin, m_sum, m_cout; void monitor: : prc_monitor(){ cout << “At time “ << sc_time_stamp() << “: : ”; cout <<“(a, b, carry_in): ”; cout << m_a << m_b << m_cin; cout << “(sum, carry_out): ”; cout << m_sum << m_cout << endl; } void prc_monitor(); SC_CTOR(monitor) { SC_THREAD(prc_monitor); sensitive << m_a, m_b, m_cin, m_sum, m_cout; } }; A. Milenkovic 17

Verifying the Functionality: Main // File full_adder_main. cpp #include “driver. h” #include “monitor. h”

Verifying the Functionality: Main // File full_adder_main. cpp #include “driver. h” #include “monitor. h” #include “full_adder. h” int sc_main(int argc, char * argv[]) { sc_signal<bool> t_a, t_b, t_cin, t_sum, t_cout; full_adder f 1(“Full. Adder. With. Half. Adders”); f 1 << t_a << t_b << t_cin << t_sum << t_cout; driver d 1(“Gen. Waveforms”); d 1. d_a(t_a); d 1. d_b(t_b); d 1. d_cin(t_cin); monitor m 1(“Monitor. Waveforms”); m 1 << t_a << t_b << t_cin << t_sum << t_cout; sc_start(100, SC_NS); return(0); } A. Milenkovic 18

Modeling Combinational Logic // File: bist_cell. h #include “systemc. h” SC_MODULE(bist_cell) { sc_in<bool> b

Modeling Combinational Logic // File: bist_cell. h #include “systemc. h” SC_MODULE(bist_cell) { sc_in<bool> b 0, b 1, d 0, d 1; sc_out<bool> z; void prc_bist_cell(); SC_CTOR(bist_cell) { SC_METHOD(prc_bist_cell); sensitive <<b 0<<b 1<<d 0<<d 1; } } // File: bist_cell. cpp #include “bist_cell. h” } void bist_cell: : prc_bist_cell(){ z = !(!(d 0&b 1)&!(b 0&d 1))|! (!(d 0&b 1)|!(b 0&d 1))); } A. Milenkovic void bist_cell: : prc_bist_cell(){ bool s 1, s 2, s 3; s 1 = !(b 0&d 1); s 2 = !(d 0&b 1); s 3 = !(s 2|s 1); s 2 = s 2&s 1; z = !(s 2|s 3); Ø Use SC_METHOD process with an event sensitivity list 19

Modeling Combinational Logic: Local Variables // File: bist_cell. cpp #include “bist_cell. h” void bist_cell:

Modeling Combinational Logic: Local Variables // File: bist_cell. cpp #include “bist_cell. h” void bist_cell: : prc_bist_cell(){ z = !(!(d 0&b 1)&!(b 0&d 1))|! !(d 0&b 1)&!(b 0&d 1))); } void bist_cell: : prc_bist_cell(){ bool s 1, s 2, s 3; Ø Local variables in the process (s 1, s 2, s 3) do not synthesize to wires Ø Hold temporary values (improve readability) Ø Are assigned values instantaneously (no delta delay) – one variable can represent many wires (s 2) § signals and ports are updated after a delta delay Ø Simulation is likely faster with local variables A. Milenkovic s 1 = !(b 0&d 1); s 2 = !(d 0&b 1); s 3 = !(s 2|s 1); s 2 = s 2&s 1; z = !(s 2|s 3); } 20

Modeling Combinational Logic: Reading and Writing Ports and Signals // File: xor_gates. h #include

Modeling Combinational Logic: Reading and Writing Ports and Signals // File: xor_gates. h #include “systemc. h” SC_MODULE(xor_gates) { sc_in<sc_uint<4> > bre, sty; sc_out <sc_uint<4> > tap; void prc_xor_gates(); SC_CTOR(xor_gates) { SC_METHOD(prc_xor_gates); sensitive << bre << sty; } } Ø Use read() and write() methods for reading and writing values from and to a port or signal // File: xor_gates. cpp #include “xor_gates. h” void bist_cell: : prc_xor_gates(){ tap = bre ^ sty; } void bist_cell: : prc_xor_gates(){ tap = bre. read() ^ sty. read(); } A. Milenkovic 21

Modeling Combinational Logic: Logical Operators // File: xor_gates. h #include “systemc. h” const int

Modeling Combinational Logic: Logical Operators // File: xor_gates. h #include “systemc. h” const int SIZE=4; SC_MODULE(xor_gates) { sc_in<sc_uint<SIZE> > bre, sty; sc_out <sc_uint<SIZE> > tap; void prc_xor_gates(); SC_CTOR(xor_gates) { SC_METHOD(prc_xor_gates); sensitive << bre << sty; } } Ø ^ - xor Ø & - and Ø | - or // File: xor_gates. cpp #include “xor_gates. h” void bist_cell: : prc_xor_gates(){ tap = bre. read() ^ sty. read(); } A. Milenkovic 22

Modeling Combinational Logic: Arithmetic Operations sc_uint<4> write_addr; sc_int<5> read_addr; read_addr = write_addr + read_addr;

Modeling Combinational Logic: Arithmetic Operations sc_uint<4> write_addr; sc_int<5> read_addr; read_addr = write_addr + read_addr; Ø Note: all fixed precision integer type calculations occur on a 64 -bit representation and appropriate truncation occurs depending on the target result size Ø E. g. : § § write_addr is zero-extended to 64 -bit read_addr is sign-extended to 64 -bit + is performed on 64 -bit data result is truncated to 5 -bit result and assigned back to read_addr A. Milenkovic 23

Modeling Combinational Logic: Unsigned Arithmetic // File: u_adder. h #include “systemc. h” SC_MODULE(u_adder) {

Modeling Combinational Logic: Unsigned Arithmetic // File: u_adder. h #include “systemc. h” SC_MODULE(u_adder) { sc_in<sc_uint<4> > a, b; sc_out <sc_uint<5> > sum; void prc_u_adder(); SC_CTOR(u_adder) { SC_METHOD(prc_u_adder); sensitive << a << b; } }; // File: u_adder. cpp #include “u_adder. h” void u_adder : : prc_s_adder(){ sum = a. read() + b. read(); } A. Milenkovic 24

Modeling Combinational Logic: Signed Arithmetic // File: s_adder. h #include “systemc. h” SC_MODULE(s_adder) {

Modeling Combinational Logic: Signed Arithmetic // File: s_adder. h #include “systemc. h” SC_MODULE(s_adder) { sc_in<sc_int<4> > a, b; sc_out <sc_int<5> > sum; void prc_s_adder(); SC_CTOR(s_adder) { SC_METHOD(prc_s_adder); sensitive << a << b; } }; // File: s_adder. cpp #include “s_adder. h” void s_adder : : prc_s_adder(){ sum = a. read() + b. read(); } A. Milenkovic 25

Modeling Combinational Logic: Signed Arithmetic (2) // File: s_adder_c. h #include “systemc. h” //

Modeling Combinational Logic: Signed Arithmetic (2) // File: s_adder_c. h #include “systemc. h” // File: s_adder. cpp #include “s_adder_c. h” SC_MODULE(s_adder_c) { sc_in<sc_int<4> > a, b; sc_out <sc_int<4> > sum; sc_out <bool> carry_out; void s_adder_c: : prc_ s_adder_c(){ sc_int<5> temp; temp = a. read() + b. read(); sum = temp. range(3, 0); carry_out = temp[4]; void prc_s_adder_c(); } SC_CTOR(s_adder_c) { SC_METHOD(prc_s_adder_c); sensitive << a << b; } }; A. Milenkovic 26

Modeling Combinational Logic: Relational Operators // File: gt. h #include “systemc. h” const WIDTH=8;

Modeling Combinational Logic: Relational Operators // File: gt. h #include “systemc. h” const WIDTH=8; // File: gt. cpp #include “gt. h” void gt: : prc_gt(){ sc_int<WIDTH> atemp, btemp; SC_MODULE(gt) { sc_in<sc_int<4> > a, b; sc_out <bool> z; void prc_gt(); SC_CTOR(gt) { SC_METHOD(prc_gt); sensitive << a << b; } }; atemp = a. read(); btemp = b. read(); z = sc_uint<WIDTH>(atemp. range(WIDTH/2 -1, 0)) > sc_uint<WIDTH>(btemp. range(WIDTH-1, WIDTH/2)) } A. Milenkovic 27

Modeling Combinational Logic: Vector and Ranges // Bit or range select of a port

Modeling Combinational Logic: Vector and Ranges // Bit or range select of a port // or a signal is not allowed sc_in<sc_uint<4> > data; sc_signal<sc_bv<6> > counter; sc_uint<4> temp; sc_uint<6> cnt_temp; bool mode, preset; mode = data[2]; // not allowed //instead temp = data. read(); mode = temp[2]; counter[4] = preset; // not allowed cnt_temp = counter; cnt_temp[4] = preset; counter = cnt_temp; A. Milenkovic 28

Multiple Processes and Delta Delay // File: mult_proc. h #include “systemc. h” // File:

Multiple Processes and Delta Delay // File: mult_proc. h #include “systemc. h” // File: mult_proc. cpp #include “mult_proc. h” SC_MODULE(mult_proc) { sc_in<bool> in; sc_out<bool> out; void mult_proc: : mult_proc 1(){ c 1 = !in; } sc_signal<bool> c 1, c 2; void mult_proc 1(); void mult_proc 2(); void mult_proc 3(); SC_CTOR(mult_proc) { SC_METHOD(mult_proc 1); sensitive << in; SC_METHOD(mult_proc 2); sensitive << c 1; SC_METHOD(mult_proc 3); sensitive << c 2; } void mult_proc: : mult_proc 2(){ c 2 = !c 1; } void mult_proc: : mult_proc 3(){ out = !c 2; } }; A. Milenkovic 29

If Statement // File: simple_alu. cpp #include “simple_alu. h” // File: simple_alu. h #include

If Statement // File: simple_alu. cpp #include “simple_alu. h” // File: simple_alu. h #include “systemc. h” const int WS=4; void simple_alu: : prc_simple_alu(){ if(ctrl) z = a. read() & b. read(); else z = a. read() | b. read(); } SC_MODULE(simple_alu) { sc_in<sc_uint<WS> > a, b; sc_in<bool> ctrl; sc_out< sc_uint<WS> > z; void prc_simple_alu(); SC_CTOR(simple_alu) { SC_METHOD(prc_simple_alu); sensitive << a << b << ctrl; } }; A. Milenkovic 30

If Statement: Priority encoder // File: priority. h #include “systemc. h” const int IS=4;

If Statement: Priority encoder // File: priority. h #include “systemc. h” const int IS=4; const int OS=3; // File: priority. cpp #include “priority. h” void priority: : prc_priority(){ sc_uint<IS> tsel; SC_MODULE(priority) { sc_in<sc_uint<IS> > sel; sc_out< sc_uint<OS> > z; tsel = sel. read(); if(tsel[0]) z = 0; else if (tsel[1]) z = 1; else if (tsel[2]) z = 2; else if (tsel[3]) z = 3; else z = 7; void prc_priority(); SC_CTOR(priority) { SC_METHOD(prc_priority); sensitive << sel; } } }; A. Milenkovic 31

Switch Statement: ALU // File: alu. h #include “systemc. h” const int WORD=4; enum

Switch Statement: ALU // File: alu. h #include “systemc. h” const int WORD=4; enum op_type {add, sub, mul, div}; // File: alu. cpp #include “alu. h” void priority: : prc_alu(){ sc_uint<WORD> ta, tb; SC_MODULE(alu) { sc_in<sc_uint<WORD> > a, b; sc_in<op_type> op; sc_out< sc_uint<WORD> > z; ta = a. read(); tb = b. read(); switch (op) { case add: z = case sub: z = case mul: z = case div: z = } void prc_alu(); SC_CTOR(alu) { SC_METHOD(prc_alu); sensitive << a << b << op; } ta+tb; ta–tb; ta*tb; ta/tb; break; } }; A. Milenkovic 32

Loops Ø C++ loops: for, do-while, while Ø System. C RTL supports only for

Loops Ø C++ loops: for, do-while, while Ø System. C RTL supports only for loops Ø For loop iteration must be a compile time constant A. Milenkovic 33

Loops: An Example // File: demux. h #include “systemc. h” const int IW=2; const

Loops: An Example // File: demux. h #include “systemc. h” const int IW=2; const int OW=4; SC_MODULE(demux) { sc_in<sc_uint<IW> > a; sc_out<sc_uint<OW> > z; void prc_demux(); // File: demux. cpp #include “demux. h” void priority: : prc_demux(){ sc_uint<3> j; sc_uint<OW> temp; for(j=0; j<OW; j++) if(a==j) temp[j] = 1; else temp[j] = 0; } SC_CTOR(demux) { SC_METHOD(prc_demux); sensitive << a; } }; A. Milenkovic 34

Methods Ø Methods other than SC_METHOD processes can be used in a System. C

Methods Ø Methods other than SC_METHOD processes can be used in a System. C RTL A. Milenkovic 35

Methods // File: odd 1 s. cpp #include “odd 1 s. h” // File:

Methods // File: odd 1 s. cpp #include “odd 1 s. h” // File: odd 1 s. h #include “systemc. h” const int SIZE = 6; SC_MODULE(odd 1 s) { sc_in<sc_uint<SIZE> > data_in; sc_out<bool> is_odd; bool is. Odd(sc_uint<SIZE> abus); void prc_odd 1 s(); void odd 1 s: : prc_odd 1 s(){ is_odd = is. Odd(data_in); } bool odd 1 s: is. Odd (sc_uint<SIZE> abus) { bool result; int i; SC_CTOR(odd 1 s) { SC_METHOD(prc_odd 1 s); sensitive << data_in; } }; for(i=0; i<SIZE; i++) result = result ^ abus[i]; return(result); } A. Milenkovic 36

Modeling Synchronous Logic: Flip-flops // File: dff. h #include “systemc. h” // File: dff.

Modeling Synchronous Logic: Flip-flops // File: dff. h #include “systemc. h” // File: dff. cpp #include “dff. h” SC_MODULE(dff) { sc_in<bool> d, clk; sc_out<bool> q; void dff: : prc_dff(){ q = d; } void prc_dff(); SC_CTOR(dff) { SC_METHOD(prc_dff); sensitive_pos << clk; } }; A. Milenkovic 37

Registers // File: reg. h #include “systemc. h” const int WIDTH = 4; //

Registers // File: reg. h #include “systemc. h” const int WIDTH = 4; // File: reg. cpp #include “reg. h” SC_MODULE(reg) { sc_in<sc_uint<WIDTH> > cstate; sc_in<bool> clock; sc_out< sc_uint<WIDTH> > nstate; void reg: : prc_reg(){ cstate = nstate; } void prc_reg(); SC_CTOR(dff) { SC_METHOD(prc_dff); sensitive_neg << clock; } }; A. Milenkovic 38

Sequence Detector: “ 101” // File: sdet. h #include “systemc. h” // File: sdet.

Sequence Detector: “ 101” // File: sdet. h #include “systemc. h” // File: sdet. cpp #include “sdet. h” SC_MODULE(sdet) { sc_in<bool> clk, data; sc_out<bool> sfound; void sdet: : prc_sdet(){ first = data; second = first; third = second } sc_signal<bool> first, second, third; // synchronous logic process void prc_sdet(); // comb logic process void prc_out(); void sdet: : prc_out(){ sfound = first & (!second) & third; } SC_CTOR(sdet) { SC_METHOD(prc_sdet); sensitive_pos << clk; SC_METHOD(prc_out); sensitive << first << second << third; } }; A. Milenkovic 39

Counter: Up-down, Async Negative Clear // File: cnt 4. h #include “systemc. h” const

Counter: Up-down, Async Negative Clear // File: cnt 4. h #include “systemc. h” const int CSIZE = 4; SC_MODULE(sdet) { sc_in<bool> mclk, cl, updown; sc_out<sc_uint<CSIZE> > dout; void prc_cnt 4(); SC_CTOR(cnt 4) { SC_METHOD(prc_cnt 4); sensitive_pos << mclk; sensitive_neg << cl; } // File: cnt 4. cpp #include “cnt 4. h” void sdet: : prc_cnt 4(){ if(!clear) data_out = 0; else if(updown) dout=dout. read()+1; else dout=dout. read()-1; } }; A. Milenkovic 40

Latches // File: latch. h #include “systemc. h” // File: latch. cpp #include “latch.

Latches // File: latch. h #include “systemc. h” // File: latch. cpp #include “latch. h” SC_MODULE(latch) { sc_in<bool> d, en; sc_out<bool> q; void latch: : prc_latch(){ if(en) q = d; } void prc_latch(); SC_CTOR(latch) { SC_METHOD(prc_latch); sensitive << en << d; } }; A. Milenkovic 41

Avoiding latches // File: su. cpp #include “su. h” void su: : prc_su(){ switch

Avoiding latches // File: su. cpp #include “su. h” void su: : prc_su(){ switch (cs) { case s 0: case s 3: z = 0; break; case s 1: z = 3; break; default: z = 1; break; } } void su: : prc_su(){ z = 1; switch (cs) { case s 0: case s 3: z = 0; break; case s 1: z = 3; break; } } A. Milenkovic 42

Tri-state drivers // File: tris. h #include “systemc. h” // File: tris. cpp #include

Tri-state drivers // File: tris. h #include “systemc. h” // File: tris. cpp #include “tris. h” SC_MODULE(tris) { sc_in<bool> rdy, dina, dinb; sc_out<bool> out; void tris: : prc_tris(){ if(rdy) out = sc_logic(‘Z’); else out = sc_logic(dina. read() & dinb. read()); void prc_tris(); SC_CTOR(tris) { SC_METHOD(prc_tris); sensitive << dina << dinb << rdy; } } }; A. Milenkovic 43

More on latches // File: su. h #include “systemc. h” enum states {s 0,

More on latches // File: su. h #include “systemc. h” enum states {s 0, s 1, s 2, s 3}; const int ZS = 2; SC_MODULE(su) { sc_in<states> cs; sc_out<sc_uint<ZS> > z; void prc_su(); SC_CTOR(su) { SC_METHOD(prc_su); sensitive << cs; } }; // File: su. cpp #include “su. h” void su: : prc_su(){ switch (cs) { case s 0: case s 3: z = 0; break; case s 1: z = 3; break; } } When cs has value s 2 port z is not assigned a value => to model the behavior of the process a latch is inferred for port z. A. Milenkovic 44

Modeling an FSM Ø Moore Machine: Outputs depend only on the present state Combinational

Modeling an FSM Ø Moore Machine: Outputs depend only on the present state Combinational Network Inputs(X) Combinational Network Next State (Q+) State Register State(Q) Clock A. Milenkovic 45

Modeling an FSM Ø Mealy Machine: Outputs depend on both the present state and

Modeling an FSM Ø Mealy Machine: Outputs depend on both the present state and inputs Combinational Network Inputs(X) Combinational Network Next State (Q+) State Register State(Q) Clock A. Milenkovic 46

Moore FSM a s 1 s 0 a !a !a z=0 z=1 a s

Moore FSM a s 1 s 0 a !a !a z=0 z=1 a s 3 !a s 2 !a a z=0 z=1 A. Milenkovic 47

Modeling an FSM: Moore Machine // File: moore. h #include “systemc. h” SC_MODULE(moore) {

Modeling an FSM: Moore Machine // File: moore. h #include “systemc. h” SC_MODULE(moore) { sc_in<bool> a, clk, reset; sc_out<bool> z; enum states {s 0, s 1, s 2, s 3}; sc_signal<states> mstate; void prc_moore(); SC_CTOR(moore) { SC_METHOD(prc_moore); sensitive_pos << clk; } }; A. Milenkovic 48

Modeling an FSM: Moore Machine // File: moore. cpp #include “moore. h” void moore:

Modeling an FSM: Moore Machine // File: moore. cpp #include “moore. h” void moore: : prc_moore(){ if(reset) mstate = s 0; else switch (mstate) { case s 0: z = 1; mstate case s 1: z = 0; mstate case s 2: z = 0; mstate case s 3: z = 0; mstate } } = = a a ? ? s 0 s 2 s 1 : : s 2; s 3; break; When synthesized, how many DFF we have? A. Milenkovic 49

Modeling an FSM: Moore Machine // File: moore 2. h #include “systemc. h” SC_MODULE(moore

Modeling an FSM: Moore Machine // File: moore 2. h #include “systemc. h” SC_MODULE(moore 2) { sc_in<bool> a, clk, reset; sc_out<bool> z; enum states {s 0, s 1, s 2, s 3}; sc_signal<states> mstate; void prc_states(); void prc_outputs(); SC_CTOR(moore 2) { SC_METHOD(prc_states); sensitive_pos << clk; SC_METHOD(prc_outputs); sensitive << mstate; } }; A. Milenkovic 50

Modeling an FSM: Moore Machine // File: moore 2. cpp #include “moore 2. h”

Modeling an FSM: Moore Machine // File: moore 2. cpp #include “moore 2. h” void moore 2: : prc_states(){ if(reset) mstate = s 0; else switch (mstate) { case s 0: mstate = a ? case s 1: mstate = a ? case s 2: mstate = a ? case s 3: mstate = a ? } } void moore 2: : prc_outputs(){ switch(mstate) { case s 3: case s 0: z = 1; break; case s 1: case s 2: z = 0; break; } } s 0 s 2 s 1 A. Milenkovic : : s 2; s 3; break; 51

Writing Test-benches Ø Typical test-bench structure stimulus. cpp stimulus. h dut. cpp dut. h

Writing Test-benches Ø Typical test-bench structure stimulus. cpp stimulus. h dut. cpp dut. h monitor. cpp monitor. h main. cpp A. Milenkovic 52

System. C Simulation Control Ø sc_clock: generate clock signal Ø sc_trace: dump trace information

System. C Simulation Control Ø sc_clock: generate clock signal Ø sc_trace: dump trace information into a file in the specified format Ø sc_start: run simulation for specified time Ø sc_stop: stop simulation Ø sc_time_stamp: get current simulation time with time units Ø sc_simulation_time: get current simulation time without time units Ø sc_cycle, sc_initialize: use to perform cycle-level simulation Ø sc_time: specify a time value A. Milenkovic 53

Sc_clock // on-off period of 10 ns, duty cycle 50%, initial value is 1

Sc_clock // on-off period of 10 ns, duty cycle 50%, initial value is 1 sc_clock rclk(“rclk”, 10, SC_NS); // 10 ns period, duty is 20%, // first edge occurs at 5 ns, initial value is 0 sc_clock mclk(“mclk”, 10, SC_NS, 0. 2, 5, SC_NS, false); Draw waveforms for “rclk” and “mclk”! A. Milenkovic 54

Sc_trace Ø Formats supported § VCD – Value Change Dumped § WIF – Waveform

Sc_trace Ø Formats supported § VCD – Value Change Dumped § WIF – Waveform Interchange Format § ISDB – Integrated Signal Data Base // open a file; file myvcddump. vcd will be created sc_trace_file *tfile = sc_create_vcd_trace_file(“myvcddump”) // in general: sc_create_{vcd|wif|isdb}_trace_file // specify signals whose values you want to be saved sc_trace(tfile, signal_name, “signal_name”); // close file sc_close_vcd_trace_file(pointer_to_trace_file); A. Milenkovic 55

Sc_start, sc_stop Ø Tells the simulation kernel to start simulation // run simulation for

Sc_start, sc_stop Ø Tells the simulation kernel to start simulation // run simulation for 100 ms sc_start(100, SC_MS); // run simulator forever sc_start(-1); Ø Stop simulation sc_stop(); A. Milenkovic 56

Sc_time_stamp, sc_simulation_time Ø Returns current simulation time // run simulation for 100 ms cout

Sc_time_stamp, sc_simulation_time Ø Returns current simulation time // run simulation for 100 ms cout << “Current time is “ << sc_time_stamp() << endl; Ø Returns an integer value of type double curr_time = sc_simulation_time(); A. Milenkovic 57

sc_cycle, sc_initialize // initialize simulation kernel sc_initialize(); // sc_cycle executes all the processes that

sc_cycle, sc_initialize // initialize simulation kernel sc_initialize(); // sc_cycle executes all the processes that are ready to run // until no more processes are ready to run; // then, traces the signals and advances the simulation // by the specified amount of time sc_cycle(10, SC_US); // 10 microseconds A. Milenkovic 58

sc_time // specify a time value sc_time t 1 (100, SC_NS); sc_time t 2

sc_time // specify a time value sc_time t 1 (100, SC_NS); sc_time t 2 (20, SC_PS); sc_start(t 1); // run simulation for 100 ns sc_start(100, SC_NS); sc_cycle(t 2); sc_set_time_resolution(100, SC_PS); A. Milenkovic 59

Creating waveforms // file wave. h #include “systemc. h” // file wave. cpp #include

Creating waveforms // file wave. h #include “systemc. h” // file wave. cpp #include “wave. h” SC_MODULE(wave) { sc_out<bool> sig_out; void wave: : prc_wave() { sig_out = 0; wait(5, SC_NS); sig_out = 1; wait(2, SC_NS); sig_out = 0; wait(5, SC_NS); sig_out = 1; wait(8, SC_NS); sig_out = 0; } void prc_wave(); SC_CTOR(wave) { SC_THREAD(prc_wave); } }; A. Milenkovic 60