diff --git a/.gitignore b/.gitignore index 4c8e9b87..bcba19d7 100644 --- a/.gitignore +++ b/.gitignore @@ -53,3 +53,6 @@ target/xilinx/build target/xilinx/out target/xilinx/scripts/add_sources.* vivado* + +# Bender/Yosys generated files +target/yosys/out diff --git a/Bender.lock b/Bender.lock index 5697c987..99bcce00 100644 --- a/Bender.lock +++ b/Bender.lock @@ -60,8 +60,8 @@ packages: dependencies: - common_cells axi_vga: - revision: 3718b9930f94a9eaad8ee50b4bccc71df0403084 - version: 0.1.3 + revision: 4d3e70d4f47bb74edc1ab68d99ffc02382e0fb9e + version: 0.1.4 source: Git: https://github.com/pulp-platform/axi_vga.git dependencies: @@ -85,16 +85,16 @@ packages: - common_cells - register_interface common_cells: - revision: 13f28aa0021fc22c0d01a12d618fda58d2c93239 - version: 1.33.0 + revision: c27bce39ebb2e6bae52f60960814a2afca7bd4cb + version: 1.37.0 source: Git: https://github.com/pulp-platform/common_cells.git dependencies: - common_verification - tech_cells_generic common_verification: - revision: 9c07fa860593b2caabd9b5681740c25fac04b878 - version: 0.2.3 + revision: fb1885f48ea46164a10568aeff51884389f67ae3 + version: 0.2.5 source: Git: https://github.com/pulp-platform/common_verification.git dependencies: [] @@ -169,8 +169,8 @@ packages: - register_interface - tech_cells_generic register_interface: - revision: ae616e5a1ec2b41e72d200e5ab09c65e94aebd3d - version: 0.4.4 + revision: 5daa85d164cf6b54ad061ea1e4c6f3624556e467 + version: 0.4.5 source: Git: https://github.com/pulp-platform/register_interface.git dependencies: @@ -187,8 +187,8 @@ packages: - common_cells - tech_cells_generic serial_link: - revision: 5a25f5a71074f1ebb6de7b5280f2b16924bcc666 - version: 1.1.1 + revision: c55df03a1da06b00e567cf968b1b1a5f40c9f802 + version: 1.1.2 source: Git: https://github.com/pulp-platform/serial_link.git dependencies: @@ -203,8 +203,8 @@ packages: dependencies: - common_verification unbent: - revision: e9c9d5cfb635f2d4668c816ce9235798cfecb297 - version: 0.1.6 + revision: af0c25ba9eaaefade8688a4a47ced999d4c5255d + version: null source: Git: https://github.com/pulp-platform/unbent.git dependencies: diff --git a/Bender.yml b/Bender.yml index 30817f2c..edf63ab5 100644 --- a/Bender.yml +++ b/Bender.yml @@ -17,7 +17,7 @@ dependencies: axi_llc: { git: "https://github.com/pulp-platform/axi_llc.git", version: 0.2.1 } axi_riscv_atomics: { git: "https://github.com/pulp-platform/axi_riscv_atomics.git", version: 0.8.2 } axi_rt: { git: "https://github.com/pulp-platform/axi_rt.git", version: 0.0.0-alpha.9 } - axi_vga: { git: "https://github.com/pulp-platform/axi_vga.git", version: 0.1.3 } + axi_vga: { git: "https://github.com/pulp-platform/axi_vga.git", version: 0.1.4 } clic: { git: "https://github.com/pulp-platform/clic.git", version: 2.0.0 } clint: { git: "https://github.com/pulp-platform/clint.git", version: 0.2.0 } common_cells: { git: "https://github.com/pulp-platform/common_cells.git", version: 1.33.0 } @@ -28,8 +28,8 @@ dependencies: opentitan_peripherals: { git: "https://github.com/pulp-platform/opentitan_peripherals.git", version: 0.4.0 } register_interface: { git: "https://github.com/pulp-platform/register_interface.git", version: 0.4.4 } riscv-dbg: { git: "https://github.com/pulp-platform/riscv-dbg.git", version: 0.8.1 } - serial_link: { git: "https://github.com/pulp-platform/serial_link.git", version: 1.1.1 } - unbent: { git: "https://github.com/pulp-platform/unbent.git", version: 0.1.6 } + serial_link: { git: "https://github.com/pulp-platform/serial_link.git", version: 1.1.2 } + unbent: { git: "https://github.com/pulp-platform/unbent.git", rev: af0c25ba9eaaefade8688a4a47ced999d4c5255d } dram_rtl_sim: { git: "https://github.com/pulp-platform/dram_rtl_sim.git", version: 0.1.1 } export_include_dirs: @@ -60,3 +60,9 @@ sources: - target/xilinx/src/dram_wrapper_xilinx.sv - target/xilinx/src/fan_ctrl.sv - target/xilinx/src/cheshire_top_xilinx.sv + + - target: chs_synthesis + files: + - target/yosys/tc_sram_blackbox.sv + - target/yosys/tc_clk_blackbox.sv + - hw/cheshire_synth_wrapper.sv diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 00000000..8e6b796a --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,21 @@ +# Copyright (c) 2024 ETH Zurich and University of Bologna. +# Licensed under the Apache License, Version 2.0, see LICENSE for details. +# SPDX-License-Identifier: Apache-2.0 +# +# Authors: +# - Philippe Sauter + +services: + oseda: + image: hpretl/iic-osic-tools:2025.01 + environment: + - UID=${UID} + - GID=${GID} + user: "${UID}:${GID}" + volumes: + - ./:/fosic/designs/cheshire + stdin_open: true + tty: true + working_dir: /fosic/designs/cheshire + entrypoint: /dockerstartup/scripts/ui_startup.sh + command: --skip bash diff --git a/hw/cheshire_synth_wrapper.sv b/hw/cheshire_synth_wrapper.sv new file mode 100644 index 00000000..3a56cfe2 --- /dev/null +++ b/hw/cheshire_synth_wrapper.sv @@ -0,0 +1,135 @@ +// Copyright 2025 ETH Zurich and University of Bologna. +// Solderpad Hardware License, Version 0.51, see LICENSE for details. +// SPDX-License-Identifier: SHL-0.51 +// +// Authors: +// Philippe Sauter + +package cheshire_synth_wrapper_pkg; + `include "cheshire/typedef.svh" + + import cheshire_pkg::*; + + // generate the cheshire configuration used here + function automatic cheshire_cfg_t gen_cheshire_cfg(); + cheshire_cfg_t ret = DefaultCfg; + // here you would modify the struct to change your configuration + return ret; + endfunction + localparam cheshire_cfg_t Cfg = gen_cheshire_cfg(); + + `CHESHIRE_TYPEDEF_ALL(, Cfg) +endpackage + + +module cheshire_synth_wrapper import cheshire_synth_wrapper_pkg::*; import cheshire_pkg::*; #( + parameter type axi_ext_llc_req_t = axi_llc_req_t, + parameter type axi_ext_llc_rsp_t = axi_llc_rsp_t, + parameter type axi_ext_mst_req_t = axi_mst_req_t, + parameter type axi_ext_mst_rsp_t = axi_mst_rsp_t, + parameter type axi_ext_slv_req_t = axi_slv_req_t, + parameter type axi_ext_slv_rsp_t = axi_slv_rsp_t, + parameter type reg_ext_req_t = reg_req_t, + parameter type reg_ext_rsp_t = reg_rsp_t +) ( + input logic clk_i, + input logic rst_ni, + input logic test_mode_i, + input logic [1:0] boot_mode_i, + input logic rtc_i, + // JTAG interface + input logic jtag_tck_i, + input logic jtag_trst_ni, + input logic jtag_tms_i, + input logic jtag_tdi_i, + output logic jtag_tdo_o, + output logic jtag_tdo_oe_o, + // UART interface + output logic uart_tx_o, + input logic uart_rx_i, + // UART modem flow control + output logic uart_rts_no, + output logic uart_dtr_no, + input logic uart_cts_ni, + input logic uart_dsr_ni, + input logic uart_dcd_ni, + input logic uart_rin_ni, + // I2C interface + output logic i2c_sda_o, + input logic i2c_sda_i, + output logic i2c_sda_en_o, + output logic i2c_scl_o, + input logic i2c_scl_i, + output logic i2c_scl_en_o, + // GPIO interface + input logic [31:0] gpio_i, + output logic [31:0] gpio_o, + output logic [31:0] gpio_en_o, + // SPI host interface + output logic spih_sck_o, + output logic spih_sck_en_o, + output logic [SpihNumCs-1:0] spih_csb_o, + output logic [SpihNumCs-1:0] spih_csb_en_o, + output logic [ 3:0] spih_sd_o, + output logic [ 3:0] spih_sd_en_o, + input logic [ 3:0] spih_sd_i, + // USB interface + input logic usb_clk_i, + input logic usb_rst_ni, + input logic [UsbNumPorts-1:0] usb_dm_i, + output logic [UsbNumPorts-1:0] usb_dm_o, + output logic [UsbNumPorts-1:0] usb_dm_oe_o, + input logic [UsbNumPorts-1:0] usb_dp_i, + output logic [UsbNumPorts-1:0] usb_dp_o, + output logic [UsbNumPorts-1:0] usb_dp_oe_o, + // VGA interface + output logic vga_hsync_o, + output logic vga_vsync_o, + output logic [Cfg.VgaRedWidth -1:0] vga_red_o, + output logic [Cfg.VgaGreenWidth-1:0] vga_green_o, + output logic [Cfg.VgaBlueWidth -1:0] vga_blue_o, + // Serial link interface + input logic [SlinkNumChan-1:0] slink_rcv_clk_i, + output logic [SlinkNumChan-1:0] slink_rcv_clk_o, + input logic [SlinkNumChan-1:0][SlinkNumLanes-1:0] slink_i, + output logic [SlinkNumChan-1:0][SlinkNumLanes-1:0] slink_o, + // External AXI LLC (DRAM) port + output axi_ext_llc_req_t axi_llc_mst_req_o, + input axi_ext_llc_rsp_t axi_llc_mst_rsp_i, + // External AXI crossbar ports + input axi_ext_mst_req_t [iomsb(Cfg.AxiExtNumMst):0] axi_ext_mst_req_i, + output axi_ext_mst_rsp_t [iomsb(Cfg.AxiExtNumMst):0] axi_ext_mst_rsp_o, + output axi_ext_slv_req_t [iomsb(Cfg.AxiExtNumSlv):0] axi_ext_slv_req_o, + input axi_ext_slv_rsp_t [iomsb(Cfg.AxiExtNumSlv):0] axi_ext_slv_rsp_i, + // External reg demux slaves + output reg_ext_req_t [iomsb(Cfg.RegExtNumSlv):0] reg_ext_slv_req_o, + input reg_ext_rsp_t [iomsb(Cfg.RegExtNumSlv):0] reg_ext_slv_rsp_i, + // Interrupts from and to external targets + input logic [iomsb(Cfg.NumExtInIntrs):0] intr_ext_i, + output logic [iomsb(Cfg.NumExtOutIntrTgts):0][iomsb(Cfg.NumExtOutIntrs):0] intr_ext_o, + // Interrupt requests to external harts + output logic [iomsb(NumIrqCtxts*Cfg.NumExtIrqHarts):0] xeip_ext_o, + output logic [iomsb(Cfg.NumExtIrqHarts):0] mtip_ext_o, + output logic [iomsb(Cfg.NumExtIrqHarts):0] msip_ext_o, + // Debug interface to external harts + output logic dbg_active_o, + output logic [iomsb(Cfg.NumExtDbgHarts):0] dbg_ext_req_o, + input logic [iomsb(Cfg.NumExtDbgHarts):0] dbg_ext_unavail_i +); + + cheshire_soc #( + .Cfg ( Cfg ), + .ExtHartinfo ( '0 ), + .axi_ext_llc_req_t ( axi_llc_req_t ), + .axi_ext_llc_rsp_t ( axi_llc_rsp_t ), + .axi_ext_mst_req_t ( axi_mst_req_t ), + .axi_ext_mst_rsp_t ( axi_mst_rsp_t ), + .axi_ext_slv_req_t ( axi_slv_req_t ), + .axi_ext_slv_rsp_t ( axi_slv_rsp_t ), + .reg_ext_req_t ( reg_req_t ), + .reg_ext_rsp_t ( reg_rsp_t ) + ) i_cheshire_soc ( + .* + ); + +endmodule diff --git a/start_linux.sh b/start_linux.sh new file mode 100755 index 00000000..89e37cea --- /dev/null +++ b/start_linux.sh @@ -0,0 +1,16 @@ +#!/bin/sh +# Copyright (c) 2025 ETH Zurich and University of Bologna. +# Licensed under the Apache License, Version 2.0, see LICENSE for details. +# SPDX-License-Identifier: Apache-2.0 +# +# Authors: +# - Philippe Sauter + +export UID=$(id -u) +export GID=$(id -g) + +docker compose pull +docker compose run \ + -e PS1="\[\033[01;32m\]oseda: \[\033[00m\]\[\033[01;34m\]\w\[\033[00m\] $" \ + -v /tmp/.X11-unix:/tmp/.X11-unix \ + oseda diff --git a/target/yosys/synthesis.sh b/target/yosys/synthesis.sh new file mode 100755 index 00000000..27b7dc55 --- /dev/null +++ b/target/yosys/synthesis.sh @@ -0,0 +1,18 @@ +#!/bin/bash +# Copyright (c) 2025 ETH Zurich and University of Bologna. +# Licensed under the Apache License, Version 2.0, see LICENSE for details. +# SPDX-License-Identifier: Apache-2.0 +# +# Authors: +# - Philippe Sauter + +SCRIPTDIR="$(realpath $(dirname "${BASH_SOURCE[0]}"))" +CHS_BENDER_RTL_FLAGS=${CHS_BENDER_RTL_FLAGS:--t rtl -t cva6 -t cv64a6_imafdcsclic_sv39} +BENDER_TARGETS="-t chs_synthesis -t asic $CHS_BENDER_RTL_FLAGS" +BENDER_DEFINES="-D SYNTHESIS -D COMMON_CELLS_ASSERTS_OFF" + +cd $SCRIPTDIR +mkdir -p out +bender script flist-plus $BENDER_TARGETS $BENDER_DEFINES > out/cheshire.f + +yosys -s yosys.ys diff --git a/target/yosys/synthetic.lib b/target/yosys/synthetic.lib new file mode 100644 index 00000000..e0fd11de --- /dev/null +++ b/target/yosys/synthetic.lib @@ -0,0 +1,113 @@ +/************************************************************************ +Copyright (c) 2025 ETH Zurich and University of Bologna. +Licensed under the Apache License, Version 2.0, see LICENSE for details. +SPDX-License-Identifier: Apache-2.0 + +Minimal cell library with area in NAND gate-equivalent. +Area derived using transistor count of textbook implementations. +Areas increased slightly so large gates have a slight area advantage. + +Authors: +- Thomas Benz +- Philippe Sauter + +************************************************************************/ + +library(synthetic) { + cell(buf) { + area: 1.01; + pin(a_i) { direction: input; } + pin(y_o) { direction: output; + function: "a_i"; } + } + cell(not) { + area: 0.51; + pin(a_i) { direction: input; } + pin(y_o) { direction: output; + function: "a_i'"; } + } + cell(nand) { + area: 1.01; + pin(a_i) { direction: input; } + pin(b_i) { direction: input; } + pin(y_o) { direction: output; + function: "(a_i*b_i)'"; } + } + cell(nor) { + area: 1.01; + pin(a_i) { direction: input; } + pin(b_i) { direction: input; } + pin(y_o) { direction: output; + function: "(a_i+b_i)'"; } + } + cell(and) { + area: 1.51; + pin(a_i) { direction: input; } + pin(b_i) { direction: input; } + pin(y_o) { direction: output; + function: "(a_i*b_i)"; } + } + cell(or) { + area: 1.51; + pin(a_i) { direction: input; } + pin(b_i) { direction: input; } + pin(y_o) { direction: output; + function: "(a_i+b_i)"; } + } + cell(xor) { + area: 2.51; + pin(a_i) { direction: input; } + pin(b_i) { direction: input; } + pin(y_o) { direction: output; + function: "(a_i^b_i)"; } + } + cell(xnor) { + area: 2.51; + pin(a_i) { direction: input; } + pin(b_i) { direction: input; } + pin(y_o) { direction: output; + function: "(a_i^b_i)'"; } + } + cell(mux) { + area: 3.01; + pin(a_i) { direction: input; } + pin(b_i) { direction: input; } + pin(s_i) { direction: input; } + pin(y_o) { direction: output; + function: "(a_i*(s_i'))+(b_i*s_i)"; } + } + cell(tiehi) { + area: 0.01; + pin(y_o) { direction: output; + function: "1"; } + } + cell(tielow) { + area: 0.01; + pin(y_o) { direction: output; + function: "0"; } + } + cell(dffsr) { + area: 6.5; + ff(IQ, IQN) { clocked_on: clk_i; + next_state: d_i; + preset: s_i; + clear: r_i; } + pin(clk_i) { direction: input; + clock: true; } + pin(d_i) { direction: input; } + pin(q_o) { direction: output; + function: "IQ"; } + pin(s_i) { direction: input; } + pin(r_i) { direction: input; } + } + cell(latch) { + area: 3; + latch(IQ, IQN) { enable: clk_i; + data_in: d_i; } + pin(clk_i) { direction: input; + clock: true; } + pin(d_i) { direction: input; } + pin(q_o) { direction: output; + function: "IQ"; } + } +} diff --git a/target/yosys/tc_clk_blackbox.sv b/target/yosys/tc_clk_blackbox.sv new file mode 100644 index 00000000..27dc85bf --- /dev/null +++ b/target/yosys/tc_clk_blackbox.sv @@ -0,0 +1,91 @@ +// Copyright 2025 ETH Zurich and University of Bologna. +// Solderpad Hardware License, Version 0.51, see LICENSE for details. +// SPDX-License-Identifier: SHL-0.51 +// +// Authors: +// Philippe Sauter + +(* blackbox *)(* keep *)(* dont_touch = "true" *) +module tc_clk_and2 ( + input logic clk0_i, + input logic clk1_i, + output logic clk_o +); + + assign clk_o = clk0_i & clk1_i; + +endmodule + +(* blackbox *)(* keep *)(* dont_touch = "true" *) +module tc_clk_buffer ( + input logic clk_i, + output logic clk_o +); + + assign clk_o = clk_i; + +endmodule + +(* blackbox *)(* keep *)(* dont_touch = "true" *) +module tc_clk_gating #( + parameter bit IS_FUNCTIONAL = 1'b1 +)( + input logic clk_i, + input logic en_i, + input logic test_en_i, + output logic clk_o +); + + logic clk_en; + + always_latch begin + if (clk_i == 1'b0) clk_en <= en_i | test_en_i; + end + + assign clk_o = clk_i & clk_en; + +endmodule + +(* blackbox *)(* keep *)(* dont_touch = "true" *) +module tc_clk_inverter ( + input logic clk_i, + output logic clk_o +); + + assign clk_o = ~clk_i; + +endmodule + +(* blackbox *)(* keep *)(* dont_touch = "true" *) +module tc_clk_mux2 ( + input logic clk0_i, + input logic clk1_i, + input logic clk_sel_i, + output logic clk_o +); + + assign clk_o = (clk_sel_i) ? clk1_i : clk0_i; + +endmodule + +(* blackbox *)(* keep *)(* dont_touch = "true" *) +module tc_clk_xor2 ( + input logic clk0_i, + input logic clk1_i, + output logic clk_o +); + + assign clk_o = clk0_i ^ clk1_i; + +endmodule + +(* blackbox *)(* keep *)(* dont_touch = "true" *) +module tc_clk_or2 ( + input logic clk0_i, + input logic clk1_i, + output logic clk_o +); + + assign clk_o = clk0_i | clk1_i; + +endmodule diff --git a/target/yosys/tc_sram_blackbox.sv b/target/yosys/tc_sram_blackbox.sv new file mode 100644 index 00000000..76765e6c --- /dev/null +++ b/target/yosys/tc_sram_blackbox.sv @@ -0,0 +1,62 @@ +// Copyright 2025 ETH Zurich and University of Bologna. +// Solderpad Hardware License, Version 0.51, see LICENSE for details. +// SPDX-License-Identifier: SHL-0.51 +// +// Authors: +// Philippe Sauter + +(* blackbox *) +module tc_sram_blackbox #( + parameter int unsigned NumWords = 32'd0, + parameter int unsigned DataWidth = 32'd0, + parameter int unsigned ByteWidth = 32'd0, + parameter int unsigned NumPorts = 32'd0, + parameter int unsigned Latency = 32'd0, + parameter SimInit = "none", + parameter bit PrintSimCfg = 1'b0, + parameter ImplKey = "none" +) (); +endmodule + +(* keep *)(* dont_touch = "true" *) +module tc_sram #( + parameter int unsigned NumWords = 32'd1024, // Number of Words in data array + parameter int unsigned DataWidth = 32'd128, // Data signal width + parameter int unsigned ByteWidth = 32'd8, // Width of a data byte + parameter int unsigned NumPorts = 32'd2, // Number of read and write ports + parameter int unsigned Latency = 32'd1, // Latency when the read data is available + parameter SimInit = "none", // Simulation initialization + parameter bit PrintSimCfg = 1'b0, // Print configuration + parameter ImplKey = "none", // Reference to specific implementation + // DEPENDENT PARAMETERS, DO NOT OVERWRITE! + parameter int unsigned AddrWidth = (NumWords > 32'd1) ? $clog2(NumWords) : 32'd1, + parameter int unsigned BeWidth = (DataWidth + ByteWidth - 32'd1) / ByteWidth, // ceil_div + parameter type addr_t = logic [AddrWidth-1:0], + parameter type data_t = logic [DataWidth-1:0], + parameter type be_t = logic [BeWidth-1:0] +) ( + input logic clk_i, // Clock + input logic rst_ni, // Asynchronous reset active low + // input ports + input logic [NumPorts-1:0] req_i, // request + input logic [NumPorts-1:0] we_i, // write enable + input addr_t [NumPorts-1:0] addr_i, // request address + input data_t [NumPorts-1:0] wdata_i, // write data + input be_t [NumPorts-1:0] be_i, // write byte enable + // output ports + output data_t [NumPorts-1:0] rdata_o // read data +); + + (* dont_touch = "true" *) + tc_sram_blackbox #( + .NumWords ( NumWords ), + .DataWidth ( DataWidth ), + .ByteWidth ( ByteWidth ), + .NumPorts ( NumPorts ), + .Latency ( Latency ), + .SimInit ( SimInit ), + .PrintSimCfg ( PrintSimCfg ), + .ImplKey ( ImplKey ) + ) i_sram_blackbox (); + +endmodule diff --git a/target/yosys/yosys.ys b/target/yosys/yosys.ys new file mode 100644 index 00000000..7fb5a9a6 --- /dev/null +++ b/target/yosys/yosys.ys @@ -0,0 +1,51 @@ +# Copyright (c) 2025 ETH Zurich and University of Bologna. +# Licensed under the Apache License, Version 2.0, see LICENSE for details. +# SPDX-License-Identifier: Apache-2.0 +# +# Authors: +# - Philippe Sauter + +plugin -i slang.so +read_liberty -lib synthetic.lib +read_slang --top cheshire_synth_wrapper -f out/cheshire.f --allow-use-before-declare \ + --ignore-unknown-modules --compat-mode --compat=vcs --keep-hierarchy + +# keep the interesting hierarchy, flatten the rest +keep_hierarchy cheshire_soc$* +keep_hierarchy cva6$* +keep_hierarchy axi_llc_reg_wrap$* +keep_hierarchy sync$* +keep_hierarchy clic$* +keep_hierarchy dm_top$* +keep_hierarchy dmi_jtag$* +keep_hierarchy cheshire_reg_top$* +keep_hierarchy irq_router$* +keep_hierarchy rv_plic$* +keep_hierarchy clint$* +keep_hierarchy axi_rt_unit_top$* +keep_hierarchy cheshire_bootrom$* +keep_hierarchy reg_uart_wrap$* +keep_hierarchy i2c$* +keep_hierarchy spi_host$* +keep_hierarchy gpio$* +keep_hierarchy cheshire_idma_wrap$* +keep_hierarchy serial_link$* +keep_hierarchy axi_vga$* +keep_hierarchy spinal_usb_ohci$* + +flatten -noscopeinfo +hierarchy -top cheshire_synth_wrapper + +proc +write_verilog -norename -noexpr out/elaborated.v +tee -o out/elaborated.rpt stat + +synth -noabc +rename -wire -suffix _reg t:*DFF* +dfflibmap -liberty synthetic.lib +abc -liberty synthetic.lib +hilomap -singleton -hicell tiehi y_o -locell tielo y_o +tee -o out/area.rpt stat -liberty synthetic.lib +tee -o out/area.json stat -liberty synthetic.lib -json +write_verilog -norename -noexpr out/synthetic_netlist.v +write_verilog -norename out/synthetic_netlist_expr.v