Synthesis »

Synthesis


edit SideBar

Synthesizing Your Design

1.  Overview

In this class we will do some very simple synthesis of your designs. The primary goal of this exercise is to get a sense for the actual hardware your Verilog is creating. Synthesizing your design will allow us to see:

  1. The actual gates
  2. Area
  3. Delay
  4. The actual longest path in your design :)

There is a lot more to synthesis optimizations than what we will cover in this class.

We will be using Synopsys DC Compiler and a 45nm gate library provided by FreePDK. A lot of the details will be abstracted away and you will be using a simple script called synth.pl which will do most of the work for you.

To synthesize your design several pieces of information are required:

  • A gate library that says what types of gates are available at your disposal. We will use the FREEPDK library installed at: /u/k/a/karu/courses/cs552/cad/Synopsys_Libraries/libs
  • List of verilog files and the name of each module. Now you will begin to appreciate why the verilog file name and the module name have to be identical
  • The top-most module name
  • Synthesis constraints (how much area, what frequency, arrival times for each primary input etc.)

You will *IGNORE* the constraints in the red box above for this class and instead use the defaults we provide. All your designs will be synthesized to meet a 1 Ghz clock frequency (1ns clock-period). Area goal is to minimum area.

We will perform synthesis in the following three steps:

  1. Write Verilog, verify
  2. Check Verilog is synthesizable
  3. Synthesize the Verilog module

Before we can begin, we should setup environment variables and such just like what we did for ModelSim.

2.  Environment Setup

Add the following lines to your ~/.bashrc:

source /s/synopsys-2020_06_08/bin/synopsys_env.sh

Download the file .synopsys_dc.setup and copy it into your home directory.

The file is called

.synopsys_dc.setup

Note a dot is the first character in the filename indicating this is a UNIX hidden file. Many browsers may sometimes delete this dot. So be careful. Your file copied in your home directory MUST have the dot as the first character.

  • You MUST not modify this file
  • You MUST not change its name
  • You MUST copy the file in your home directory

IMPORTANT: Log out of the shell, then log back in, or explicitly source ~/.bashrc to make sure the modifications to your .bashrc take effect.

3.  The synth.pl Script

The synth.pl script is a wrapper that will allow us to perform synthesis. It requires the following information and has the following usage:

3.1  Usage

Usage: synth.pl [options]

    Options:

     [-cmd <check|synth>] What to do:
                              check = just check if everything is ok
                              synth = perform synthesis (will take longer)
     [-type <other|proc>] What is the design:
                              proc = This is the processor.
                                     Use when synthesizing the full processor
                                     then -f, -d, -e, -m, -wb must be specified
                              other = Some other design (use for hw, caches etc.)
     [-top <module name>] Name of the top-most module in your design. This
                          must be module instantiated inside the _hier level.
                          **You cannot specify the _hier module here*
     [-opt <yes|no> ]     Optimize the design yes or no. [Default = no]
     [-list <filename> ]  <filename> has a list of verilog files which make up
                          your design.
     [-file <f0,f1,f2,..> ] Provide a comma-separated list of verilog file names.

     Only one of -list or -file can be used


     [-f <fetch module]   Name of your fetch module,
                          required if type=proc, else ignored

     [-d <fetch module]   Name of your decode module,
                          required if type=proc, else ignored
     [-e <fetch module]   Name of your execute module,
                          required if type=proc, else ignored
     [-m <fetch module]   Name of your memory module,
                          required if type=proc, else ignored
     [-wb <fetch module]  Name of your write-back module,
                          required if type=proc, else ignored

3.2  Outputs

Output:

    If cmd=check

       synth/hiearchy.txt   Hieararchy of your design
       synth/<top>.syn.v    Gate-level version of your design
                            All modules will be in ONE single
                            verilog file. Replace top with the
                            top module name you specified
                            as input.

    If cmd=synth
       The above two files, PLU

       synth/report_reference.txt  Detailed usage of each module
       synth/area_report.txt       Detailed area report
       synth/timing_report.txt     Detailed timing report

3.3  Example

Some example usage:

Checking the ALU from hw2/hw2_2:

prompt> synth.pl --list=list.txt --type=other --cmd=check --top=alu

