Implementing a Macro for Caravel¶
Originally written by Kareem Farid and Mohamed Hosni
Note
If you do not have prior experience with LibreLane, please make sure to go through the Getting Started: Newcomers tutorial first.
Initially released in 2020 by Efabless Corporation, the Caravel harness chip is comprised of base functions supporting IO, power, and configuration as well as drop-in modules for a management SoC core, and a ≈ 3mm x 3.6mm open project area for the placement of user IP blocks.
Both OpenLane and LibreLane were initially developed for use with Caravel, which in turn was created for the OpenMPW project.
AES stands for Advanced Encryption Standard which is a symmetric encryption
algorithm widely used across the globe to secure data. It operates on blocks of
data using keys of 128, 192, or 256 bits to encrypt and decrypt information,
providing a high level of security and efficiency for electronic data
protection. In this tutorial, we are going to harden an AES core and have it
as a
Caravel User Project
macro to serve as an accelerator for the chip
Caravel.
Creating your own project repository¶
Note
For the purposes of this tutorial, we will be using a maintained fork of the Caravel User Project by UmbraLogic Technologies LLC that uses LibreLane instead of OpenLane.
Start by creating a new repository from the Caravel user project LibreLane template. Let’s call it
caravel_aes_accelerator.Open a terminal and clone your repository as follows:
$ git clone git@github.com:<github_user_name>/caravel_aes_accelerator.git ~/caravel_aes_accelerator
RTL integration¶
We begin by using the open-source RTLs for AES by
Joachim Strömbergson and adding a Wishbone bus
wrapper for Caravel. Since the RTL from secworks provides a generic memory
interface, we only need to add the ack, write_enable, and read_enable
logic to the Wishbone wrapper.
Clone the
secworks/aesGit repository$ git clone git@github.com:secworks/aes.git ~/secworks_aes
Create the Verilog file
~/caravel_aes_accelerator/verilog/rtl/aes_wb_wrapper.vand add the Wishbone wrapper to the RTL:aes_wb_wrapper.v
// SPDX-FileCopyrightText: 2020 Efabless Corporation // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // SPDX-License-Identifier: Apache-2.0 `default_nettype none module aes_wb_wrapper ( `ifdef USE_POWER_PINS inout VPWR, inout VGND, `endif // Wishbone Slave ports (WB MI A) input wb_clk_i, input wb_rst_i, input wbs_stb_i, input wbs_cyc_i, input wbs_we_i, input [3:0] wbs_sel_i, input [31:0] wbs_dat_i, input [31:0] wbs_adr_i, output wbs_ack_o, output [31:0] wbs_dat_o ); wire valid; wire write_enable; wire read_enable; reg wbs_ack_o_reg; assign valid = wbs_cyc_i && wbs_stb_i; assign write_enable = wbs_we_i && valid; assign read_enable = ~wbs_we_i && valid; aes aes( // Clock and reset. .clk(wb_clk_i), .reset_n(!wb_rst_i), // Control. .cs(wbs_cyc_i && wbs_stb_i), .we(write_enable), // Data ports. .address(wbs_adr_i[9:2]), .write_data(wbs_dat_i), .read_data(wbs_dat_o) ); // Ack logic always @(posedge wb_clk_i or posedge wb_rst_i) begin if (wb_rst_i) wbs_ack_o_reg <= 1'b0; else if (wbs_cyc_i && wbs_stb_i && ~wbs_ack_o_reg) wbs_ack_o_reg <= 1'b1; else wbs_ack_o_reg <= 1'b0; end assign wbs_ack_o = wbs_ack_o_reg; endmodule `default_nettype noneInstantiate the
aes_wb_wrapperin theuser_project_wrapperVerilog file under~/caravel_aes_accelerator/verilog/rtluser_project_wrapper.v
// SPDX-FileCopyrightText: 2020 Efabless Corporation // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // SPDX-License-Identifier: Apache-2.0 `default_nettype none /* *------------------------------------------------------------- * * user_project_wrapper * * This wrapper enumerates all of the pins available to the * user for the user project. * * An example user project is provided in this wrapper. The * example should be removed and replaced with the actual * user project. * *------------------------------------------------------------- */ module user_project_wrapper #( parameter BITS = 32 ) ( `ifdef USE_POWER_PINS inout vdda1, // User area 1 3.3V supply inout vdda2, // User area 2 3.3V supply inout vssa1, // User area 1 analog ground inout vssa2, // User area 2 analog ground inout vccd1, // User area 1 1.8V supply inout vccd2, // User area 2 1.8v supply inout vssd1, // User area 1 digital ground inout vssd2, // User area 2 digital ground `endif // Wishbone Slave ports (WB MI A) input wb_clk_i, input wb_rst_i, input wbs_stb_i, input wbs_cyc_i, input wbs_we_i, input [3:0] wbs_sel_i, input [31:0] wbs_dat_i, input [31:0] wbs_adr_i, output wbs_ack_o, output [31:0] wbs_dat_o, // Logic Analyzer Signals input [127:0] la_data_in, output [127:0] la_data_out, input [127:0] la_oenb, // IOs input [`MPRJ_IO_PADS-1:0] io_in, output [`MPRJ_IO_PADS-1:0] io_out, output [`MPRJ_IO_PADS-1:0] io_oeb, // Analog (direct connection to GPIO pad---use with caution) // Note that analog I/O is not available on the 7 lowest-numbered // GPIO pads, and so the analog_io indexing is offset from the // GPIO indexing by 7 (also upper 2 GPIOs do not have analog_io). inout [`MPRJ_IO_PADS-10:0] analog_io, // Independent clock (on independent integer divider) input user_clock2, // User maskable interrupt signals output [2:0] user_irq ); /*--------------------------------------*/ /* User project is instantiated here */ /*--------------------------------------*/ aes_wb_wrapper mprj ( `ifdef USE_POWER_PINS .VPWR(vccd2), .VGND(vssd2), `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 `default_nettype wire
Hardening strategies¶
There are 3 options for implementing a Caravel User Project design using LibreLane:
Macro-First Hardening: Harden the user macro(s) initially and incorporate them into the user project wrapper without top-level standard cells. Ideal for smaller designs, as this approach significantly reduces Placement and Routing (PnR) and signoff time.Full-Wrapper Flattening: Merge the user macro(s) with the user_project_wrapper, covering the entire wrapper area. While this method demands more time and iterations for PnR and signoff, it ultimately enhances performance, making it suitable for designs requiring the full wrapper area.Top-Level Integration: A hybrid approach where the user macro(s) are hardened then instantiated in the wrapper alongside standard cells at the top level. This is useful to allow user macros to be harderned separately, but the top-level may still insert its own buffers or similar to handle boundary violations.
See also
See the Caravel Integration & Power Routing document (archived from original) for more information about these options.
For this tutorial, we will be following all three in order.