1. Trang chủ
  2. » Công Nghệ Thông Tin

High Level Synthesis: from Algorithm to Digital Circuit- P10 pptx

10 341 1
Tài liệu đã được kiểm tra trùng lặp

Đang tải... (xem toàn văn)

THÔNG TIN TÀI LIỆU

Thông tin cơ bản

Định dạng
Số trang 10
Dung lượng 360,94 KB

Các công cụ chuyển đổi và chỉnh sửa cho tài liệu này

Nội dung

5.2 C ++ SupportBecause SystemC is a class library implemented in C++, the advantages of high-level C++ constructs are available to hardware designers working in SystemC.. 5.2.1 Synthesi

Trang 1

5.2 C ++ Support

Because SystemC is a class library implemented in C++, the advantages of high-level C++ constructs are available to hardware designers working in SystemC Cynthesizer supports a large number of these constructs but, just as there are SystemVerilog constructs that are only intended for verification, there are C++ constructs that are only appropriate for modeling and testbench construction, not for synthesis

5.2.1 Synthesizable High-Level C ++ Constructs

The C++ constructs that are within the synthesizable subset can be used in ways that give SystemC synthesis advantages unattainable in any other hardware design language

• Encapsulation: C++ classes can be used in SystemC synthesis to manage the

complexity inherent in hardware design

Algorithmic functionality can be captured in a class for reuse Functions providing a public API for use of the algorithm can be made externally avail-able using the C++ “public” access control Internal computation functions and storage of internal state needed by the algorithm can be made private

Interface functionality can be encapsulated as discussed earlier creating a modular, reusable interface Modular interfaces expose a transaction-level func-tion call interface to the designer which allows them to be used without requiring the designer to be expert in the details of the interface protocol

• Construction of custom data types: Operator overloading is a C++ technique

whereby a class can provide a custom implementation for such built-in opera-tors as “*” (multiply) and “+” (add) This allows the construction of user defined datatypes such as for complex arithmetic, and matrix arithmetic Arithmetic oper-ations can be performed on these datatypes using conventional C++ syntax, e.g., a= b + c; which promotes ease-of-use and improves a reader’s ability to understand the code

• Development of configurable IP: C++ provides template specialization as a way

to write a single body of code which can represent a wide range of behaviors depending on the specific template parameters selected As a simple example, template specialization can be used to build a filter class that can operate on any given datatype, including user-defined custom datatypes

A more sophisticated example is the cynw float parameterized floating-point class that Forte has developed It allows the user to specify template parameters

to choose the exponent and mantissa widths as well and configure options such

as normalization and rounding behaviors

Trang 2

Supported C++ Constructs

Arithmetic operators Integer data types

s e r u t c u r t S s

r o t a r e o l a c i

g

L

Statically-determinable pointers Inheritance

if-else statements Operator overloading

switch-case statements Inferring memories from arrays

do, while, and for loops Inferring registers from arrays

break and continue statements Template classes and functions

Template specialization

5.2.2 Non-Synthesizable C ++ Constructs

One characteristic of the synthesis process is that it uses the source code of the high-level design without access to information that can only be determined at simulation time In other words, the synthesis process can only take advantage of language features that can be resolved statically and information that can be determined by inspection of the source code This is the source of most of the restrictions on C++ constructs that can be used:

• Pointer arithmetic: In the processor-based execution environment in which the C

and C++ languages were originally envisioned, all variables, structures, arrays and other storage elements are defined to exist within a single uniform address space

A hardware implementation may include multiple separate memories of dif-ferent kinds as well as storage elements implemented directly with flip-flops Clearly, in this environment making decisions based on the value of the address

of a variable is meaningless Consequently, pointer arithmetic is not supported for SystemC synthesis

• Pointer dereferencing: Similarly, accessing a specific storage element by its

address assumes a processor-based execution environment Therefore, in general, passing pointers and dereferencing them is not supported for SystemC synthesis Nevertheless, under some circumstances the target of the pointer can be unam-biguously determined by a static analysis of the source code For instance, if the address of an array is passed directly to a subroutine it is usually possible to statically determine the identity of the array in question In such cases the use of the pointer will be supported by synthesis

Trang 3

• Dynamic memory allocation: For reasons similar to those limiting the use of

pointers, allocation of storage elements using malloc(), free(), new, and delete is not supported for SystemC synthesis One notable exception is that allocation of sub-modules using new is supported

• Virtual functions: Virtual functions select the behavior of a particular object

based upon run-time determination of its class identity Since this cannot, in general, be determined statically, use of virtual functions is not supported for SystemC synthesis

5.3 Synthesizable Module Structure