Synthesizing the ALU from hw2/hw2_2:

prompt> synth.pl --list=list.txt --type=other --cmd=synth --top=alu

Checking the full processor for demo1 or demo2:

prompt> synth.pl --list=list.txt --type=proc --cmd=check --top=proc -f=fetch -d=decode -e=execute -m=memory -wb=write_back

4.  Step-by-step Tutorial

4.1  Synthesizing alu from hw2/hw2_2

Step 1 Setup environment.
Step 2 Go to the correct directory where you have all the verilog files.
prompt> cd hw2/hw2_2
Step 3 Make a list of verilog files that are part of the design. Create a text file called list.txt in hw2/hw2_2. Its content: one verilog filename per line.
  • NO testbenches should be included in this list
  • NO _hier files which are wrappers should be in this list
  • clkrst.v should NOT be in the list, since we don't want to synthesize the clock generator

An example list.txt looks like:

16_4mux.v
16_8mux.v
16CLA.v
24_12mux.v
28_14mux.v
32_16mux.v
32_8mux.v
4_1mux.v
4CLA.v
8_2mux.v
alu.v
bshifter.v
bshift.v

where alu is your top-level module.

Step 4

a) First "check" the design is synthesizable:

prompt> synth.pl --list=list.txt --type=other --cmd=check --top=alu

b) Look at the output on the screen or synth.log.

  • If you see any "Error"s, you should definitely fix those;
  • Most of the "Warning"s are fine - you only need to take care of the two listed on the Common synthesis errors page.
  • Refer to the Common synthesis errors page for common questions.

c) Checking done.

Step 5 Synthesis.
prompt> synth.pl --list=list.txt --type=other --cmd=synth --top=alu

Wait for some time, it may take a few minutes.....

Go look in the synth/ folder created at current path. You will find a total area report, a cell report, a reference report, and a timing report.

Step 6 Checking synthesis output.

Make sure that:

  • NO cells in the synth/cell_report.txt has zero area in it. If you see a zero area for a module name, then that means that module had some kind of Verilog coding error and did NOT get synthesized. You must fix this problem. Look in synth.log, search for that module name, and look for warnings/errors.
  • NO cells in the synth/reference_report.txt has zero total area. If it does, then some sub modules underneath have failed to synthesize. Check cell_report.txt.

4.2  Synthesizing Full Processor

We will do this slightly differently. For all other problems, we allowed the synthesis tool to completely "flatten" the design. If we flatten the full processor, then reasoning about it and applying optimizations will be hard. So we will break it up into some large pieces and preserve the hierarchy at those levels. Specifically, we will preserve fetch, decode, execute, memory, and writeback modules of your processors. Within each of those modules, we will let synthesis completely flatten the design. This is why, when you specify the --type=proc option, you must specify the fetch, decode, execute, memory, and writeback module names.

Step 1 Setup environment.
Step 2 Go to the correct directory where you have all the Verilog files.
prompt> cd demo1
Step 3 Create a list file list.txt with one Verilog filename per line.

For the project, the memory2c.v module you provided cannot be synthesized because it contains simulation logic to test your processor on a simulated memory. You might have noticed that we provided a memory2c.syn.v file as well. It is basically a dummy memory2c module which removes all the unsynthesizable code.

Hence, in synthesis, we list memory2c.syn.v instead of memory2c.v in list.txt.

The following is an example list.txt for a project demo:

alu.v
claadder16.v
claadder4.v
compless16.v
compless4.v
ctrl.v
decode.v
dff.v
exec.v
extender16.v
fetch.v
fulladder1.v
memory.v
memory2c.syn.v
proc.v
regfile.v
register.v
rf_bypass.v
rotaterl16.v
rotaterr16.v
shifterl16.v
shifterr16.v
writeback.v
Step 4

a) First "check" the design:

prompt> synth.pl --list=list.txt --type=proc --cmd=check --top=proc --f=fetch --d=decode --e=exec --m=memory --wb=writeback

b) Look at the output on the screen or synth.log.

  • If you see any "Error"s, you should definitely fix those;
  • Most of the "Warning"s are fine - you only need to take care of the two listed on the Common synthesis errors page.
  • Refer to the Common synthesis errors page for common questions.

