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.5.0 的 DataView 功能进行重命名: // https://www.

Read More

升级 Linksys E8450 的 OpenWRT 系统到 UBI

背景 在 OpenWRT Linksys E8450 页面 中,如果要用新版的固件,需要转换到 UBI 格式的文件系统。之前用的是 non-UBI 格式的文件系统,直接在官方的分区下,覆盖掉其中一个启动分区。但是经常会报告 flash 出错,然后系统也不稳定,决定要按照文档更新到 UBI。 步骤 请注意:更换文件系统操作比较危险,请先备份好数据,并做好变砖的心理准备。本文仅记录了作者编写时可行的更新操作,不代表读者在阅读时,依然可以按照这个顺序进行,请按照 https://github.com/dangowrt/owrt-ubi-installer 的文档进行操作。 基本按照文档一步一步走。初始状态是一个 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

XRDP 和 NVIDIA 显卡兼容性问题

背景 最近在尝试配置 XRDP,发现它在有 NVIDIA 的机器上启动远程桌面后会黑屏,查看错误信息可以看到: xf86OpenConsole: Cannot open virtual console 1 (Permission denied) 解决方法 XRDP 作者在 issue #2010 中提到了解决方法: 修改 /etc/xrdp/sesman.ini,在 [Xorg] 部分里加上下面的配置: param=-configdir param=/ 实际上就是不让 Xorg 加载 nvidia xorg 驱动,这样就绕过了问题。

Read More

NVIDIA 驱动和 CUDA 版本信息速查

背景 之前和 NVIDIA 驱动和 CUDA 搏斗比较多,因此记录一下一些常用信息,方便查询。 常用地址 CUDA Toolkit Downloads NVIDIA Driver Installation Quickstart Guide NVIDIA Driver Downloads NVIDIA Docker Installation Guide CUDA 版本与 NVIDIA 驱动兼容性 可以通过 apt show cuda-runtime-x-x 找到: cuda 11.7 >= 515 cuda 11.6 >= 510 cuda 11.5 >= 495 cuda 11.4 >= 470 cuda 11.3 >= 465 cuda 11.2 >= 460 cuda 11.1 >= 455 cuda 11.0 >= 450 cuda 10.2 >= 440 cuda 10.1 >= 418 cuda 10.

Read More

「教学」缓存一致性协议分析

背景 最近在《高等计算机系统结构》课程中学习缓存一致性协议算法,这里用自己的语言来组织一下相关知识的讲解。 Write-invalidate 和 Write-update 最基础的缓存一致性思想有两种: Write-invalidate:写入数据的时候,将其他 Cache 中这条 Cache Line 设为 Invalid Write-update:写入数据的时候,把新的结果写入到有这条 Cache Line 的其他 Cache Write-once 协议 Write-once 协议定义了四个状态: Invalid:表示这个块不合法 Valid:表示这个块合法,并可能是共享的,同时数据没有修改 Reserved:表示这个块合法,不是共享的,同时数据没有更改 Dirty:表示这个块合法,不是共享的,数据做了修改,和内存不同。 可见,当一个缓存状态在 R 或者 D,其他缓存只能是 I;而缓存状态是 V 的时候,可以有多个缓存在 V 状态。 Write-once 协议的特点是,第一次写的时候,会写入到内存(类似 Write-through),连续写入则只写到缓存中,类似 Write-back。 当 Read hit 的时候,状态不变。 Read hit: The information is supplied by the current cache. No state change. 当 Read miss 的时候,会查看所有缓存,如果有其他缓存处于 Valid/Reserved/Dirty 状态,就从其他缓存处读取数据,然后设为 Valid,其他缓存也设为 Valid。如果其他缓存处于 Dirty 状态,还要把数据写入内存。 Read miss: The data is read from main memory.

Read More

DRAM 在 Kintex 7 FPGA 上内部 Vref 的性能问题

背景 最近我们设计的 Kintex 7 FPGA 开发板在测试 DDR SDRAM 的时候遇到了一个问题,因为采用了 Internel VREF,MIG 在配置的时候限制了频率只能是 400 MHz,对应 800 MT/s,这样无法达到 DDR 的最好性能。 原理 首先,VREF 在 DDR 中是用来区分低电平和高电平的。在 JESD79-4B 标准中,可以看到,对于直流信号,电压不小于 VREF+0.075V 时表示高电平,而电压不高于 VREF-0.075V 时表示低电平。VREF 本身应该介于 VDD 的 0.49 倍到 0.51 倍之间。 在连接 FPGA 的时候,有两种选择: Internal VREF: 从 FPGA 输出 VREF 信号到 DRAM External VREF:接入 FPGA 以外的 VREF 对于 7 Series 的 FPGA,Xilinx 要求如下: For DDR3 SDRAM interfaces running at or below 800 Mb/s (400 MHz), users have the option of selecting Internal VREF to save two I/O pins or using external VREF.

Read More

「教学」DRAM 结构和特性

DRAM 是如何组织的 DRAM 分成很多层次:Bank Group,Bank,Row,Column,从大到小,容量也是各级别的乘积。 举例子: 4 Bank Group 4 Bank per Bank Group 32,768 Row per Bank 1024 Column per Row 4 Bits per Column 那么总大小就是 4*4*32768*1024*4=2 Gb。 访问模式 DRAM 的访问模式决定了访问内存的实际带宽。对于每次访问,需要这样的操作: 用 ACT(Bank Activate) 命令打开某个 Bank Group 下面的某个 Bank 的某个 Row,此时整个 Row 的数据都会复制到 Sense Amplifier 中。这一步叫做 RAS(Row Address Strobe) 用 RD(Read)/WR(Write) 命令按照 Column 访问数据。这一步叫做 CAS(Column Address Strobe)。 在访问其他 Row 之前,需要用 PRE(Single Bank Precharge) 命令将 Sense Amplifier 中整个 Row 的数据写回 Row 中。 可以看到,如果访问连续的地址,就可以省下 ACT 命令的时间,可以连续的进行 RD/WR 命令操作。

Read More