Developers Club geek daily blog

2 years, 3 months ago
Development of the digital equipment on C ++/SystemC eyes of SystemVerilog of the programmer

SystemC is a library for C ++ allowing to model various hardware systems at the different abstraction layer. It is supported as the traditional discrete and event modeling usual to programmers on Verilog and VHDL, and analog modeling in the spirit of SPICE/Verilog AMS. The library and methodology for virtual prototyping, library for writing of test environments and verification with use of randomized tests is also included in the package.

In this I will tell about a synthesizable subset of SystemC, comparing it to synthesizable SystemVerilog. I use SystemC about 3 years, and before wrote several years on Verilog/SystemVerilog. I will try to cover a subject from the different parties: since philosophical reasonings on origins of SystemC, the short overview of an ecosystem and tools and finishing with practical examples of syntax and semantics.

It is meant that readers are familiar with Verilog and C ++.

Reflections about SystemC origins


For the long history the industry of development of electronics found application for a set of programming languages and generated a huge number of DSLEY (Domain-specific languages). If to imagine hypothetical full-stack of the bureaucrat (by analogy with full-stack the web programmer) which alone can design a modern chip, from algorithm before implementation in silicon, then he in addition to knowledge of a hardware (an arikhitektur of the computer, the electronic engineer, algorithms from application area, etc.) should own the whole heap of various languages: Matlab for algorithm elaboration, Verilog or VHDL for the description of RTL model, SystemVerilog/E/Vera for writing of tests and a test environment, TCL for writing of scripts of a managing CAD packets, SPICE/Verilog-AMS for modeling of analog subsystems, SKILL or Python for generation of topology, SI/Asm for writing of various firmware. At desire the list can be continued further.

Of course in the nature such universal engineers practically do not meet and the project is done by several commands, each of which well understands rather narrow area. However, very often it is necessary to combine work at several development stages. For example, it is easy to provide that the person the IP model of the block will write the written RTL for it and test set for verification. It in turn creates request for creation of the universal languages suitable for a solution of adjacent tasks.

In the world of digital microelectronics SystemVerilog which in addition to classical Verilog (with small expansions), comprises an object-oriented language for writing of test environments, language of statements (assertions) for formal verification and also special constructions for randomization and the analysis of a test coverage became such universal language. In some sense of SystemVerilog it is not absolutely modern language, and it is rather the conglomerate of languages which is stuck together by the general syntax.

But what if we want bigger? Language in which in addition to all above-mentioned it is possible to develop algorithms, to write built-in software, to create virtual prototypes. Isn't it time for DSL steam to add to SystemVerilog still?

Development of the digital equipment on C ++/SystemC eyes of SystemVerilog of the programmer
We need to go deeper

There is however also other approach: instead of inventing all of new DSLEY, it is possible to create the program libraries intended for a solution of a special class of tasks. In such way creators of SystemC — library for C ++, allowing to model the digital equipment went. Though in some sense of SystemC is Dls'Em created by means of metac programming ++ itself C ++ at the same time do not extend new syntactic constructions. Metaprogramming is widely applied also in others C ++ libraries.

Such approach has pluses and minuses. The main plus of C ++ in its universality: today you can write a hardver on SystemC, and tomorrow GUI on Qt. (Though it is necessary to spend a lot of time for studying of each of these libraries). The main minus in syntax: the code on pure DSL will be much more beautiful, especially if it is necessary to make something simple (for simple modules the code on Verilog will be more compact and simpler, than a similar code on SystemC).

In addition to insufficient universality Verilog have also other problem: it is very low-level. In some sense synthesizable Verilog is the macroassembler for the equipment (if the assembler for the equipment is the logic diagram). The new constructions which appeared in synthesizable SystemVerilog do not solve this problem of a nizkourovnevost. Very often it is necessary to resort to use of various generators of a code on Verilog, for example scripts on Python. Among my colleagues the idea to insert a code on Perl in modules on Verilog was popular. The hybrid received in such way was called perlilogy. I think many are familiar with Verilog-mode for emacs which is able to generate Verilog a code for module binding.

In comparison with SystemVerilog, synthesizable SystemC allows much more. Yes, you can write a synthesizable code with classes! At a solution of complex challenges of means of abstraction of C ++ allow to write more elegant (simple and compact) a code.