c) Checking done.

Step 5 Synthesis.
prompt> synth.pl --list=list.txt --type=proc --cmd=synth --top=proc --f=fetch --d=decode --e=exec --m=memory --wb=writeback

Wait for some time, it may take a few minutes.....

Go look in the synth/ folder created at current path. You will find a total area report, a cell report, a reference report, and a timing report.

Step 6 Checking synthesis output.

Make sure that:

  • NO cells in the synth/cell_report.txt has zero area in it. If you see a zero area for a module name, then that means that module had some kind of Verilog coding error and did NOT get synthesized. You must fix this problem. Look in synth.log, search for that module name, and look for warnings/errors.
  • NO cells in the synth/reference_report.txt has zero total area. If it does, then some sub modules underneath have failed to synthesize. Check cell_report.txt.

4.3  Synthesizing Standalone Cache

Just like in the processor demo, some basic memory modules we provided for the cache demo are not synthesizable because they contain simulation logic for testing your cache design. You may have noticed that we provided the following dummy module files:

  • final_memory.syn.v
  • memc.syn.v
  • memv.syn.v

For these three modules, list the above filename in list.txt instead of its original .v.

Also, do not include:

  • mem_system_ref.v

, as it is a reference model only invoked by the testbench.

The rest of the steps to synthesize our standalone cache is just the same as synthesizing a normal homework assignment module. The top-level module of your standalone cache system should be mem_system.

5.  Interpreting the Output Files (under synth/)

5.1  hierarchy.txt

This file describes your design hierarchy in text-format. It shows the list of top-level modules. For each module it shows list of sub-modules. And for each sub-module, the sub-sub-module, and so on. An example is shown below:

alu
    GTECH_AND2                                   gtech
    GTECH_NOT                                    gtech
    GTECH_OR2                                    gtech
    GTECH_XOR2                                   gtech
    barrelshifter
        bit1_shifter
            mux4_1
                mux2_1
                    GTECH_BUF                    gtech
                    GTECH_NOT                    gtech
        bit2_shifter
            mux4_1
                ...
        bit4_shifter
            mux4_1
                ...
        bit8_shifter
            mux4_1

5.2  synth.log

This is the log of all synthesis commands. Specifically look in this file for warnings and errors if your design does not synthesize.

5.3  area_report.txt

This file includes a report on the area occupied by your design. The file is mostly self-explanatory. The cell area is expressed in square microns. An example file is shown below:

Library(s) Used:

    gscl45nm (File: /scratch/users/karu/courses/cs755/tools/Synopsys_Libraries/libs/gscl45nm.db)

Number of ports:                3
Number of nets:               660
Number of cells:               15
Number of references:          12

Combinational area:       17600.626691
Noncombinational area:    2433.320446
Net Interconnect area:      undefined  (No wire load specified)

Total cell area:          20033.947137
Total area:                 undefined

Whatever you see on the line: "Total cell area:" is the actual cell area.

5.4  timing_report.txt