Synthesizable SC MODULES can include multiple SC CTHREAD processes, and multiple SC METHOD processes In addition they can include submodules along with signals and channels to provide internal interconnect Because SC MODULES are C++ classes, they can also include data members of any synthesizable data type

to provided internal state, and member functions that can be used by the processes

to implement the required behavior

5.4 Concurrent Processes

Among the required hardware semantics provided by SystemC are process con-structs that allow a designer to directly express concurrent behaviors Two of these process constructs, SC CTHREAD, and SC METHOD, are appropriate for syn-thesis to hardware and are supported by Cynthesizer A module may contain any combination of these Use of multiple SC CTHREADs and/or SC METHODs in a single module is fully supported

This allows SystemC synthesis using Cynthesizer to encompass the areas tra-ditionally considered separately as the behavioral level and the register-transfer

Trang 4

level Using Cynthesizer, an engineer can combine high-level behavioral design with low-level register-transfer level design

Ordinarily, an engineer who wants to do a pure RTL design will choose a con-ventional HDL such as SystemVerilog or VHDL SystemC is more often used when high-level synthesis is needed for a substantial part of the design Typically a com-plex algorithm or a comcom-plex control structure is defined using an SC CTHREAD,

or multiple concurrently executing SC CTHREADs These are combined with

SC METHODS for implementation of small parts of the design that can be bet-ter specified at a low level Examples of these low-level parts of the design might include the clock boundary crossing logic or an asynchronous bypass path

5.4.1 SC CTHREAD Processes

The SC CTHREAD construct implements a clocked process The declaration of the process includes specification of a signal that will be used as the clock for the process The semantics of SC CTHREAD guarantee that the behavior of the process will be synchronized to this clock

In addition the reset signal is() function specifies a signal that will be used to reset the process Whenever the reset signal is asserted, the process is restarted in its initial state This allows explicit initialization behaviors to be written that determine the state of the flip-flops of the design when it comes out of reset During simulation, within the body of the subroutine that is the behavior of the SC CTHREAD process, execution proceeds sequentially until the process hits a wait() statement upon which the process is suspended until the next clock cycle

These characteristics make SC CTHREAD ideal for high-level synthesis of abs-tract, untimed behaviors combined with detailed cycle-accurate, pin-level interfaces Synthesizer interprets all behavior in an SC CTHREAD process that occurs before the first wait() statement as reset conditions Synthesis requires that this reset code be schedulable in a single clock cycle

void thread_func() {

// reset behavior must be // executable in a single cycle

reset_behavior();

wait();

// initialization may contain // any number of wait()s

// This part is only executed // once after a reset.

initialization();

// infinite loop – concurrent hardware

while (true) { rest_of_behavior();

} }

SC_CTHREAD

reset behavior

while (1) {

main loop

}

post-reset

initialization

module_name.cc

Trang 5

SC MODULE(sub)

{

// ports

sc in clk clk;

sc in<bool> rst;

SC CTOR(sub)

{

SC CTHREAD( thread func, clk.pos() );

reset signal is( rst, 1 );

}

void thread func()

{

// reset behavior

wait();

while(1)

{

}

}

};

The “SC CTHREAD” statement associates the thread func() function with the positive edge of the signal clk Cynthesizer implements such a thread as a circuit synchronous to that clock edge

The “reset signal is” statement makes the “1” level of the rst signal reset the thread

5.4.2 SC METHOD Processes

The SC METHOD process construct implements a triggered process associated with a sensitivity list The SC METHOD declaration includes a set of signals and rising-edge/falling-edge information that define the sensitivity list of the

SC METHOD The subroutine associated with the SC METHOD process is exe-cuted whenever any of the signal transitions in its sensitivity list occurs

These characteristics make SC METHOD ideal for synthesis of register-transfer level behaviors

The SC METHOD construct is used to express design functionality at a low level equivalent to RTL for synthesis SC METHOD provides a way to specify a sensitivity list that a specific clock signal with a thread, and has precise semantics for reset behavior

Trang 6

Cynthesizer can be used to synthesize synchronous SC METHODS using static sensitivity to a clock as follows

SC CTOR(sync)

{

CYN DEFAULT INPUT DELAY(.1,"delay");

SC METHOD( sync method );

sensitive pos( clk );

dont initialize();

}

Asynchronous SC METHODS using static sensitivity to a number of inputs can also be synthesized as follows

SC CTOR(async)

{

CYN DEFAULT INPUT DELAY(.1,"delay");

SC METHOD( async method );

sensitive << input 1 << input 2;

dont initialize();

}

SystemC semantics for SC METHOD also provide for dynamic sensitivity using the next trigger() function Dynamic sensitivity is not supported for synthesis SystemC semantics for SC METHOD also provide that each SC METHOD will