SystemC ecosystem


Let's consider the main software tools with which developers should deal on SystemVerilog and SystemC.

Development environment

SystemVerilog:
Most of programmers on Verilog for writing of a code use a text editor: support of Verilog is in Vim, Emacs, Sublime Text, Notepad ++, Slickedit and other popular editors. Writing of a code in the test editor can seem to application programmers archaism: the majority of them use smart IDE with the auto-hints automated by refaktoringa, convenient navigation. However in the world of synthesizable Verilog of huge advantage of use there is no IDE: it is explained by the fact that all functionality breaks into modules absolutely independent from each other. All context with which the developer of the separate module usually works finds room in one file. Quite another matter with writing testbenchy on SystemVerilog, here quite can IDE, such as DVT is useful.

SystemC:
When writing synthesized C ++/SystemC by a simple text editor not to manage any more. Fortunately, there is a great number of C ++ IDE (including free) which are able to cope with a code on SystemC. For example, many MS Visual Studio can use usual. I long time used Eclipse CDT and Netbeans for writing of a code on C ++/SystemC. Lately I try Clion from Jetbrains.
Development of the digital equipment on C ++/SystemC eyes of SystemVerilog of the programmerWriting of SystemC of a code in Clion

Simulation and debugging

SystemVerilog:
For simulation and debugging of a code on Verilog the HDL simulator is used. Exist both free (IcarusVerilog), and paid simulators. In comparison with the free simulator commercial solutions provide a high speed of simulation and provide convenient graphical environments for debugging.

SystemC:
With SystemC the situation in general is similar: it is possible to use the referensny simulator and GDB for debugging, but when it is necessary to debug some more or less difficult signal protocol it is necessary to use one of commercial simulators.
Development of the digital equipment on C ++/SystemC eyes of SystemVerilog of the programmer
Debugging of SystemC in the simulator

Synthesis

SystemVerilog:
Synthesis of SystemVerilog is supported by the main FPGA and ASIC vendors. Including there are also free versions of packets for FPGA, than many Russian higher education institutions for training of students in elements of digital circuit engineering use.

SystemC:
For synthesis of SystemC special packets of high-level synthesis (English High-level Synthesis, HLS) are used. What in them such high-level is asked by you? All the matter is that HLS packets, in addition to the traditional RTL code written on SystemC are able to synthesize also purely behavioural ("untimed") code, automatically inserting registers, there where it is necessary.

The majority of HLS of packets can synthesize also pure C/C ++, SystemC is used only when it is necessary to add a modularity and signal interfaces. In some sense synthesis with C/C ++ is technology for the development of accelerators competing with synthesis with OpenCL. Though when using SystemC we are not limited only to development of accelerators, and we can develop any digital circuits. A bit later I will tell about HLS a little in more detail.

On a packet HLS output we usually have usual RTL modules on Verilog which then are synthesized by means of synthesizer Verilog.

Unfortunately, all existing HLS with support of SystemC exclusively commercial also cost a lot of money. There are no free versions though to universities everything is sold at greatly reduced prices.
The best means of synthesis of SystemC in the market are Stratus from Cadence and Catapult C from Calypto/Mentor Graphics.

Other EDA packets for SystemC

In addition to writing of a synthesizable code, SystemC it is rather widely used for virtual prototyping. Creation of virtual prototypes (emulators) on C ++/SystemC is used in packets of Synopsys Virtualizer, Mentor Graphics Vista, Cadence Virtual System Platform. At the same time it is impossible to tell that SystemC in this market is the dominating solution: there are also SystemC products which are not using for example of WindRiver Simics.

On it the survey part of article comes to the end. Time to plunge into a code came.

Development of the digital equipment on C ++/SystemC eyes of SystemVerilog of the programmer
Immersion in a code

Synthesizable SystemC. Basic construction blocks


Here I will not describe completely all SystemC standard, I will walk only on the most necessary. All examples will be constructed on comparison of SystemVerilog and SystemC.
Data types

SystemVerilog:
The main type used in synthesizable SystemVerilog is the logic type. The logic variable can accept 4 values: 1, 0, x, z. x means unknown value. z means a high-impedance status. It is possible to create a vector like logic of different length, for example:
logic [1:0] data; // 2-х битный вектор
initial begin
	data = 7;
	$display(data);
