Synopsys Design Compiler 综合实践

工艺库 综合很重要的一步是把 HDL 的逻辑变成一个个单元,这些单元加上连接方式就成为了网表。那么,基本单元有哪些,怎么决定用哪些基本单元? 这个就需要工艺库了,工艺库定义了一个个单元,单元的引脚、功能,还有各种参数,这样 Design Compiler 就可以按照这些信息去找到一个优化的网表。 Liberty 格式 网上可以找到一些 Liberty 格式的工艺库,比如 Nangate45,它的设定是 25 摄氏度,1.10 伏,属于 TT(Typical/Typical)的 Process Corner。 在里面可以看到一些基本单元的定理,比如 AND2_X1,就是一个 drive strength 是 1 的二输入与门: cell (AND2_X1) { drive_strength : 1; pin (A1) { direction : input; } pin (A2) { direction : input; } pin (ZN) { direction : output; function : "(A1 & A2)"; } /* ... */ } 这样就定义了两个输入 pin,一个输出 pin,还有它实现的功能。还有很重要的一点是保存了时序信息,比如: lu_table_template (Timing_7_7) { variable_1 : input_net_transition; variable_2 : total_output_net_capacitance; index_1 ("0.

Read More

OpenROAD Flow 初尝试

背景 最近在尝试接触一些芯片前后端的知识。正好有现成的开源工具链 OpenROAD 来做这个事情,借此机会来学习一下整个流程。 尝试过程 首先 clone 仓库 OpenROAD-flow-scripts,然后运行:./build_openroad.sh,脚本会克隆一些仓库,自动进行编译。 编译中会找不到一些库,比如可能需要安装这些依赖:liblemon-dev libeigen3-dev libreadline-dev swig,此外运行的时候还需要 klayout 依赖。 如果遇到解决 cmake 找不到 LEMON 的问题,这是一个 BUG,可以运行下面的命令解决: cd /usr/lib/x86_64-linux-gnu/cmake/lemon cp lemonConfig.cmake LEMONConfig.cmake 编译后整个目录大概有 4.8G,输出的二进制目录是 133M。 如果要跑一下样例里的 nangate45 工艺的 gcd 例子,运行: cd flow make DESIGN_CONFIG=./designs/nangate45/gcd/config.mk 分析 GCD 测例 这个测例的代码提供了这样一个接口: module gcd ( input wire clk, input wire [ 31:0] req_msg, output wire req_rdy, input wire req_val, input wire reset, output wire [ 15:0] resp_msg, input wire resp_rdy, output wire resp_val ); endmodule 从名字可以推断出,外部通过 req 发送请求到 GCD 模块,然后模块计算出 GCD 后再返回结果。

Read More

通过 JTAG 对 VCU128 上的 Rocket Chip 进行调试

前言 两年前,我尝试过用 BSCAN JTAG 来配置 Rocket Chip 的调试,但是这个方法不是很好用,具体来说,如果有独立的一组 JTAG 信号,配置起来会更方便,而且不用和 Vivado 去抢,OpenOCD 可以和 Vivado hw_server 同时运行和工作。但是,苦于 VCU128 上没有 PMOD 接口,之前一直没考虑过在 VCU128 上配置独立的 JTAG。然后最近研究了一下,终于解决了这个问题。 寻找 JTAG 接口 前几天在研究别的问题的时候,看到 VCU128 文档中的这段话: The FT4232HL U8 multi-function USB-UART on the VCU128 board provides three level-shifted UART connections through the single micro-AB USB connector J2. • Channel A is configured in JTAG mode to support the JTAG chain • Channel B implements 4-wire UART0 (level-shifted) FPGA U1 bank 67 connections • Channel C implements 4-wire UART1 (level-shifted) FPGA U1 bank 67 connections • Channel D implements 2-wire (level-shifted) SYSCTLR U42 bank 501 connections 其中 Channel A 是到 FPGA 本身的 JTAG 接口,是给 Vivado 用的,如果是通过 BSCAN 的方式,也是在这个 Channel 上,但是需要经过 FPGA 自己的 TAP 再隧道到 BSCAN 上,比较麻烦。Channel B 和 C 是串口,Channel D 是连接 VCU128 上的 System Controller 的。之前的时候,都是直接用 Channel B 做串口,然后突发奇想:注意到这里是 4-wire UART,说明连接到 FPGA 是四条线,那是不是也可以拿来当 JTAG 用?

Read More

解决 k3s 中 traefik 不会转发 X-Forwarded-For 等头部的问题

背景 把应用迁移到 k3s 中,然后用了 traefik 作为 Ingress Controller,发现无法获得真实的用户 IP 地址,而是 cni 内部的地址。搜索了一番,找到了靠谱的解决方案: Traefik Kubernetes Ingress and X-Forwarded-Headers 具体来说,需要给 traefik 传额外的参数,方法是在 k3s 的配置目录下,添加一个 HelmChartConfig: # edit /var/lib/rancher/k3s/server/manifests/traefik-config.yaml # content: apiVersion: helm.cattle.io/v1 kind: HelmChartConfig metadata: name: traefik namespace: kube-system spec: valuesContent: |- additionalArguments: - "--entryPoints.web.proxyProtocol.insecure" - "--entryPoints.web.forwardedHeaders.insecure" 这样相当于让 traefik 信任前一级代理传过来的这些头部。更精细的话,还可以设置信任的 IP 地址范围,不过如果 traefik 不会直接暴露出去,就不用考虑这个问题了。

Read More

在 M1 上运行 Windows ARM 虚拟机

目前 Windows ARM 出了预览版,可以从 Windows Insider Preview Downloads 下载,得到一个 9.5GB 的 vhdx 文件。 接着,用 qemu-img 转换为 vmdk 格式: $ qemu-img convert Windows11_InsiderPreview_Client_ARM64_en-us_22533.vhdx -O vmdk -o adapter_type=lsilogic Windows11_InsiderPreview_Client_ARM64_en-us_22533.vmdk 转换后,在 VMWare Fusion for Apple Silicon Tech Preview 中,选择从已有的 vmdk 中创建虚拟机,启动前修改一些设置,特别是内存,默认 256MB 肯定不够,默认单核 CPU 也太少了一些。内存不足可能导致安装失败,记住要第一次启动前设置。 启动以后会无法访问网络,按照下面网页里的方法设置网络: https://www.gerjon.com/vmware/vmware-fusion-on-apple-silicion-m1/ 需要注意的是,bcdedit 选项填的 IP 地址一般是 bridge 上的地址,比如 bridge101 的地址。 然后就可以正常工作了! 在 VMWare 论坛里,还谈到了下面几个问题的解决方法: 为了让声音工作,可以修改 vmx 文件,设置 guestOS: guestOS = "arm-windows11-64" 这样声音就可以正常播放了。 分辨率的问题,可以用 RDP 来解决:首先在虚拟机里打开 Remote Desktop,然后用 macOS 的 Microsoft Remote Desktop Beta 访问即可。

Read More

RISC-V Vector 1.0 工具链构建

不久前 RVV 1.0 标准终于是出来了,但是工具链的支持目前基本还处于刚 upstream 还没有 release 的状态。而目前 RVV 1.0 的支持主要在 LLVM 上比较活跃,因此也是采用 LLVM Clang + GCC Newlib Toolchain 的方式进行配合,前者做 RVV 1.0 的编译,后者提供 libc 等基础库。 UPDATE: LLVM 14 已经发布,这个版本已经支持 RVV 1.0,直接从 https://apt.llvm.org 等地安装 LLVM 14 即可。 LLVM Clang 直接采用 upstream 即可。编译选项: $ cmake -G Ninja ../llvm -DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++ -DCMAKE_INSTALL_PREFIX=/prefix/llvm -DCMAKE_BUILD_TYPE=Release -DLLVM_ENABLE_PROJECTS="clang" -DLLVM_TARGETS_TO_BUILD="RISCV" $ ninja $ ninja install $ /prefix/llvm/bin/clang --version clang version 14.0.0 (https://github.com/llvm/llvm-project.git 8d298355ca3778a47fd6b3110aeee03ea5e8e02b) Target: x86_64-unknown-linux-gnu Thread model: posix InstalledDir: /data/llvm/bin 还需要配合一个 GCC 工具链才可以完整地工作。可以直接采用 riscv-gnu-toolchain nightly 版本,比如 riscv64-elf-ubuntu-20.

Read More

分析 Rocket Chip 中 Diplomacy 系统

概念 Diplomacy 主要实现了两个功能: 把整个总线结构在代码中表现出来 自动配置总线中各个端口的参数 具体来说,第一点实现了类似 Vivado Board Design 中连线的功能,第二点则是保证总线两端的参数一致,可以连接起来。 Diplomacy 为了表示总线的结构,每个模块可以对应一个 Node,Node 和 Node 之间连接形成一个图。Node 的类型主要有以下几个: Client:对应 AXI 里面的 Master,发起请求 Manager:对应 AXI 里面的 Slave,处理请求 Adapter:对应 AXI Width Converter/Clock Converter/AXI4 to AXI3/AXI4 to AHB bridge 等,会修改 AXI 的参数,然后每个输入对应一个输出 Nexus:对应 AXI Crossbar,多个输入和多个输出 每个 Node 可能作为 Manager 连接上游的 Client,这个叫做入边(Inward Edge);同样地,也可以作为 Client 连接下游的 Manager,这个是出边(Outward Edge)。想象成一个 DAG,从若干个 Client 流向 Manager。 连接方式采用的是 := :=* :*= :*=* 操作符,左侧是 Client,右侧是 Manager。 Rocket Chip 总线结构 Rocket Chip 主要有以下几个总线:

Read More

Chisel3 Cookbook

Chisel 版本选择 尽量选择较新版本的 Chisel。Chisel v3.5 完善了编译器插件,使得生成的代码中会包括更多变量名信息。 去掉输出 Verilog 文件中的寄存器随机初始化 版本:FIRRTL >= 1.5.0-RC2 代码: new ChiselStage().execute( Array("-X", "verilog", "-o", s"${name}.v"), Seq( ChiselGeneratorAnnotation(genModule), CustomDefaultRegisterEmission( useInitAsPreset = false, disableRandomization = true ) ) ) 设置 disableRandomization=true 即可。useInitAsPreset 不建议开启。 关闭 FIRRTL 优化,输出尽可能与源代码一致的 Verilog 设置 Chisel 生成 MinimumVerilog: new ChiselStage().execute( Array("-X", "mverilog", "-o", s"${name}.v"), Seq( ChiselGeneratorAnnotation(genModule) ) ) 此时代码中会保留更多原始 Chisel 代码的元素。 重命名 AXI4 为标准命名 Rocket Chip 中 AXI4Bundle 直接生成的名字和标准写法不同,可以利用 Chisel3 3.

Read More

升级 Linksys E8450 的 OpenWRT 系统到 UBI

背景 在 OpenWRT Linksys E8450 页面 中,如果要用新版的固件,需要转换到 UBI 格式的文件系统。之前用的是 non-UBI 格式的文件系统,直接在官方的分区下,覆盖掉其中一个启动分区。但是经常会报告 flash 出错,然后系统也不稳定,决定要按照文档更新到 UBI。 步骤 基本按照文档一步一步走。初始状态是一个 non-UBI 版本的 OpenWRT 固件: 下载官方的 1.0 固件:https://downloads.linksys.com/support/assets/firmware/FW_E8450_1.0.01.101415_prod.img 在 luci 中,刷入官方 1.0 固件,这时候进入了官方固件的系统 登录官方固件网页,恢复出厂设置 下载 openwrt ubi recovery 固件 然后在官方固件里刷入 这时候进入了 recovery 固件,下载 ubi 固件,继续在网页里刷入 这时候固件就更新完成了。ssh root@192.168.1.1,然后进去安装 luci 等软件,恢复配置即可。

Read More