480 likes | 651 Views
A Path to Higher-Level Design. CynApps Cynthesis Applications for Higher-Level Design. Levels of Abstraction. Algorithm C/C++. Design Gap. RTL Verilog, VHDL. RTL synthesis. netlist Verilog, Edif. layout. Physical GDS-II. Cost of disconnect. Tools
E N D
A Path to Higher-Level Design CynApps Cynthesis Applications for Higher-Level Design
Levels of Abstraction Algorithm C/C++ Design Gap RTL Verilog, VHDL RTL synthesis netlist Verilog, Edif layout Physical GDS-II
Cost of disconnect • Tools • Separate suite of tools in both environments • Knowledge • Lose information when starting over in HDL • Design Time • Starting from scratch • Separate testbenches/verification efforts
Bridging the Gap with C++ • System design is done in C/C++ • Hardware design will be done in C/C++ • Over 50% of today’s designs begin with C/C++ • The end of “tossing specs over the wall” • Refine architectural models in C/C++ into cycle-accurate executable specifications • Automatically Cynthesize C++ to HDL • C++ enables higher levels of abstraction • Object-orientation matches hardware structure
Define a New Level • Extension • A collection of procedures that express the operations of the new level in terms of those of the previous level • e.g. object-oriented classes • Translation • A transformation from one linguistic level to another • e.g. Design Compiler • Interpretation • Direct execution of the new level by the lower level • e.g. embedded processor - Jack Dennis 1973
Abstraction & Refinement C/C++ ATM Design producers consumers switch (packet sources) (packet destinations) Extension connection receiver transmitter table channel fifo packet comparators logic macros registers muxes RTL translation Netlist translation GDS-II
Unified Design Environment • System/Algorithm Modelling • Software Design • Hardware Design C++ Based Hardware Design Allows... ...to be in the Same Language
C++/Cynlib is Best • A better foundation • Closer to hardware • More flexible, fewer restrictions • Open source business model • CynApps sells support • Library is really open • Cyn++ provides Verilog/VHDL familiarity • Supporting tools are available
CynApps Tool Suite Overview
Introducing the CynApps Suite… Design Creation • Cynlib Open Source C++ Library for System Design • Cyn++ Makes C/C++ easy to use for HDL Designers Verification • Cyntax Detects coding errors prior to simulation • Cyngdb FSF GDB source debugger with Cynlib extensions • Cynlib Free, Fast, Cycle-accurate system simulator • Cynchronizer Converts synthesizable HDL into C++Cynlib Synthesis • Cynthesizer Compiles C++Cynlib into synthesizable RTL
CynApps Tool Flow Cynlib .cc files Cyn++ .cyn files HDL files Design Input Cyn++ Cynchro Cyntax C/C++ Modules Cynthesizer GCC Compiler Output Files Synthesizable RTL .v File Simulation .out File
Cynlib Open Source Library • Cynlib provides the missing HW features • HW concurrency • bit-accurate data types • Cynlib is a C++ class library • the standard way to extend C++ • well-defined, supported, open-source
Cynlib simulation • Cynlib has a built-in simulation kernel • fast cycle-accurate simulation • both event queue & thread implementation • VCD generation capability • Cynlib is free!
Verification with Cynlib • Unified design & test environment • HW & SW models in one language facilitates system simulation • Mixed abstraction levels for HW blocks maximizes simulation performance • Implement test environment in C/C++ • Cycle-accurate executable specification
Cyn++ • Increases familiarity for HDL designers • HDL-like C++ macros using Cynlib • Module/EndModule, Entity/EndEntity • Initial/EndInitial • Always/EndAlways, Process/EndProcess • Posedge(), Negedge(), Changed() • Rising_Edge(), Falling_Edge(), Event() • Verilog Instantiation Syntax
Cyntax • Detects common errors • Semantic errors • Constructs leading to race conditions • Code omissions • Functional errors
Cynchronizer • Synthesizable Verilog => C++Cynlib • Enables a single design environment • Converts legacy code to C++Cynlib • More efficient than co-simulation • Fast system level simulations • Facilitates HW/SW co-verification
Cynthesizer v1.0 • Automatically compiles C++Cynlib into Verilog RTL • Accepts fully elaborated bit accurate & cycle accurate model • Generates synthesizable Verilog compatible with Synopsys’ DC or Cadence’s BuildGates • Performs standard compiler optimizations • Loop Unrolling • Constant Folding and propagation • Dead code elimination • Common sub-expression elimination
Labs • Lab 1 – Up-down counter in Cyn++ • Easy HDL-like design creation • Free, fast, cycle-accurate simulation • Access to standard debug file formats • Lab 2 – Up-down counter in Cynlib • Brief introduction to C++ and cynlib concepts • Naming conventions, access specifiers etc
Cyn++ Equivalents Verilog module (…) … endmodule always@( … ) begin … end initial begin … end @(posedge(…) or …) @(negedge(…) or …) @(a or …) input [x-1:0] sig1; output [x-1:0] sig1; reg [x-1:0] sig1; reg [x-1:0] sig1; f <= a; Verilog Cyn++ Module (…) … EndModule Always ( … ) … EndAlways Initial … EndInitial (Posegde(…) || …) (Negedge(…) || …) (Changed(a) || …) In<x> sig1; Out<x> sig1; Uint<x> sig1; f <<= a; VHDL Cyn++ Entity (…) … EndEntity Process ( … ) … EndProcess (Rising_Edge(…) || …) (Falling_Edge(…) || …) (Event(a) || …) In<x> sig1; Out<x> sig1; Uint<x> sig1; f <<= a;
Small Example in Cyn++ a f b #include "cynlib.h" Moduleand2 ( In<1>a, In<1> b, Out<1>f ) Always ( Changed(a) || Changed(b) ) f = a && b; EndAlways EndModule
Components of Cynlib • Class (Module) Declaration • Defines how objects are structured at runtime • Inherits CynModule class from Cynlib • Can hide implementation: public and private • Declares ports and local variables • Declares behavior methods • Declares constructor • Behavior Method Definitions • Constructor Definitions • Run once when class is created at runtime • Behavior methods registered with execute_on • Same name as class
Small Example in Cynlib a f b • // AND method definition • void and2 :: comb_and() { • f = a && b; • } • // Constructor definition • and2 :: and2( • char *name, • In<1>p_a, • In<1>p_b, • Out<1>p_f • ) : CynModule(name), • a(p_a, “a”), • b(p_b, “b”), • f(p_f, “f”) • { • execute_on(&comb_and, ”=", &a, &b, 0); • epilog(); • } • #include "cynlib.h" • // “and2” class declaration • class and2 : public CynModule { • public: • // Module ports • In<1>a, b; • Out<1>f; • // Combinational AND method • void comb_and(); • // Constructor declaration • and2 ( • char *name, • In<1>p_a, • In<1>p_b, • Out<1>p_f • ); • };
Class Declaration • Cynlib designs are defined as classes using the following syntax: class and2 : public CynModule { … }; • CynModule has all the functions needed to give your class complete hardware behavior. Name of class Means class will inherit all public variables, methods and constructors of a Cynlib class object called CynModule Body of class declaration goes between braces
Port Declaration • Class ports can be inputs or outputs using In<x> or Out<x> syntax: • class and2 : public CynModule { • public: • In<1> a, b; • Out<1> f; • … • }; • You can declare local signals as unsigned or signed integers using Uint<x> or Int<x> syntax: • Uint<1> local_sig1; • Int<1> local_sig2; Make your ports public so they can be used at a higher level Comma-separated list of port names ending with a semicolon Specify bit width of port between <> brackets
Constructor Declaration • All classes must have a constructor • class and2 : public CynModule { • public: • ... • and2 ( • char *name, • In<1> a, • In<1> b, • Out<1> f • ); • }; • Constructor will be called once — when the class is instantiated. • Methods are registered for simulation later in the constructor definition using execute_on. Constructor must have same name as class String pointer is where class instance name is passed Constructor ports will correspond to class ports (names do not have to be the same)
Method Definition • Method definitions contain behavior or functionality that will occur on a clock edge or change of variable levels class and2 : public CynModule { … }; void and2 :: comb_and() { f = a && b; } Syntax is “class_name :: method_name” Method functionality
Constructor Definition • Constructor definitions map class ports and inherit the base CynModule constructor class and2 : public CynModule { … }; and2 :: and2 ( • char *name, • In<1> a, • In<1> b, • Out<1> f • ) : CynModule(name), • a(a, “a”), • b(b, “b”), • f(f, “f”) • { • … • } Syntax is “class_name :: constructor_name” Constructor inherits the constructor of CynModule Port constructors passed to CynModule Name to appear in VCD file Class port name Constructor port name
Method Registration • Methods can be registered with the Cynlib simulator in the body of the constructor and2 :: and2 ( • char *name, • In<1> a, • In<1> b, • Out<1> f • ) : CynModule(name), • a(a, “a”), • b(b, “b”), • f(f, “f”) • { • execute_on(&and2::comb_and, “=“, &a, &b, 0); • epilog(); • } Edge sensitivity operator. Possible values are: “=“ Method is triggered whenever a signal in the sensitivity list changes value “+” Method is triggered on the positive edge on the sensitive signal “-” Method is triggered on the negative edge of the sensitive signal List of ports method is sensitive to Name of method Multiple port list is null terminated epilog designates the end of a constructor
execute_on Sample Usage • Synchronously trigger a method called edge on the rising edge of signal clk: • execute_on(&edge, “+“, &clk); • Asynchronously trigger async on signals x and y: • execute_on(&async, “=“, &x, &y, 0); • Asynchronously trigger func on signal a: • execute_on(&func, “=“, &a); • Trigger cnt on rising edge of clk or falling edge of reset_n: execute_on(&cnt, “+“, &clk); execute_on(&cnt, “-”, &reset_n); No null termination needed for only one sensitive signal
Deferred Assignments • In Verilog, non-blocking assignments ( <= ) are those scheduled to take place at the end of the current simulation cycle — the equivalent to this in Cynlib is a deferred assignment • To eliminate confusion with the C less-than-or-equal-to operator ( <= ), Cynlib overloads the seldom used left-shift-assignment operator ( <<= ) to designate a deferred signal assignment Verilog VHDL Cynlib y <= 1’b1; y <= ‘1’; y <<= 1;
SWITCH Statement • Analogous to CASE statement — each branch needs a break; statement to prevent fall through switch(x) { case(0): y <<= 1; break; case(1): y <<= 2; break; case(2): y <<= 3; break; … default: y <<= 0; break; } Without break; compiler will examine next branch even if current branch matches selection expression
Vector Manipulation • Bit and Range Selection a(5) Selects bit 5 of vector a b(5,3)Selects bits 5 through 3 of vector b c(3,0) = d(7,4);Assigns bits 7 through 4 of vector d to bits 3 through 0 of vector c • Concatenation (b(3,0), c(2), d(4))Builds a 6-bit concatentation (m(2,0), e) <<= f(3,0);Assigns bits 3 through 0 of vector f to a concatenation of vector m and variable e
The cyn Command • cyn script compiles Cynlib/Cyn++ files into a simulation executable cyn [options] {source files} -lint Do not compile. Instead, run Cyntax on the input files -cynth Do not compile. Instead, run Cynthesizer on the input files -verbose Print the commands being invoked by this script to stdout -I*, -D*, -U* Include, Define and Undefine options passed to Cyn++ preprocessor and C++ compiler -save_temp Save the temporary directory after preprocessing -help Print this message % cyn -o fifo -I/myobjs fifo.cyn top_fifo.cc Cynlib/Cyn++ files to be compiled Other switches go right through to gcc Generates an executable called fifo Add a directory named myobjs to the scope
Example: and2 Testbench #include "cynlib.h” #include ”and2.cc” void main() { // Local signals to connect // UUT and stimulus signals Uint<1>a, b, f; struct stim { int a, b; } s[] = { // a b { 0, 0 }, // s(0) vector { 0, 1 }, // s(1) vector { 1, 0 }, // s(2) vector { 1, 1 } // s(3) vector }; // Instantiate and2 as instance U1 and2u1 ( "u1", a, b, f ); CynVcdFile("and2.vcd"); CynVcdAdd(&u1, 0); CynVcdOn(); f Test Bench a b printf(” a b f\n"); printf("--------\n"); for ( int i = 0; i < 4; i++ ) { a = s[i].a; b = s[i].b; CynTick(); printf("%2d %2d %2d\n", (int)a, (int)b, (int)f ); } } }
main( ) • Every C/C++ program needs a method called main. main is the highest level of program execution, where the order of events is defined and where all major modules are instaniated. This makes it very useful in Cynlib testbench description • void main() { • … • }
Clocks • Cynlib has a base clock class called CynClock0 • Declare a clock signal using the CynClock data type CynClock clk(0,5,6,4); CynClock0 is a continously running clock — HI for one time unit, LO for one time unit CynClock0 0 2 4 6 8 10 12 14 Initial value (0 or 1) Time HI Time LO Delay clk 0 5 11 15
CynClock Pulses • CynClock has a two-argument constructor for pulse creation • Useful for reset signals CynClock reset_n(0,14); Asserted pulse value is “0” Delay reset_n 0 14 15 Pulse lasts one time unit
Creating Test Vectors • One C/C++ construct available for creating vectors is a structure. Structures let you define a number of stimulus values for any collection of design inputs • Use the struct keyword to define structures • struct stim { • int up, down; • } s[] = { • //up down • { 0, 0 }, • { 0, 1 }, • { 1, 0 }, • { 1, 1 } • }; Name of structure Structure fields You can refer later to specific field values by indexing s s[0].up = 0 s[1].down = 1 Variable s of type stim Sets of values for structure fields
Instantiation • Instantiating a class is very similar to module instantiation in Verilog • First argument passes the instance name • counter U1 (“U1”, clk, reset, up, down, data, cnt); Class name Character string passes the instance name to the CynModule constructor (remember the “char *name” pointer argument) Local signal names map to class ports Instance name
VCD Files • Cynlib provides several classes for VCD file creation • CynVcdFile lets you give your VCD file a name • CynVcdFile(“updown.vcd”); • CynVcdAdd specifies how deep in an instance to include signals • CynVcdAdd(&u1, 0); Level indicator 0 Include signals from current instance level only in VCD file 1 Include signals from current instance and one level down … -1 Include signals from ALL instance levels Reference to instance name
VCD Files • CynVcdAdd can also be used to include specific signals • CynVcdAdd(&sig1, &sig2, 0); • CynVcdRemove removes specific signals from VCD file inclusion • CynVcdRemove(&sig1, &sig2, 0); • CynVcdOn turns on VCD file dumping • CynVcdOn(); • Conversely, CynVcdOff turns off VCD file dumping CynVcdOff();
Advancing Time: CynTick() • CynTick() advances simulation time one cycle of CynClock0 • for ( int i = 0; i < 256; i++ ) { • for ( int j = 0; j < 4; j++ ) { • ... • CynTick(); • } • } • CynTick() has another constructor allowing a clock signal as an argument • for ( int i = 0; i < 256; i++ ) { • for ( int j = 0; j < 4; j++ ) { • ... • CynTick(&sys_clk); • } • } Simulation time will move forward one CynClock0 cycle — 2 time units Simulation time will move forward one cycle of clock signal sys_clk
Advancing Time: CynRun() • CynRun() advances simulation time a fixed number of CynClock0 cycles • for ( int i = 0; i < 256; i++ ) { • for ( int j = 0; j < 4; j++ ) { • ... • CynRun(5); • } • } • CynRun() has another constructor allowing an integer and a clock signal as arguments • for ( int i = 0; i < 256; i++ ) { • for ( int j = 0; j < 4; j++ ) { • ... • CynRun(10, &sys_clk); • } • } Simulation time will move forward five CynClock0 cycles — 10 time units Simulation time will move forward ten cycles of clock signal sys_clk
Lab 1 • 8-bit up-down counter with asynchronous reset • Create a class called updown with ports as shown in the diagram • Define an 8-bit local variable called cnt_nxt • Define a combinational method called next that assigns values to cnt_nxt • Define a method called edge to synchronously assign cnt_nxt to cnt • Asynchronously reset cnt when rstn is asserted LO 8 data cnt_nxt 8 next 8 up cnt edge down clk rstn up down cnt_nxt 0 0 cnt 0 1 cnt - 5 1 0 cnt + 3 1 1 data
Running Lab 1 • Change to the directory called lab1 and list the directory contents • % cd lab1 • % ls • updown.cc top.cc • Open the template file called updown.cc with your favorite text editor and create the design described on the previous page • % vi updown.cc • Run the cyn compiler script on the top level testbench file top.cc • % cyn top.cc • Run the a.out simulation executable that is created. View the results printed to the screen, then open the generated VCD file with your favorite waveform viewer % a.out % wave updown.vcd & top.cc is the testbench that instantiates the updown class Command to run GTKWave waveform viewer
Wrap-up • Unified design & test environment • HW & SW models in one language facilitates system simulation • Complete solution • modelling (Cynlib, Cyn++) • debugging (Cyntax, Cyngdb) • path to gate (Cynthesizer) • legacy code support (Cynchronizer)