end
Will display in konsol:3

SystemC:
In SystemC there are types with 4 statuses too. However in practice types with 2 statuses 1 and 0 are generally used. A basic reason — types with 2 statuses are simulated quicker.

After synthesis all types with 2 statuses turn into logic. It can result in distinctions in results of simulation of SystemC (before synthesis) and Verilog (after synthesis). In SystemC not reset register will matter 0, in Verilog — x. Fortunately, the synthesizer issues warning every time when sees the register without reset therefore in practice after reading a log of a synthesizer of problems with discrepancy of results of simulation it is possible to avoid.

Very often in a code on SystemC the built-in types C ++, such as int or char are used. If we need number with the set number of bits, it is possible to use the sc_uint type:
sc_uint<2> data;  // 2-х битная переменная
data = 7;
cout << data;
Will display in konsol:3

How sc_uint is implemented? It is just template class in which all main operators are overloaded.

Modules

Let's review an example of the empty module on SystemVerilog and SystemC
SystemVerilog:
module top (
input clk, rstn,
input [7:0] din,
output logic  [7:0] dout
)

// тело модуля
endmodule

SystemC:
struct top: public  sc_module {
   sc_in<bool>         clk, rstn;
   sc_in<sc_uint<8> >  din;
   sc_out<sc_uint<8> > dout;

