在硬件中格式化串行数据流

作者利用 Haskell 的 Clash 框架在 FPGA 上构建 Sudoku 求解器,重点解决了如何将串行数据流格式化为易读的网格输出。文章深入探讨了状态机设计,从简单的定制状态类型演进到使用类型级组合子(Type-level Combinators)实现声明式格式化。通过定义 Forward、Concatenation 和 Repetition 等类型类实例,作者展示了一种在硬件描述中复用软件设计模式的方法,最终实现了紧凑且高效的 Verilog 生成代码。这对熟悉函数式编程和硬件描述的工程师具有很高的参考价值。
评论点赞收藏733 天前

极限编程的终章:HomeLab-2 移植中的磁带加载陷阱与底层调试

作者回顾了在 RetroChallenge 中将一款老游戏移植到 HomeLab-2 的过程。核心亮点在于调试环节:开发时直接注入内存运行正常,但生成磁带 WAV 文件提交时却崩溃。作者深入分析了 HomeLab-2 的固件机制,发现是因为磁带加载方式覆盖了用于处理键盘输入的内存向量,导致游戏陷入死循环。修复方法简单但极具针对性。文章展示了极客式的底层调试思维、对复古硬件架构的理解以及从踩坑到最终获奖的完整经历,非常适合喜欢系统编程和复古计算的读者。
评论点赞收藏1020 天前

极限压缩:在16KB内存限制下重构文字冒险游戏的工程实战

作者回顾在RetroChallenge中开发16KB内存限制下的文字冒险游戏的过程。核心挑战是如何在截止日前将22KB的游戏压缩至16KB以内。作者分析了两种策略:删除内容可能破坏谜题连贯性,因此选择将游戏剧情从中间切断作为结局。通过详细解析字节码结构和地图可达性,作者展示了如何精准移除后半段场景和脚本以节省空间,同时保留核心玩法。最终成功实现游戏状态保存功能,但最后一天的测试部署过程充满波折。文章提供了极具价值的嵌入式系统资源优化实战经验和工程思维。
评论点赞收藏1023 天前

一个宏大的冒险构想:在 16KB 内存上重跑经典 C64 文字冒险游戏

作者计划将经典的 Commodore 64 文字冒险游戏移植到内存仅 16KB 的 HomeLab-2 硬件上。由于原版游戏数据远超目标容量,作者正在探索通过自定义字节码解释器和字符压缩技巧来精简数据。文章详细记录了从逆向工程背景到当前遇到的内存瓶颈及初步优化方案,属于硬核复古计算的一手工程实践记录。
评论点赞收藏1026 天前

让HomeLab-2初具雏形:我的复古硬件游戏开发实战

作者参与HomeLab-2游戏开发挑战,使用Z80汇编和Haskell作为汇编器。先尝试了Snake游戏,利用LFSR实现屏幕过渡效果。随后开发2048游戏,遇到性能瓶颈,采用双缓冲技术解决画面闪烁问题。由于时间紧迫,第三款游戏未能完成,将在后续文章中介绍。
评论点赞收藏1029 天前

HomeLab-2是什么?从零构建复古匈牙利家用电脑模拟器

作者介绍了一款鲜为人知的匈牙利产80年代家用电脑HomeLab-2。由于现有模拟器存在缺陷且不开源,作者在参加游戏开发限时赛的压力下,先用JavaScript快速手写了一个能用的Web版模拟器,随后又因追求类型安全和工程规范,用Idris 2重写了第二个更严谨的模拟器。文章详细描述了该电脑基于Z80、视频信号由CPU位踢产生导致性能受限的技术细节,以及逆向工程硬件行为来完善模拟器的过程。
评论点赞收藏1032 天前

又是一年 RetroChallenge:我的 HomeLab 复古计算挑战之旅

作者受匈牙利复古计算机 HomeLab 启发,决定参加 RetroChallenge 比赛。他计划先开发小游戏熟悉系统,然后在比赛中完成一个更完整的项目,并后续分享开发过程、自写的模拟器以及汇编游戏代码。这是一篇关于个人复古计算项目经历的预告。
评论点赞收藏1034 天前

面向浏览器的函数式语言性能基准测试

作者为了在浏览器里写一个 MOS 6502 模拟器,对比了多种函数式语言生成代码的性能。测试包括 PureScript、Idris 2、Asterius (GHC/Wasm) 以及作为基线的原生 JavaScript。结果显示 Idris 2 性能最好,接近原生 JS,而 PureScript 和 Asterius 较慢且包体积大。后来作者又补充了 ReScript 测试,发现 ReScript 性能最佳,但开发体验因缺乏类型驱动运算符解析而痛苦。这是一篇典型的工程实测与踩坑记录,对关注前端函数式编程选型的技术人员有直接参考价值。
评论点赞收藏1505 天前

