How to integrate commercial SRAM to your design

This article summarizes how to install and integrate the commercial SRAM from fabless Marketplace to your user project.

This tutorial demonstrates how to seamlessly integrate SRAM into your design using Caravel as the platform. While Caravan and openFrame are also viable options, we will focus on Caravel for this example. Our approach involves streamlining the controller and linking it to the SRAM within a macro for efficient integration.

Step 1:

Install IPM:

cd ~
git clone https://github.com/efabless/IPM.git
pip install ./IPM

Test IPM installation:

ipm ls-remote

You should see something like this:Screenshot 2024-05-13 at 11.59.17 PM

For the purpose of this tutorial, we are interested in the EF_SRAM_1024x32 IP.

Step 2:

Create your project repository from our template:

Follow these steps from caravel user project repo

Setup your environment:

Start by cloning the repo you created:

git clone <repo url>

Setup the environment:

cd <repo name>
make setup

Install the SRAM IP:

Use this command to install the SRAM IP using IPM that we installed earlier in the tutorial

ipm install EF_SRAM_1024x32

This will download the IP inside your project directory, it will be found under ip/ directory. The directory structure of the IP is predefined as shown:

.
├── EF_SRAM_1024X32.yaml - Configuration file for IP
├── README.md - General information (or datasheet) for project
├── doc/ - Documentation files for the project
├── gds/ - GDSII files for the IP
├── hdl/ - Hardware Description language files
│   └── beh_models/ - Behavioral models
├── lef/ - Library Exchange Format files
├── lib/ - Liberty files for timing
└── mag/ - magic layout files

The SRAM datasheet can be found here.

Step 3:

To integrate the SRAM macro into the user project's Verilog, in order to interface the wishbone bus, the SRAM IP comes with a controller located in ip/EF_SRAM_1024x32/hdl/ram_controller.v. This controller is not pre-hardened, so we will combine it with the SRAM IP inside a macro. The integration of the SRAM IP and controller can be found in ip/EF_SRAM_1024x32/hdl/SRAM_1024x32.v. This Verilog file will be used to harden our SRAM + controller macro.

Update user_proj_example openLane configuration file:

We'll create a new directory and copy everything inside the user_proj_example to it