   top(const char* name) : sc_module(name) , clk("clk") , rstn("rstn") , din("din"), dout("dout")
   {  }
  
};
Let's sort interesting lines in more detail:
struct top: public  sc_module {
modules in SystemC it is derivative classes from the class sc_module
   sc_in<bool>         clk, rstn;
   sc_in<sc_uint<8> >  din;
   sc_out<sc_uint<8> > dout;
For creation of ports in SystemC the special classes sc_in and sc_out are used.
   top(const char* name) : sc_module(name) , clk("clk") , rstn("rstn") , din("din"), dout("dout")
The lines containing their name are transferred to designers of the module and ports. It is necessary in order that the simulyatsionny kernel could issue convenient for reading a log, for example:
Error: (E109) complete binding failed: port not bound: port 'top.dout' (sc_out)
Ошибка: порт dout модуля top никуда не подключен.
(It is possible when in C ++ normal support of an introspektion objects in SystemC appears will be able to learn the names independently)
For convenience of creation of modules in SystemC several macroes are defined. With their use the similar module looks as follows:
SC_MODULE(top) {

   sc_in<bool>         clk, rstn;
   sc_in<sc_uint<8> >  din;
   sc_out<sc_uint<8> > dout;

SC_CTOR(top) , clk("clk") , rstn("rstn") , din("din"), dout("dout") {}
};

Variables and assignment

SystemVerilog:
It is possible to claim that all variables in synthesizable SystemVerilog-static: they exist since the beginning and until the end of simulation. Also have global scope (though access to signals "through a roof" on a hierarchical name is not allowed in a synthesizable code). One more feature of SystemVerilog is existence of several assignment operators: the blocking and non-blocking assignment in procedural blocks, and also continuous assignment.
The blocking assignment happens or at once, or blocks execution of the current process till the moment when assignment is made.
Example:
logic  a;
initial begin
	a = #42 1;
	$display($time);
end
Will display in konsol:42
since function call of $display will happen only in a timepoint 42 when assignment happens.
Non-blocking assignment postpones assignment for some moment of simulyatsionny time in the future and does not block process execution. If time is not specified obviously, assignment happens on the following delta cycle.
initial begin
	a <= #42 1;
	$display($time);
end
Will display in the console: 0

SystemC:
Variables in C ++ know nothing about a simulyatsionny kernel of SystemC and therefore behave usual for C ++ the programmer in the way. To promodelirovat non-blocking assignment in SystemC the special sc_signal type is used, variables of this type are called further signals:
sc_signal< sc_uint<2> > data;  // сигнал типа sc_uint<2> 
Any assignment of data value will be non-blocking.
Synthesizable SystemC demands that interaction between several processes happened through signals. Similarly, in Verilog good style is use of exclusively non-blocking prisvaivaniye in always_ff procedural blocks. Otherwise we risk to receive indefinite behavior (a race status) when the result of simulation depends on an order of a challenge of processes in one delta to the scraper.
There is no analog of the blocking assignment in SystemC.

Processes (Procedural blocks)

SystemVerilog:
Synthesizable SystemVerilog supports two main types of procedural always_comb and always_ff blocks. In addition to them there is still always_latch, but it is necessary to use registers latches in practice quite seldom.
always_comb is used for the description of combinatory logic
always_comb 
begin
	a = b + c;
end
Process will be performed every time when value b or c changes. The same could be written more obviously, as in classical Verilog:
always@(b or c)
begin
	a = b + c;
end
In addition to the procedural always_comb block for the description of combinational schemes it is possible to use the operator of continuous assignment:
assign a = b + c;
The procedural always_ff block is used for the description of posledovatelnostny logic, i.e. schemes with memory.
always_ff @(posedge clk or negedge arst_n) begin
	if(~rst_n) begin
    	    a <= 0;
	end 
        else begin
    	    a <= a + 1;
	end
end
This example describes the scale-of-two counter with asynchronous reset.

SystemC:
Processes in SystemC are created in the designer of the module. The body of processes is described in member functions of the module. The type of process similar to always the block from Verilog in SystemC is called SC_METHOD.
Let's review the examples of processes similar to the given earlier procedural blocks on SystemVerilog:
Combinatory logic:
SC_CTOR(top) {
	SC_METHOD(comb_method);    // макрос для создания процесса типа SC_METHOD
	sensitive << b << c;   // список чуствительности  (аналог @(a or b) )
}

void comb_method() { a = b + c;  }        // тело процесса описывается в функции-члене 
Posledovatelnostny logic:
SC_CTOR(top) {
	SC_METHOD(seq_method);  // макрос для создания процесса типа SC_METHOD
	sensitive << clk.pos() << arst_n.neg();  // список чуствительности ( @(posedge clk or negedge arst_n)  )
}

void seq_method() {  // тело процесса описывается в функции-члене 
if (!arst_n) 
    a = 0;  
 else
    a = a + 1; 
}
There is no analog of continuous assignment in SystemC. As well as there is no opportunity to specify wildcard in the list of sensitivity (always @* in Verilog). Even the strong sample magic of C ++ does not allow to implement it means of metaprogramming.

Parametrization

Modules on SystemVerilog can be parametrized. For example, it is possible to write parametrizable FIFO which width and depth will be specified during creation of a copy.

In SystemC for creation of parametrizable modules template classes are used. With use of templates and inheritance of an opportunity for parametrization in SystemC become almost boundless.

Intermediate results

SystemC allows to describe the equipment at the level of RTL in style very close to simple Verilog. The code on Verilog will be more graceful and more compact, but in general all functionality can be repeated. Let's review a full-fledged example: we implement on Verilog and SystemC a shift register with a consecutive input and an output (serial-in/serial-out) and asynchronous reset:
Code on Verilog:
module shifreg (
     input clk, sin, reset,
     output sout
); 

reg [7:0] tmp; 
 
always @(posedge clk or posedge reset)    begin 
    if (reset) 
        tmp <= 0; 
    else 
        tmp <= {tmp[6:0], sin}; 
end

assign sout = tmp[7]; 

endmodule

Code on SystemC
// Для сигналов и портов используется инициализация в стиле C++11

SC_MODULE(shift_reg) {
    sc_in<bool> clk{"clk"}, sin{"sin"}, reset{"reset"};
    sc_out<bool> sout{"sout"};

    SC_CTOR(shift_reg) {
        SC_METHOD(shift_method);
        sensitive << clk.pos() << reset.pos();
        // т.к. непрерывного присваивания нет, приходится создавать процесс
        SC_METHOD(sout_method);         
        sensitive << tmp; 
     }

private:

    sc_signal <sc_uint<8> > tmp {"tmp"};

    void shift_method() {
	 // для чтения и записи сигналов используются методы read и write
	 // метод write - аналог неблокирующего присваивания в verilog
        if ( reset.read() ) {
            tmp.write(0);
        } else {
            // перегруженный оператор "," (запятая) используется для конкатенации
            tmp.write((tmp.read().range(6,0) , sin.read()));   
        }
    }

    void sout_method() {
        sout = tmp.read()[7];
    }

};

Good SystemC. A possibility of synthesizable SystemC which are not in SystemVerilog


User data types

Synthesizable SystemC completely supports object-oriented programming on C ++. It allows to create convenient data types for work in the data domain. For example, if you are engaged in 3D graphics, then you constantly should deal with 3-dimensional material vectors. For their hardware implementation it will be required to solve several problems.
First, operations with a floating point as a rule are not supported by a synthesizer. Therefore you should implement them independently, or to use third-party library, for example DesignWare floating point. Both in that and in other case you can create a convenient class for work with a floating point:
class my_float  {
public:
	my_float operator+( const my_float &rval;) const;
	my_float operator-( const my_float &rval; ) const;
	my_float operator*( const my_float &rval; ) const;
	// и другие операции ...
private:
	sc_uint<32> raw_data;  // внутри себя float это простой 32-битный вектор
} 
With use of my_float it is possible to implement a class for work with vectors:
class vector_3d {
public:
	vector_3d operator*( const vector_3d &rval; ) const; // vector product
	vector_3d dot_product (const vector_3d &other;) const; // dot product
 	// и другие операции ...
private:
	my_float x, y, z;
};
Then these user types can be used in synthesizable SystemC.
vector_3d a,b,c;
c = a + b;
Synthesizers of SystemVerilog do not support synthesis of classes, but are able to synthesize structures. Therefore programming on SystemVerilog something reminds programming in the Xi language. On SystemVerilog this problem is usually solved with vectors as follows: you create a separate packet, and in it define structures and functions for work with them:
package Vector3DPkg;
typedef struct {
logic [31:0] x, y, x;
} vector_3d;

function vector_3d add(vector_3d a, b);
add.x = float_add (a.x, b.x);  
add.y = float_add (a.y, b.y);  
//...
endfunction

function vector_3dmul(vector_3d a, b);
//....

endpackage : Vector3DPkg

SC_CTHREADS (clocked threads). Processes with an implicit status

Synthesizable processes in Verilog cannot use expressions for management of time and expectations of events. I.e. the started process has to be performed up to the end and only then transfer control to other process. For example, this process is not synthesized:
always @(posedge clk)
begin
    out <= 1;    
    @(posedge clk); // ожидание события не синтезируется
    out <= 2;
    @(posedge clk); 
    out <= 42;
end
In Verilog we have to specify obviously the register of a status which will define behavior of process on each clock period. The following process will be synthesizable analog of the previous code sample:
logic [1:0] state;  

always @(posedge clk or negedge reset_n)
begin
    if ( ~ reset_n)
	state <= 0;
	out <= 1;
    else 
case (state)
    0: begin
    	state <= 1;
        out <= 1;
    end
   1: begin
	state <= 2;
        out <= 2;
    end
    2: begin
	state <= 0;
        out <= 42;
    end
end
In SystemC the synthesizable processes describing posledovatelnostny logic (the digital automatic machine) can stop on waiting of an event from a clock signal. It allows to describe the automatic machine without the explicit specification of the register of a status. Processes of this kind are created by means of SC_CTHREAD macro. The process stop to the following clock signal is performed by function call of wait (); Example:
SC_CTOR ( top ) {
	// процесс создается в конструкторе
        // clk.pos() означает тактирование по переднему фронту сигнала clk
	SC_CTHREAD(test_cthread,  clk.pos() );
	async_reset_signal_is(reset_n, 0);  // асинхронный сброс по уровню 0
}

void test_cthread () {
      // код до первого вызова wait() называется reset-секцией, выполняется при запуске процесса или при активном сигнале сброса.
      out <= 1;
      wait(); 

     // в отличии от SC_METHOD, SC_CTHREAD не должен завершаться никогда
     // поэтому в теле процесса всегда есть бесконечный цикл
     while (1) { 
           out.write(1);
           wait (); // ожидание переднего фронта на clk

           out.write(2);
           wait (); // ожидание переднего фронта на clk

           out.write(42);
      }
}
At first sight the advantage of existence of such processes is not obvious. Eventually not so difficult obviously to code a variable for a status of the digital automatic machine (the state variable in an example on Verilog).
True power of SC_CTHREAD of processes consists in a possibility of a challenge of functions which can block process, i.e. cause the wait function (). Such function can be performed several clock periods! Analog from the world of Verilog are task'i, they however are not synthesized and used only in tests.
For example:
while (1) {
res = calculate_something(); // несколько тактов занимаемся какими-то вычислениями
spi_send(res); // отправляем результат по SPI, тоже за несколько тактов
}
It is even more advantage of functions which execution sometimes occupies several clock periods, and sometimes occurs instantly, without wait challenge ().
For an example we will consider process which reads data from FIFO, processes them then sends result to memory of the front-side bus (for example, AMBA AXI). Let the 3-dimensional vector considered early will be data, and processing will consist in normalization of this vector. With use of SC_CTHREAD and ready classes for work with FIFO and AXI it is very simple to write such process:
fifo  data_fifo; // экземпляр FIFO
amba_axi bus_master; // реализация мастера шины AMBA AXI

void computational_thread() {
wait();
while (1) {
	vector_3d vec = data_fifo.pop();  // читаем данные из FIFO
	vec.normalize();     	    	    // обрабатываем данные
	bus_master.write( 0xDEADBEEF,  vec); // отправляем результат в память по адресу 0xDEADBEEF
}
Let's assume that normalization of a vector is implemented in the form of the combinational scheme. Then, depending on readiness of FIFO and the bus, execution of one cycle of such process can occupy from one clock period and more. If in FIFO there are data and the bus is not occupied, then normalization of one vector will happen for clock period. If FIFO empty, then process is blocked on function of reading from FIFO data_fifo.pop until receipt of new data. If the bus is occupied, then process will be blocked on the bus_master.write function till the moment when the bus is released.

The experienced developer for certain had a question how we do normalization of a vector for clock period? At what frequency our module works? Really, the chain of multiplication, two additions, the square root and division it is too much for one combinational scheme. Especially as it is about operations with a floating point. In case of synchronous circuit engineering this combinational chain for certain will become a bottleneck, limiting the maximum clock frequency of work of all scheme.
Development of the digital equipment on C ++/SystemC eyes of SystemVerilog of the programmer
Depending on requirements to the flow capacity of our normalizer the problem can be solved in several ways:
  • If we do not hurry anywhere, then it is possible to save on resources and to implement normalization in the form of FSMD with one multiplier, the adder, a divider and the module of root squaring. In this case we will spend 6 clock periods for calculation of length of a vector and 3 more clock periods for calculation of value of each of result elements, in the sum — 9 clock periods on one vector.
    Development of the digital equipment on C ++/SystemC eyes of SystemVerilog of the programmer
  • If we strongly hurry, and it is not a pity for resources, the original combinational scheme can be turned into the pipeline. In this case in dive (when in FIFO constantly there are data) we will receive the same 1 clock period on a vector, but already at a bigger clock frequency.
    Development of the digital equipment on C ++/SystemC eyes of SystemVerilog of the programmer
  • Any are also possible intermediate between the first and second options. For example, if the logician expensive and registers cheap, then in the first considered option of microarchitecture it is possible to begin processing of the following vector without waiting for completion previous, in process of release of resources. After calculation of three squares of elements of the first vector, the multiplier is released and it is possible to begin processing of the following vector. Such implementation is called the pipeline with an initialization interval of 3 clock periods. I.e. each three clock periods the pipeline will take away a new vector from FIFO.

Unfortunately, implementation of any of the proposed solutions manually will demand a lot of time and considerably will complicate ours 3rd the lower case source code. For example, in case of pipeline implementation it is necessary to create on process on each of pipeline stages. Fortunately, when using SystemC we need to do nothing by hands — it is possible just to use high-level synthesis!

High-level synthesis.


High-level synthesis is a process of transformation of the algorithmic code written on a high-level programming language to the digital equipment it implementing. On an input of HLS of a packet move:
  • Source code. Sometimes it is called by untimed code since it does not contain constructions for a stop of process, such as the wait function
  • Timing constraints. Temporary restrictions. Set the list of clock signals and their period, and also delays on external ports
  • Specification of microarchitecture. As microarchitecture we can select any of the options considered earlier
In our example we want to subject to high-level synthesis function of normalization of a vector:
void vector_3d::normalize() {
	my_float magnitude = sqrt( x*x + y*y + z*z );
	x = x / magnitude;
	y = y / magnitude;
	z = z / magnitude;
}
As microarchitecture it is possible to select for example the pipeline with an initialization interval of 1 clock period and a delay (latency) of 4 clock periods, and clock frequency to set in 500 MHz. Using technology library HLS the packet will define propagation delay of a signal through each arithmetic element and will optimum place them on pipeline stages. If necessary, execution of one operation can be broken into several stages: for example division is rather difficult operation which execution can not get into one clock period. Therefore it is quite possible that the sintezetor will break a divider between the 3rd and 4th pipeline stage.
Development of the digital equipment on C ++/SystemC eyes of SystemVerilog of the programmer
The analysis of the project in HLS a packet from Cadence

Experienced users of means of a logical synthesis know that some of them (for example Deisgn Compiler) possess similar function which is called a retayming (retiming). In comparison with a retayming of HLS has several advantages:
  • It is not required by hands to specify registers, logic of a stop of the pipeline.
  • HLS allows to switch between several microarchitecture without changing the source code.
One more interesting feature of HLS is work with memory. Abstraction of memory in HLS is the normal array. From us only the synthesizer needs to specify library of available memories in technical process. For example, it is possible to remake our example so that the result did not go on the bus AXI, and it was stored directly:
uint32_t write_address;  // 32-битный адрес
vector_3d  memory[1024]; // память 1024x96  , каждый вектор - 96 бит
....
while (1) {
	vector_3d vec = data_fifo.pop();  // читаем данные из FIFO
	vec.normalize(); // обрабатываем данные
	memory [write_address] = vec; // записываем результат в память
	write_address ++;
}
There is also a wish to note that not all support by HLS of means synthesis with SystemC. Use of SystemC is required only where it is necessary to describe signal interfaces (for example AMBA or UART). On FPGA platforms bus interfaces are usually standardized therefore their use in a HLS code can be implicit. For example, Vivado HLS from Xilinx is oriented first of all to synthesis from pure C/C ++. Within Xilinx platform SoC the standard is the AMBA AXI interface therefore it is supposed that your these functions on AXI, or by means of simple handshake of the protocol will send and receive. Everything that from you it is required — to describe an algorithmic code. Of course such approach has also shortcomings: during creation of difficult projects you can quite come to pasting of a set of HLS modules in a code on Verilog or the graphics editor of schemes. For these purposes Xilinx have one more product — Vivado IP Integrator.
Development of the digital equipment on C ++/SystemC eyes of SystemVerilog of the programmer
The HLS connection of the block with the ARM processor through AMBA AXI in Vivado IP Integrator

Conclusion


As the conclusion I want to try to answer a question which is often asked by RTL developers having seen new Toole: And what with quality of result? How timings, the area, energy consumption of the schemes described on SystemC and synthesized by means of HLS in comparison with RTL described on SystemVerilog will differ?

Actually in any way. In total in your hands: SystemC and HLS do not deprive of you an opportunity to zatyunit everything to within a gate there where it is required. And at the same time HLS does not exempt you from need to understand fundamentals of digital circuit engineering. HLS it not the magic means turning C ++ the programmer into the bureaucrat, this means allowing to automate routine work, facilitating process of writing and support of a synthesizable code.

In this article I did not concern a question of verification in any way. Verification always occupies the most part of time of development and SystemC is what to offer in this field. Well written SystemC is stimulated quicker than RTL since the part of a code is written to "untimed style", and signal interfaces can be replaced with challenges of functions (Transaction-level modeling). The SCV library (SystemC Verification Library) allows to randomize test a vector, also on the way SystemC the UVM version. And since SystemC is C ++, parts of the source code can be pereispolzovat between a synthesizable code, referensny model, a virtual prototype and the driver of an operating system. But the story about all this is worthy separate article.

This article is a translation of the original post at habrahabr.ru/post/274137/
If you have any questions regarding the material covered in the article above, please, contact the original author of the post.
If you have any complaints about this article or you want this article to be deleted, please, drop an email here: sysmagazine.com@gmail.com.

We believe that the knowledge, which is available at the most popular Russian IT blog habrahabr.ru, should be accessed by everyone, even though it is poorly translated.
Shared knowledge makes the world better.
Best wishes.

comments powered by Disqus