be executed once at the beginning of simulation This is meaningless in the con-text of synthesis, so disabling this behavior using the dont initialize() function is recommended

5.5 Modular Interfaces

In addition to simple signals carrying single-bit or scalar values, designers using Cynthesizer can implement high-level channels for communication By encapsulat-ing the low-level signals, ports, and protocol functions in modular interface socket classes, the designer is relieved of the tedious connection of individual signals, and can connect an entire interface, such as a connection to a memory, with a sin-gle binding function In addition, the modular interface code can be thoroughly tested once, and then reused many times without modification, avoiding numerous common errors and reducing debug time

These modular interfaces consist of C++ classes containing synthesizable Sys-temC code using constructs such as signals, ports, and synthesizable protocol code Common interfaces are provided by Forte Interfaces conforming to specific cor-porate standards can be written in SystemC by a corcor-porate CAD department, and project-specific interfaces can be written by any engineer

Trang 7

The abstraction and modularity capabilities of C++ and SystemC offer a unique advantage for high-level hardware design when they are used in this way to encap-sulate interfaces for ease-of-use and for reuse

The key technique is to use the C++ class mechanism to encapsulate the signal-level connections (i.e., ports) along with the code that implements the signal-signal-level protocol

In general, there are two complementary interfaces (e.g., input and output) that are implemented as two modular interface “socket” classes These are connected by binding calls to a modular interface “channel” class The processes in the modules containing the sockets call transaction-level interface functions defined in the socket classes to execute their interface behaviors

sc_in/out

sc_signal

Module 2

CTHREAD

Module 1

CTHREAD

Modular interface Channel

Modular interface

Output socket

f1()

Modular interface Input socket f2()

g1() g2()

5.5.1 Modular Output Socket

In its simplest form, an output socket for a ready/valid handshake interface might look like the following

// Output socket

template <class T>

class RV out

{

public:

sc in<bool> rdy;

sc out<bool> vld;

sc out<T> data;

RV out( const char* name=0 )

{}

// reset function called from SC CTHREAD

// establishes initial conditions

void reset()

Trang 8

vld = 0;

data = 0;

}

// put function called from SC CTHREAD

// executes output protocol

void put( const T& val )

{

do { wait(); } while ( !rdy.read() );

data.write( val );

vld = 1;

wait();

vld = 0;

}

};

Note that the sc in/sc out ports are incorporated into the modular interface socket

as data members The two transactions that the port implements, reset() and put(), are also implemented as member functions

5.5.2 Modular Input Socket

The corresponding input socket implements the reciprocal protocol Note that the direction of the ports is reversed from that of the output socket

// Output socket

template <class T>

class RV in

{

public:

RV in( const char* name=0 )

{}

sc out<bool> rdy;

sc in<bool> vld;

sc in<T> data;

//

// Protocol transaction functions

//

void reset()

{

rdy = 0;

}

Trang 9

T get()

{

wait();

rdy = 1;

do { wait(); } while ( !vld.read() );

rdy = 0;

return data.read();

}

};

5.5.3 Use of Modular Interfaces

The modular interface socket can be used in a design in a way that is similar to how a simple sc in or sc out port would be used The instantiation and binding

of the socket look just like an sc in or sc out port To execute the protocol, the

SC CTHREAD calls the transaction functions of the modular interface socket as follows

SC MODULE(sub)

{

sc in clk clk;

sc in<bool> rst;

RV in< sc uint<8> > din;

RV out< sc uint<8> > dout;

SC CTOR(sub)

{

SC CTHREAD( thread func, clk.pos() );

reset signal is( rst, 1 );

}

void thread func()

{

// reset behavior

din.reset();

dout.reset();

wait();

while (1)

{

sc uint<8> d = din.get();

dout.put( d + 1 );

}

}

};

Trang 10

5.5.4 Channel

The signals that are needed to provide connectivity for this interface can also be encapsulated in a channel class as follows

// Channel class

template <class T>

class RV

{

public:

sc signal<bool> rdy;

sc signal<bool> vld;

sc signal<T> data;

};

5.5.5 Binding

The addition of a couple of binding functions to the modular interface socket allows the entire interface to be bound using a single function call This reduces the number

of lines of code needed to use an interface, allows interchange of different inter-faces with minimal code modification, and prevents trivial errors due to misspelling and misconnecting individual signals For our example the binding functions in the output port are as follows

// Output socket

template <class T>

class RV out

{

//

// Binding functions

//

template <class C>

void bind( C& c )

{

rdy(c.rdy);

vld(c.vld);

data(c.data);

}

template <class C>

void operator() ( C& c )

Ngày đăng: 03/07/2014, 14:20

TỪ KHÓA LIÊN QUAN