廉价且高效的微代码压缩技术

作者通过一个单词字典的例子,详细讲解了如何压缩CPU微代码以节省FPGA资源。从固定长度存储到终止符,再到链表和公共后缀消除,逐步优化存储效率。最终利用Haskell实现了一个后缀树压缩算法,将Intel 8080微代码体积减少了约80%,展示了理论算法在硬件设计中的实际应用价值。
评论点赞收藏1566 天前

在 MOS 6502 上运行 Rust:超越斐波那契数列

作者尝试在 Commodore 64 (MOS 6502 架构) 上使用 Rust 和 LLVM-MOS 后端运行 CHIP-8 模拟器。文章详细记录了从可行性验证、集成核心引擎到处理磁盘 IO 的全过程。亮点在于展示了现代编译器在复古硬件上的实际表现:虽然能跑通,但生成的汇编代码极其冗长低效,导致实时游戏性能不足,仅适合回合制游戏。这是一篇典型的硬核工程实践记录,提供了关于 LLVM-MOS 现状的一手经验和具体踩坑细节。
评论点赞收藏1792 天前

用 Clash 在 FPGA 上构建运行 Tiny BASIC 的微型计算机

作者用 Haskell 的硬件描述语言 Clash,在 FPGA 上从零构建了一台运行 Tiny BASIC 的 Intel 8080 计算机。文章详细拆解了核心设计思路:通过抽象接口灵活对接 UART、PS/2 键盘或 VGA 屏幕;利用类型系统优雅处理 CPU 信号转换;以及使用组合子实现精确的地址解码和内存映射。这是一篇典型的硬核复古计算工程实践,展示了如何用现代函数式编程思想重构底层硬件逻辑。
评论点赞收藏2097 天前

一种“强类型”容器,用于表示微代码

作者为Clash硬件描述语言书籍开发Intel 8080 CPU核心时,遇到微代码描述的难题:既要方便人类阅读(包含前导和后处理步骤),又要保证底层执行时读写地址不冲突。作者利用Haskell的高级类型系统(Type Families, Singletons, GADTs),设计了一种名为Amble的类型容器。该容器在编译期静态检查相邻微指令步骤的地址访问兼容性,防止读写冲突,并提供清晰的自定义报错信息。此外还实现了长度追踪以适配FPGA综合限制。这是一篇展示如何用类型系统解决底层硬件建模中具体工程问题的优秀技术文章。
评论点赞收藏2160 天前

通过符号执行解决文字冒险游戏

作者受Martin Lester演讲启发,在Haskell中从零实现了一个Scott Adams文字冒险游戏引擎,并利用SBV库将其转化为符号执行问题。通过将用户输入设为自由变量,使用SMT求解器自动寻找通关路径。文章详细记录了从解释器实现、符号状态管理到发现并修复SBV底层Bug的全过程,最终成功让Z3求解器在几分钟内解出教程关卡的最优解。这是一篇典型的硬核工程实践分享,结合了形式化验证与复古游戏,对关注Haskell、SMT求解及符号执行的开发者极具参考价值。
评论点赞收藏2205 天前

通过 Cabal 将 Verilator 与 Clash 集成

作者分享如何将 Haskell HDL 编译器 Clash 与 Verilog 模拟器 Verilator 无缝集成到 Cabal 构建流程中。由于 Clash 生成的电路在纯 Haskell 模拟中性能较差,而 Verilator 速度快,作者开发了一个名为 Clashilator 的工具。核心难点在于解决构建依赖循环:必须先编译 Haskell 代码生成 Verilog,再用 Verilator 生成 C++ 库,最后链接回 Haskell。作者通过深入阅读 Cabal 内部文档,编写自定义 Hook 脚本,在构建过程中自动执行这些步骤,消除了手动配置 Makefile 和链接标志的样板代码,实现了自动化的一体化构建体验。
评论点赞收藏2291 天前

在CλaSH中实现可组合的CPU描述及RetroChallenge 2018/09总结

作者分享在CλaSH(Haskell的FPGA DSL)中描述CPU状态机的经验。起初直接写状态转换函数导致代码混乱,尝试使用State Monad和Lenses改善可读性,但在处理组合输出(如声音支持)时发现难以将局部修改合并到全局输出中。最终采用RWS Monad(Reader-Writer-State)模式,利用Writer轴收集对输出的修改(Endo函数),实现了更清晰的模块化设计。文章还探讨了未来方向,如引入ContT的可能性,并总结了RetroChallenge 2018/09的经历:成功在FPGA上运行CHIP-8模拟器,但意识到编写详细博客的时间成本过高,计划下次挑战减少未知因素。
评论点赞收藏2876 天前

在CλaSH中对CPU进行建模

