SpinalHDL
前言
为什么要放弃传统的 HDL
VHDL/Verilog 不是硬件描述语言
事件驱动范式对于 RTL 没有任何意义
VHDL 和 Verilog 的最新版本不可用
VHDL 结构记录(record),Verilog 结构(struct)已经破碎(SystemVerilog 在这方面很好,如果您可以使用它)
VHDL 和 Verilog 太冗长了
元硬件描述能力
简介
关于 SpinalHDL
什么是SpinalHDL?
SpinalHDL 不是什么
Spinal开发流程
SpinalHDL 相对于 VHDL / Verilog 的优势
一个简单的例子
Component
端口
内部逻辑
使用 SpinalHDL 的项目
仓库
公司
大学
联系方式
许可证
贡献
常见问题
与人工编写的 VHDL/Verilog 相比,SpinalHDL 生成的 RTL 的开销是多少?
如果 SpinalHDL 将来没有支持了怎么办?
SpinalHDL 是否在生成的 VHDL/Verilog 中保留注释?
SpinalHDL 可以扩展到大型项目吗?
SpinalHDL 是如何诞生的
既然有了VHDL/Verilog/SystemVerilog,为什么还要开发新的语言呢?
如何使用 SpinalHDL 的未发布版本(但在 git 上提交)?
其他学习资料
入门
安装和设置
必需/推荐的工具
Linux安装
Mac OS X 安装
Windows安装
用于仿真的 MSYS2 verilator工具
用 MSYS2 实施形式化验证
OCI容器
在无网络的 Linux 环境中安装 SBT
创建第一个 SpinalHDL 项目
项目的目录结构
在 SpinalHDL 代码中使用 Spinal
在 CLI (命令行)中结合 SBT 使用 Spinal
在 VSCodium 中使用 Spinal
从 IntelliJ IDEA 使用 Spinal
Scala 使用指南
基础内容
类型
变量
函数
对象(Object)
入口点(main)
类
模板/类型参数化
编码规范
简介
类与样例类
交互
简介
SpinalHDL 在 API 隐藏后的工作原理
一切都是引用
硬件类型
生成的 RTL 中的信号名称
Scala 用于实例细化,SpinalHDL 用于硬件描述
Scala 实例细化能力(if、for、函数式编程)
Scala 使用指南
简介
VHDL 用户入门
与VHDL对比
简介
过程(Process)
隐式与显式定义对比
时钟域
组件的内部组织方式
安全性
功能与流程
总线和接口
信号声明
组件实例化
类型转换
调整位宽
参数化
元硬件描述
VHDL 等效语法
实体和架构
数据类型
信号
赋值
字面量(Literals)
寄存器
过程块
快速参考
Core
Lib
Symbolic
数据类型
Bool
描述
声明
运算符
逻辑运算
边缘检测
比较运算
类型转换
杂项
掩码布尔值
位
声明
运算符
逻辑运算
比较运算
类型转换
位提取
杂项
掩码字面量
UInt/SInt
声明
运算符
逻辑运算
算术运算
比较运算
类型转换
位提取
杂项
定点小数操作
低位运算
高位操作
fixTo 函数
SpinalEnum
描述
声明
编码
示例
运算符
比较运算
类型
类型转换
Bundle
描述
声明
条件信号
运算符
比较运算
类型转换
将位转换回线束
IO元件方向
in/out
master/slave
Vec
描述
声明
示例
运算符
比较运算
类型转换
杂项
库辅助函数
UFix/SFix
描述
声明
无符号定点小数
有符号定点小数
格式
示例
赋值
有效赋值
来自 Scala 常量
原始值
示例
运算符
算术运算
比较运算
类型转换
杂项
浮点小数
描述
IEEE-754 浮点小数格式
重新编码的浮动小数格式
声明
IEEE-754 编码数
重新编码的浮点数
运算符
类型转换
AFix
描述
声明
数学运算
不等式运算
位移操作
饱和与舍入
赋值
结构设计
组件和层次结构
输入/输出定义
裁剪信号
参数化硬件(VHDL 中的“Generic”,Verilog 中的“Parameter”)
综合后组件名称
Area
函数
RGB信号转灰度信号
Valid Ready Payload 总线
时钟域
简介
实例化
配置
内部时钟
外部时钟
生成 HDL 时的信号优先级
语境
跨时钟域设计
特殊计时逻辑区
慢时钟逻辑区
启动复位
复位时钟域
时钟使能逻辑区
实例化 VHDL 和 Verilog IP
描述
定义一个黑盒
泛型
实例化黑盒
时钟和复位信号的映射
io前缀
重命名黑盒中的所有io
添加 RTL 源
VHDL - 无数值类型
保留名称的方法
Nameable 基类
从 Scala 中提取名称
组件中的区域
函数中的逻辑区
函数中的复合区(Composite)
复合区级联链
在一个线束(Bundle)的函数中的复合区
Unnamed signal handling
Verilog 表达式分割
Verilog 长表达式分割
When 语句条件
最后一招
参数化
实例细化时参数
可选硬件
语义
赋值
位宽检查
组合逻辑环(Combinatorial loops)
CombInit
When/Switch/Mux
When
WhenBuilder
Switch
示例
其他选项
本地声明
Mux
按位选择
示例
规则
并发
最后有效赋值生效
信号和寄存器与 Scala 语言的协作(OOP 引用 + 函数)
时序逻辑
寄存器
实例化
复位值
用于仿真目的的初始化值
寄存器组
将线缆/信号转换为寄存器
RAM/ROM存储器
同步使能注意事项
写入时读取策略
混合位宽存储器
自动黑盒化
黑盒策略
标准存储器黑盒
设计错误
赋值覆盖(Assignment overlap)
简介
示例
跨时钟域违例(Clock crossing violation)
简介
示例
crossClockDomain标签
setSynchronousWith
BufferCC
组合逻辑环(Combinatorial loop)
简介
示例
误报
层次违例(Hierarchy violation)
简介
示例
IO线束
简介
示例
锁存器检测(Latch detected)
简介
示例
因多路复用器产生的错误
无驱动检测(No driver on)
简介
示例
空指针异常(NullPointerException)
简介
示例
问题说明
超出范围的常数(Out of Range Constant)
简介
示例
特殊情况
定义为组件输入的寄存器(Register defined as component input)
简介
示例
作用域违例(Scope violation)
简介
示例
Spinal无法克隆类(Spinal can’t clone class)
简介
例子1
例子2
未赋值的寄存器(Unassigned register)
简介
示例
只有初始化(init)的寄存器
无法访问的is语句(Unreachable is statement)
简介
示例
位宽不匹配(Width mismatch)
简介
赋值示例
运算操作示例
其他语言功能
实用工具
介绍
Cat
克隆硬件数据类型
将数据类型作为构造函数参数传递
老办法
安全的方法
频率和时间
二进制前缀
存根(Stub)
Assertions
Report
ScopeProperty
模拟信号和输入输出
简介
模拟信号
输入/出
输入/出包装器
手动驱动模拟线束
VHDL 和 Verilog 生成
从 SpinalHDL 组件生成 VHDL 和 Verilog
Scala 的参数化
来自 shell 的参数化
生成的 VHDL 和 Verilog
组织
组合逻辑
时序逻辑
VHDL 和 Verilog 属性
模块库
实用工具
免状态工具
全状态工具
计数器
超时
复位控制
特殊工具
Stream
规范
语义
函数
实用工具
StreamFifo
StreamFifoCC
StreamCCByToggle
StreamWidthAdapter(反压流位宽适应器)
StreamArbiter(反压流仲裁器)
StreamJoin
StreamFork
StreamMux
StreamDemux
StreamDispatcherSequencial
StreamTransactionExtender
仿真支持
Flow
规范
函数
代码示例
仿真支持
Fragment
规范
函数
状态机
简介
StateMachine
入口点
转换
状态编码
状态
StateDelay(状态延迟)
StateFsm
StateParallelFsm
关于入口状态的注释
VexRiscv(RV32IM CPU)
总线从端生成器
简介
功能
纤程框架
简单的示例
Handle[T]
soon(handle)
二进制系统
规范
String转为Int/Long/BigInt
Int/Long/BigInt转为String
Int/Long/BigInt转为二进制列表
二进制列表转为Int/Long/BigInt
BigInt放大器
RegIf
自动分配
28种访问类型
自动生成文档
特殊访问用途
字节掩码
典型例子
中断生成器
IP级中断生成器
SYS级中断合并
Spinal的生成器
示例
默认读取值
开发者区域
总线
AHB-Lite3
Configuration and instantiation
变体
Apb3
Configuration and instantiation
函数和运算符
Axi4
Configuration and instantiation
变体
函数和运算符
AvalonMM
Configuration and instantiation
Tilelink
Configuration and instantiation
tilelink.fabric.Node
顶层示例
GPIOFiber示例
RamFiber示例
CpuFiber示例
位宽适配器(WidthAdapter)示例
通信接口
SPI XDR
配置
软件驱动
串口
总线定义
UartCtrl
USB设备
架构
寄存器
描述符
用法
USB OHCI
用法
IO口
可读开漏IO(ReadableOpenDrain)
三态
三态
三态阵列
图形
颜色
RGB
VGA
VGA总线
VGA时序
VGA控制器
自动设计工具(EDA)
QSysify
示例
标签
添加新的接口支持
QuartusFlow
对于单个rtl文件
对于一个现有项目
Pipeline
简介
简单示例
Payload
Node
Links
DirectLink
StageLink
S2mLink
CtrlLink
其他链接
您的自定义链接
Builders
StagePipeline
StageCtrlPipeline
组合能力(Composability)
Retiming / Variable length
简单的CPU示例
杂项
Plic映射器
PlicMapper.apply
PlicMapping.sifive
PlicMapping.light
插件
简介
执行顺序
简单示例
联锁/排序
仿真
用于仿真的 SBT 设置
后台依赖的安装说明
GHDL 的设置和安装
Icarus Verilog 的设置和安装
VCS 仿真配置
Verilator 的设置和安装
启动仿真器
简介
配置
在同一硬件上运行多个测试
从线程中抛出仿真成功或失败结果
在失败之前捕获给定时间窗内的波形
仿真过程中访问信号
读写信号
访问组件层次结构内部的信号
仿真中内存的加载和存储
时钟域
激励函数API
等待相关API
回调函数API
默认时钟域
新时钟域
全线程API
分裂和合并仿真线程
休眠和等待
无线程API
敏感API
仿真器的具体细节
SpinalHDL 如何使用 Verilator 后端进行硬件仿真
SpinalHDL 如何使用 GHDL/Icarus Verilog 后端进行硬件仿真
SpinalHDL 如何使用 Synopsys VCS 后端进行硬件仿真
SpinalHDL 如何使用 Xilinx XSim 后端进行硬件仿真
性能
仿真引擎
示例
异步加法器
双时钟域FIFO
单时钟域FIFO
同步加法器
串口解码器
串口编码器
形式化验证
介绍
形式化验证后端
安装要求
示例
外部断言
内部断言
外部激励
更多关于断言/past(以前某个时钟内的状态)的例子
假设内存中的内容
实用工具和原语
断言/时钟/复位
指定信号的初始值
指定初始假设
内存内容(Mem)检查
在复位的时候进行断言检查,可以这样做
形式化验证的原语
局限性
命名策略
对于组件
对于实现 IMasterSlave的接口
示例
简单示例
APB3定义
简介
规范
实现
用法
进位加法器
颜色求和
带清零的计数器
锁相环黑盒和复位控制器
PLL BlackBox定义
TopLevel定义
RGB信号转灰度信号
正弦 ROM
中级示例
分形计算器
简介
规范
细化参数(泛型)
Bundle定义
组件实现
串口
规范
数据结构
实现
简单应用
带TestBench的例子
额外奖励:享受 Stream 带来的乐趣
VGA
简介
数据结构
VGA控制器
高级示例
JTAG TAP
简介
JTAG总线
JTAG状态机
JTAG TAP
Jtag指令
用户友好型包装
使用演示
内存映射UART
简介
规范
实现
Pinesec
插槽(Slots)
简介
计时器
简介
计时器
桥接函数
入门
历史遗留
RiscV
特性
基础FPGA项目
如何生成CPU VHDL
如何调试
Todo
pinsec
简介
简介
板级支持
硬件
简介
RISCV
AXI4
APB3
生成RTL
SoC顶层(Pinsec)
简介
定义所有IO
时钟和复位
主要组件
外设
总线互连
杂项
软件
RISCV工具链
OpenOCD/GDB/Eclipse配置
杂项
常见错误
“main”线程中异常 java.lang.NullPointerException
层次违例(Hierarchy violation)
Signal X can’t be assigned by Y
Input signal X can’t be assigned by Y
Output signal X can’t be assigned by Y
spinal.core
组件
时钟域定义
时钟域语法
时钟配置
外部时钟
跨时钟域设计
赋值
When / Switch
组件/层次结构
Area
函数
RGB信号转灰度信号
Valid Ready Payload 总线
VHDL生成
实例化 VHDL 和 Verilog IP
实用工具
Element
范围
开发者专区
总线从端(Factory)实现
简介
规范
实现
BusSlaveFactory
BusSlaveFactoryDelayed
AvalonMMSlaveFactory
结论
项目中如何使用本地的SpinalHDL克隆作为依赖
创建本地的SpinalHDL git 克隆
配置构建系统
配置 sbt (更新
build.sbt
)
配置 mill (更新
build.sc
)
完成
如何修改本文档
标题约定
Wavedrom 的集成
新章节
示例
通过Mill构建(输出)
编译SpinalHDL库
运行所有测试套件
运行指定的测试套件
运行指定程序(App)
本地发布
SpinalHDL 内部数据模型
简介
总体结构
探索数据模型
编译环节
在不使用插件的情况下,以用户身份修改网表
用户空间网表分析
遍历、枚举正在使用的每个时钟域
类型
简介
Bool
声明
运算符
BitVector 系列 - (
Bits
,
UInt
,
SInt
)
声明语法
运算符
掩码过滤结果比较
位
UInt、SInt
Bool, Bits, UInt, SInt
Vec
Bundle
简单示例(RGB/VGA)
接口示例(APB)
Enum
Data (Bool, Bits, UInt, SInt, Enum, Bundle, Vec)
使用字面量声明信号
用连续赋值字面量作来声明信号
SpinalHDL
历史遗留
在 GitHub 上编辑
历史遗留
RiscV
特性
基础FPGA项目
如何生成CPU VHDL
如何调试
Todo
pinsec
简介
简介
板级支持
硬件
简介
RISCV
AXI4
APB3
生成RTL
SoC顶层(Pinsec)
简介
定义所有IO
时钟和复位
复位控制器
每个系统的时钟域设置
主要组件
RISCV CPU
片上RAM
SDRAM控制器
JTAG控制器
外设
GPIO
计时器
UART控制器
VGA控制器
总线互连
AXI4桥接到APB3
AXI4交叉开关(crossbar)
APB3解码器
杂项
软件
RISCV工具链
OpenOCD/GDB/Eclipse配置