This file will contain the list of the top-20 longest/slowest paths in your design. For each such path you will see the start and a list of gates that make up the path. Recall that, all your designs will be synthesized to meet a 1 Ghz clock frequency (1ns clock-period). For example:

  Startpoint: dx_reg/dff0[106]/dff0/state_reg
              (rising edge-triggered flip-flop clocked by clk)
  Endpoint: xm_reg/dff0[62]/dff0/state_reg
            (rising edge-triggered flip-flop clocked by clk)
  Path Group: clk
  Path Type: max

  Point                                                   Incr       Path
  --------------------------------------------------------------------------
  clock clk (rise edge)                                   0.00       0.00
  clock network delay (ideal)                             0.00       0.00
  dx_reg/dff0[106]/dff0/state_reg/CLK (DFFPOSX1)          0.00 #     0.00 r
  dx_reg/dff0[106]/dff0/state_reg/Q (DFFPOSX1)            0.13       0.13 f
  dx_reg/dff0[106]/dff0/q (dff_264)                       0.00       0.13 f
  dx_reg/dff0[106]/q (dff_en_264)                         0.00       0.13 f
  dx_reg/Out<106> (register_N_N114)                       0.00       0.13 f
  ex_stage/reg_rs_dx<2> (Execute)                         0.00       0.13 f
  ex_stage/U225/Y (INVX1)                                 0.02       0.15 r
  ex_stage/U224/Y (NAND2X1)                               0.01       0.16 f
  ex_stage/U227/Y (AND2X2)                                0.04       0.20 f
  ex_stage/U228/Y (INVX1)                                 0.00       0.19 r
  ex_stage/U231/Y (AND2X2)                                0.03       0.22 r
  ex_stage/U242/Y (INVX1)                                 0.02       0.24 f
  ex_stage/U232/Y (NOR2X1)                                0.02       0.26 r
  ex_stage/forward/C47/Z_0 (*SELECT_OP_4.1_4.1_1)         0.00       0.26 r
  ex_stage/U223/Y (OR2X1)                                 0.03       0.29 r
  ex_stage/forward_a_mux/mux0[0]/mux2/C11/Z_0 (*SELECT_OP_2.1_2.1_1)
                                                          0.00       0.29 r
  ex_stage/U538/Y (INVX1)                                 0.01       0.30 f
  ex_stage/U537/Y (NAND2X1)                               0.01       0.31 r
  ex_stage/U448/Y (AND2X2)                                0.04       0.35 r
  ex_stage/U378/Y (XOR2X1)                                0.03       0.38 f
  ex_stage/U318/Y (INVX1)                                 0.00       0.39 r
  ex_stage/U434/Y (AND2X2)                                0.03       0.42 r
  ex_stage/U435/Y (INVX1)                                 0.02       0.43 f
  ex_stage/U584/Y (OAI21X1)                               0.05       0.49 r
  ex_stage/U601/Y (OAI21X1)                               0.03       0.51 f
  ex_stage/U390/Y (AND2X2)                                0.03       0.55 f
  ex_stage/U442/Y (INVX1)                                 0.00       0.54 r
  ex_stage/U417/Y (AND2X2)                                0.03       0.57 r
  ex_stage/U418/Y (INVX1)                                 0.01       0.59 f
  ex_stage/U276/Y (AND2X2)                                0.04       0.63 f
  ex_stage/U338/Y (XOR2X1)                                0.02       0.65 r
  ex_stage/alu/mux1/mux0[5]/mux0/C11/Z_0 (*SELECT_OP_2.1_2.1_1)
                                                          0.00       0.65 r
  ex_stage/alu/mux1/mux0[5]/mux2/C11/Z_0 (*SELECT_OP_2.1_2.1_1)
                                                          0.00       0.65 r
  ex_stage/alu/mux0/mux0[5]/C11/Z_0 (*SELECT_OP_2.1_2.1_1)
                                                          0.00       0.65 r
  ex_stage/alu/mux10/mux0[5]/C11/Z_0 (*SELECT_OP_2.1_2.1_1)
                                                          0.00       0.65 r
  ex_stage/U252/Y (OR2X2)                                 0.03       0.69 r
  ex_stage/U251/Y (INVX1)                                 0.01       0.70 f
  ex_stage/U250/Y (AND2X2)                                0.03       0.74 f
  ex_stage/U247/Y (AND2X2)                                0.03       0.77 f
  ex_stage/U246/Y (AND2X2)                                0.03       0.80 f
  ex_stage/U10/Y (AND2X2)                                 0.03       0.83 f
  ex_stage/U244/Y (AND2X2)                                0.03       0.87 f
  ex_stage/U257/Y (AND2X2)                                0.03       0.90 f
  ex_stage/U258/Y (AND2X2)                                0.03       0.93 f
  ex_stage/U261/Y (AND2X2)                                0.04       0.97 f
  ex_stage/U265/Y (INVX1)                                 0.00       0.96 r
  ex_stage/U262/Y (NAND2X1)                               0.01       0.97 f
  ex_stage/alu/mux7/C11/Z_0 (*SELECT_OP_2.1_2.1_1)        0.00       0.97 f
  ex_stage/alu/mux6/C11/Z_0 (*SELECT_OP_2.1_2.1_1)        0.00       0.97 f
  ex_stage/alu/mux5/mux0[0]/C11/Z_0 (*SELECT_OP_2.1_2.1_1)
                                                          0.00       0.97 f
  ex_stage/alu/mux4/mux0[0]/C11/Z_0 (*SELECT_OP_2.1_2.1_1)
                                                          0.00       0.97 f
  ex_stage/alu/mux3/mux0[0]/C11/Z_0 (*SELECT_OP_2.1_2.1_1)
                                                          0.00       0.97 f
  ex_stage/ALU_out<0> (Execute)                           0.00       0.97 f
  xm_reg/In<62> (register_N_N92)                          0.00       0.97 f
  xm_reg/dff0[62]/d (dff_en_128)                          0.00       0.97 f
  xm_reg/dff0[62]/U3/Y (INVX1)                            0.00       0.97 r
  xm_reg/dff0[62]/U2/Y (MUX2X1)                           0.02       0.99 f
  xm_reg/dff0[62]/dff0/d (dff_128)                        0.00       0.99 f
  xm_reg/dff0[62]/dff0/U3/Y (AND2X1)                      0.03       1.02 f
  xm_reg/dff0[62]/dff0/state_reg/D (DFFPOSX1)             0.00       1.02 f
  data arrival time                                                  1.02

  clock clk (rise edge)                                   1.00       1.00
  clock network delay (ideal)                             0.00       1.00
  xm_reg/dff0[62]/dff0/state_reg/CLK (DFFPOSX1)           0.00       1.00 r
  library setup time                                     -0.06       0.94
  data required time                                                 0.94
  --------------------------------------------------------------------------
  data required time                                                 0.94
  data arrival time                                                 -1.02
  --------------------------------------------------------------------------
  slack (VIOLATED)                                                  -0.08