cd openlane
mkdir SRAM_1024x32
cp user_proj_example/* SRAM_1024x32

Now we will delete the user_proj_example because we don't need it anymore

rm -rf user_proj_example

Let's change openLane configuration file config.json:

  1. Delete all the configurations in the openlane/SRAM_1024x32/config.json file and replace them with the following:
    {
      "DESIGN_NAME": "SRAM_1024x32",
      "VERILOG_FILES": [
          "dir::../../ip/EF_SRAM_1024x32/hdl/ram_controller.v",
          "dir::../../ip/EF_SRAM_1024x32/hdl/EF_SRAM_1024x32_wrapper.v",
          "dir::../../ip/EF_SRAM_1024x32/hdl/SRAM_1024x32.v"
      ],
      "ERROR_ON_LINTER_ERRORS": false,
      "CLOCK_PERIOD": 25,
      "CLOCK_PORT": "wb_clk_i",
      "FP_SIZING": "absolute",
      "DIE_AREA": "0.000 0.000 380 435",
      "CORE_AREA": "5.000 5.000 375 430",
      "FP_PIN_ORDER_CFG": "dir::pin_order.cfg",
      "PNR_SDC_FILE": "dir::base.sdc",
      "SIGNOFF_SDC_FILE": "dir::base.sdc",
      "VDD_NETS": [
          "VPWR"
      ],
      "GND_NETS": [
          "VGND"
      ],
      "VERILOG_FILES_BLACKBOX": [
          "dir::../../ip/EF_SRAM_1024x32/hdl/EF_SRAM_1024x32_stub.v"
      ],
      "EXTRA_GDS_FILES": [
          "dir::../../ip/EF_SRAM_1024x32/gds/EF_SRAM_1024x32_wrapper.gds"
      ],
      "EXTRA_LEFS": [
          "dir::../../ip/EF_SRAM_1024x32/lef/EF_SRAM_1024x32_wrapper.lef"
      ],
      "EXTRA_LIBS": [
          "dir::../../ip/EF_SRAM_1024x32/lib/EF_SRAM_1024x32_wrapper_tt_180V_25C.lib"
      ],
      "MACRO_PLACEMENT_CFG": "dir::macro.cfg",
      "FP_PDN_HORIZONTAL_LAYER": "met3",
      "FP_PDN_VERTICAL_LAYER": "met2",
      "RUN_IRDROP_REPORT": false,
      "FP_PDN_VOFFSET": 5,
      "FP_PDN_HOFFSET": 5,
      "FP_PDN_VWIDTH": 1.76,
      "FP_PDN_HWIDTH": 1.76,
      "FP_PDN_VSPACING": 10,
      "FP_PDN_HSPACING": 10,
      "FP_PDN_VPITCH": 50,
      "FP_PDN_HPITCH": 50,
      "FP_PDN_MACRO_HOOKS": [
          "SRAM_0 VPWR VGND vpwra vgnd",
          "SRAM_0 VPWR VGND vpb vnb",
          "SRAM_0 VPWR VGND vpwrp vgnd",
          "SRAM_0 VPWR VGND vpwrm vgnd"
      ],
      "FP_PDN_CFG": "dir::pdn.tcl",
      "QUIT_ON_LINTER_ERRORS": false,
      "GRT_OBS": [
          "met1 0 40 314 435",
          "met2 0 40 314 435",
          "met3 0 40 314 435",
          "met4 0 40 314 435",
          "met5 0 40 314 435"
      ],
      "PL_TARGET_DENSITY": 0.15,
      "PL_TIME_DRIVEN": false,
      "GRT_ALLOW_CONGESTION": true,
      "GRT_ADJUSTMENT": 0,
      "GRT_REPAIR_ANTENNAS": false,
      "QUIT_ON_MAGIC_DRC": false,
      "QUIT_ON_KLAYOUT_DRC": false,
      "MAGIC_EXT_USE_GDS": true,
      "QUIT_ON_LVS_ERROR": false,
      "QUIT_ON_TR_DRC": false
    }
    For more information about the openLane configurations used, visit openLane's documentation.
  2. Adjust the pin order by updating the file openlane/SRAM_1024x32/pin_order.cfg. Ensure that all pins are oriented towards the south to facilitate smooth connection with the wishbone bus:
    #BUS_SORT

    #S
    $40
    wb_.*
    wbs_.*
  3. Create a openlane/SRAM_1024x32/macro.cfg file and add the macro placement:
    SRAM_0 10.1 40 W
  4. Create a openlane/SRAM_1024x32/pdn.tcl file, this will edit the PDN to add metal 4 stripes to make the integration to the top level easier. The PDN script can be found here.

Harden the SRAM + controller macro:

Now we need to run the openLane flow to harden the macro we created above, this can be done with one command from the root directory of your project:

make SRAM_1024x32

The flow should start running, and after a couple of seconds you should see something like this:

NOTE: The klayout DRC error is a known issue with the DRC deck, if by the time you are trying this tutorial, it didn't spit out a DRC error, it is because we fixed it.

Step 4:

To integrate the SRAM macro with the user_project_wrapper, we have to start by editing the rtl/user_project_wrapper.v, to add the SRAM macro:

SRAM_1024x32 mprj (
`ifdef USE_POWER_PINS
 .VPWR(vccd1), // User area 1 1.8V power
 .VGND(vssd1), // User area 1 digital ground
`endif


    .wb_clk_i(wb_clk_i),
    .wb_rst_i(wb_rst_i),


    // MGMT SoC Wishbone Slave


    .wbs_cyc_i(wbs_cyc_i),
    .wbs_stb_i(wbs_stb_i),
    .wbs_we_i(wbs_we_i),
    .wbs_sel_i(wbs_sel_i),
    .wbs_adr_i(wbs_adr_i),
    .wbs_dat_i(wbs_dat_i),
    .wbs_ack_o(wbs_ack_o),
    .wbs_dat_o(wbs_dat_o)
);


endmodule // user_project_wrapper

This should be added after:

/*--------------------------------------*/
/* User project is instantiated  here   */
/*--------------------------------------*/

Update the user_project_wrapper openLane configuration file:

  1. Add the generated files that we generated in the step before, these include verilog, GDS, LEF, lib and SPEF files:
    "VERILOG_FILES_BLACKBOX": [
          "dir::../../verilog/gl/SRAM_1024x32.v"
      ],
      "EXTRA_LEFS": "dir::../../lef/SRAM_1024x32.lef",
      "EXTRA_GDS_FILES": "dir::../../gds/SRAM_1024x32.gds",
      "EXTRA_LIBS": "dir::../../lib/SRAM_1024x32.lib",
      "EXTRA_SPEFS": [
          "SRAM_1024x32",
          "dir::../../spef/multicorner/SRAM_1024x32.min.spef",
          "dir::../../spef/multicorner/SRAM_1024x32.nom.spef",
          "dir::../../spef/multicorner/SRAM_1024x32.max.spef"
        ],
  2. Update the macro PDN hooks:
        "FP_PDN_MACRO_HOOKS": "mprj vccd1 vssd1 VPWR VGND"
  3. Update the Global Routing Obstructions to avoid routing over the SRAM macro:
        "GRT_OBS": [
          "met1 0 40 314 435",
          "met2 0 40 314 435",
          "met3 0 40 314 435",
          "met4 0 40 314 435"
        ],
  4. Adjust the macro placement using the openlane/user_project_wrapper/macro.cfg file:
    mprj 15.06 115 N

Harden the user_project_wrapper:

from the project root run the flow to harden the user_project_wrapper

make user_project_wrapper

Now you should get a fully integrated SRAM IP macro inside the user_project_wrapper. You can view the final GDS from gds/user_project_wrapper.gds, using any tool of your liking, example: Klayout.

This is how the fully integrated wrapper should look like

Resources:

  • The example in this tutorial can be found in this repo
  • Efabless webinar going through the whole process YouTube video
  • Efabless Marketplace