作者使用CλaSH(一种用于FPGA的Haskell子集)来建模CHIP-8 CPU。文章详细描述了如何将CPU内部状态(寄存器、栈、相位)定义为Haskell数据类型,以及如何定义输入输出接口。核心难点在于处理多周期指令(如清屏),通过引入“相位”状态机来管理时序。作者指出直接编写状态转换函数会导致代码难以维护,并预告下一篇文章将介绍更优雅、可组合的CPU描述方法。
评论点赞收藏2883 天前

重返赛场:绕过 Xilinx ISE 缺陷完成 FPGA CHIP-8 实现

作者在进行 CHIP-8 FPGA 实现时遭遇 Xilinx ISE 综合器的内部 Bug,导致代码无法编译。在更换硬件来不及的情况下,他通过切换目标芯片型号(从 Spartan 6 到 Spartan 3E)并调整 CλaSH 编译器参数,成功绕过综合器缺陷完成项目。文章深入探讨了 FPGA 开发生态中闭源工具的局限性、开源工具链(如 Yosys、IceStorm)的现状与挑战,以及 CλaSH 在生成高效 HDL 方面的不足。这是一篇典型的硬核工程调试记录,包含大量关于 FPGA 选型、工具链对比和硬件描述语言实践的一手经验,对从事嵌入式、FPGA 开发及开源硬件感兴趣的读者具有极高的参考价值。
评论点赞收藏2884 天前

CλaSH CPU 的高级软件模拟方案

作者分享了一种在软件层面直接测试 CλaSH 编写的 CHIP-8 CPU 的方法。核心思路是利用 CλaSH 中 Mealy 机类型的纯粹性,绕过硬件信号模拟,直接在 Haskell 中运行 CPU 逻辑。通过将内存和帧缓冲映射到 IOArray,并结合 SDL 处理图形渲染和键盘输入,实现了无需综合即可在 PC 上交互式运行和调试 FPGA 逻辑。这种方法不仅简化了开发流程,还保留了便于调试的 trace 功能,体现了 Haskell 类型系统在硬件描述中的独特优势。
评论点赞收藏2891 天前

用 CλaSH 实现 PS/2 键盘接口

作者使用 Haskell 的硬件描述方言 CλaSH 实现了 PS/2 键盘接口。文章详细讲解了同步串行信号的采样、去抖、以及 11 位数据包的解析逻辑。接着处理了 PS/2 扫描码(Scan Codes)的解析难点,包括扩展键和释放键的特殊字节序列。最后将键盘输入与之前的 VGA 视频驱动结合,在 FPGA 上实现了一个可通过方向键移动的像素点。作者在调试过程中还发现并绕过 CλaSH 的一个时钟域类型级参数冗余问题,借此强化了类型系统的静态约束。
评论点赞收藏2898 天前

用 CλaSH 在 FPGA 上生成 VGA 信号:从原理到实战排错

作者使用 Haskell 的硬件描述方言 CλaSH 在 FPGA 上实现 VGA 视频信号生成器,以运行 CHIP-8 模拟器。文章详细讲解了 VGA 时序原理、CHIP-8 分辨率缩放策略,并展示了核心代码。特别提到了一个真实的调试经历:因时钟管理器配置错误导致信号异常,最终通过 LED 闪烁测试发现并解决。这是一篇结合了理论、代码和实战排错经验的硬核技术博文。
评论点赞收藏2904 天前

RetroChallenge 2018:用 CλaSH 在 FPGA 上实现 CHIP-8

作者计划参加 RetroChallenge 2018,使用 CλaSH(一种将 Haskell 编译为硬件描述语言的编译器)在 FPGA 上实现 CHIP-8 虚拟机。文章介绍了 CλaSH 与传统的 Haskell HDL(如 Kansas Lava)的区别,解释了 CHIP-8 的基本规格及其作为入门项目的优势,并详细列出了开发计划:先从外部 IO(VGA 显示和 PS/2 键盘)入手,再实现 CPU 核心,最后尝试声音输出等扩展功能。这是一篇典型的工程师项目规划与技术选型分享。
评论点赞收藏2908 天前

Rust 在 AVR 上的应用:超越点灯

作者尝试在 AVR 微控制器上使用 Rust 重写 CHIP-8 模拟器。由于当时 Rust/LLVM 对 AVR 支持尚处于早期阶段,存在编译器 Bug 和核心库无法编译等问题。作者详细记录了从构建自定义精简版 libcore、处理中断、调试模拟器到修复 LLVM/Rust 编译器 Bug 的全过程。这是一篇典型的底层系统编程实战分享,包含大量工程细节和踩坑经验,对关注嵌入式 Rust 和编译器开发的读者有较高参考价值。
评论点赞收藏3382 天前

登录芦苇

登录后关注作者、收藏内容和参与讨论。