In the above example, there are about 40 or 50 gates on that path. Right at the end notice the string slack (VIOLATED). This means the design is consuming 0.08ns longer than it should. You should try optimizing. The names of gates and their prefix give you a hint on which stage of the pipeline this logic belongs to.

5.5  reference_report.txt

This file will show you all the low-level modules that ended up in your design. It will show you how many times each such cell was instantiated. For example:

Reference          Library       Unit Area   Count    Total Area   Attributes
-----------------------------------------------------------------------------

AND2X1             gscl45nm       2.346500       5     11.732500
AND2X2             gscl45nm       2.815800      15     42.236999
BUFX2              gscl45nm       2.346500      15     35.197499
BUFX4              gscl45nm       2.815800       3      8.447400
INVX1              gscl45nm       1.407900      22     30.973799
INVX2              gscl45nm       1.877200       8     15.017600
INVX4              gscl45nm       3.285100       1      3.285100
INVX8              gscl45nm       3.285100       4     13.140400
NOR2X1             gscl45nm       2.346500       1      2.346500
OAI21X1            gscl45nm       2.815800       1      2.815800
OR2X1              gscl45nm       2.346500       1      2.346500
OR2X2              gscl45nm       2.815800      28     78.842399

5.6  cell_report.txt

This file will provide the individual areas of every module synthesized. If you see any module with a zero in this file, it means that module was NOT synthesized correctly. The format of this file is similar to the references_report.txt file.

5.7  .syn.v file

This file contains the synthesized structural netlist of your design.

6.  Optimizing Your Design - Make it faster & smaller

Thus far we have been synthesizing your design preserving its hierarchy. That is, if you said build a barrel-shifft using mux -> shift -> mux -> shift. Then synthesis will blindly create a hardware module for each such individual module you specified.

You can guide synthesis into "flattening" your design, i.e. treat everything between two flip-flops as raw combinational logic and simply create the most efficient logic gates to implement this. When you do this process, you will see your hierarchical design of the datapath completely disappear.

You can do this by adding the --opt option to synth.pl. For example:

prompt>synth.pl --list=list.txt --type=other --cmd=synth --top=ALU --opt
prompt>synth.pl --list=list.txt --type=proc --cmd=synth --top=proc --f=fetch --d=decode --e=execute --m=memory --wb=write_back --opt

Page last modified on October 05, 2020, visited times

Edit - History - Print - Recent Changes (All) - Search