5个版本 (3个重大变更)
使用旧的Rust 2015
0.5.0 | 2017年1月1日 |
---|---|
0.4.0 | 2016年12月31日 |
0.2.0 | 2016年11月4日 |
0.1.0 | 2016年8月18日 |
#769 in 硬件支持
250KB
1.5K SLoC
hoodlum (alpha)
hoodlum 是一个看起来很不错的硬件描述语言,可以编译成Verilog。它想添加更强的类型保证和高级概念,如枚举(以及结构体/typedefs),同时也要使FPGA设计更容易、更有趣。要开始
cargo install hoodlum
将以下内容添加到名为 blinky.hdl
的文件中
entity Main {
in clk: bit,
out LED1: bit,
}
impl Main {
def mut index: uint{..6000000};
on clk.posedge {
if index == 6000000 - 1 {
index <= 0;
LED1 <= !LED1;
} else {
index <= index + 1;
}
}
}
然后运行
hoodlum blinky.hdl -o output.v
教程和示例针对 $20 iCEstick 评估板和 IceStorm开源编译器工具链。参见 "examples/blinky" 中的简单闪烁灯示例。
注意: 我在前进的过程中学习Verilog和VHDL。请随意在问题部分提出想法和最佳实践!
示例
- examples/blinky — 使用计数器开/关LED。iCEstick评估板示例。
- examples/sequence — 显示通过
sequence
生成器编译的LED显示模式。 - examples/ntsc — 生成NTSC视频并显示静态图像。需要外部电路。
- examples/ethernet — 控制编码器
enc424j600
的以太网PMOD板以发送UDP数据包。需要enc424j600 PMOD板。
在 iCEstick评估套件 上运行
每个示例都有一个Makefile,允许您运行
make && make flash
如果您在macOS上遇到设备未找到的错误,请尝试先运行此命令来卸载本机FTDI驱动程序
sudo kextunload -b com.apple.driver.AppleUSBFTDI
Atom高亮插件
您可以在Atom中高亮显示 .hdl
脚本。运行以下命令来安装Atom插件
cd language-hoodlum
apm link --local .
hoodlum教程
Hoodlum脚本由实体定义组成,在 entity
块中,逻辑定义在 impl
块中。最顶层的实体是 Main
块。
entity Main {
in clk: bit,
out LED1: bit,
}
这些顶级条目引用了您的 .pcf
文件中的引脚定义;请参见 "examples/blinky/icestick.pcf",其中包含iCEstick评估板的示例。
每个这些实体成员都声明
- 方向:
in
表示值将由实体 读取,而out
表示值将由实体 写入。 - 名称。这可以在
impl
块中通过名称引用。 - 类型。在这里,我们声明这两个值都为
bit
宽,即逻辑值为0
或1
(或在更复杂的逻辑中为x
)。
在相应的 impl
块内部,我们可以引用这些值
impl Main {
def mut toggle: bit;
def toggle_next: bit = !toggle;
on clk.negedge {
toggle <= toggle_next;
}
LED1 = toggle;
}
让我们逐步分析。首先,我们定义一个名为 "toggle" 的变量,它是一个位宽的变量。我们将其声明为 def mut
,这意味着变量在 on
块内部是可变的。
接下来,我们定义一个名为 "toggle_next" 的变量,它 不是 可变的。这意味着我们有一个无状态的定义,不需要状态(锁存器或触发器)。我们可以在定义中直接声明它的值,或者作为单独的声明。它的值始终等于 "toggle" 变量的反值。
on
块对信号值的上升沿或下降沿敏感。在 on
块内部,我们可以使用非阻塞的 <=
或阻塞的 :=
操作符对可变变量进行赋值。在这里,每次我们看到负时钟沿,我们将 "toggle" 锁存器重置为 "toggle_next" 的值,即其自身的反值。
(非阻塞定义将在 on
块的末尾进行,这简化了有状态逻辑,使其在同一个时钟脉冲上设置。)
最后,我们声明输出变量的值。将 LED1
设置为始终等于可变 "toggle" 的值。
在 12MHz 时,您将看不到 LED 以此速度闪烁!有关如何使用计数器使其可见的说明,请参阅 "examples/blinky/blinky.hdl"。
类型
每个定义都有一个类型,用以下格式声明:def [mut] name: <type>
。
bit
声明一个可以存储0
、1
或x
的值。bit[n]
声明一个 n 位宽的端口。您可以使用切片操作符(例如myvariable[1]
)引用单个位,并使用数值字面量(例如myvariable = 0b101101
等)一次性设置它。uint{..n}
和int{..n}
声明整数(无符号和有符号),其最大值为n
(到最近的 2 的幂)。这是计算给定整数的最大位长度的简写。
在实体内部,您还可以定义子实体
entity Toggle {
in value: bit,
out opposite: bit,
}
impl Toggle { ... }
entity Main { ... }
impl Main {
def clk_prime: bit;
def toggle = Toggle {
value: clk,
opposite: clk_prime,
}
}
Main 声明一个子实体 Toggle,它有一个输入值 "clk" 和一个输出值 "clk_prime"。请注意,您需要与子实体一起声明输出变量才能使用它们。
贡献
在任何问题追踪器中提出任何问题、讨论、想法或错误。
语言设计目标
目标
- 定义一种优雅的硬件描述语言,借鉴Rust语法和其他现代(熟悉)语言的语法。
- 生成兼容的Verilog-2001(和VHDL)代码。
- 创建抽象,简化状态机、顺序代码和复位状态的生成。
- 可修改性高,以便您可以添加自己的构造。
- 在它们达到综合阶段之前,静态检测错误。
- 未来,添加仿真功能。
非目标
- 不将Rust编译成HDL。Rust的stdlib适合完全不同的计算模型。抽象不匹配使得代码难以调试。
- 不支持编译Verilog-2001或VHDL的所有功能,仅支持功能子集。
许可
MIT或Apache-2.0。
依赖
~5MB
~92K SLoC