疯狂4004-用世界上第一个微处理器进行实验

2020-09-13 05:57:07

当我试图理解为什么我的Busicom 141-PF计算器的基于锁存器的实现在Spartan-6中实现时不能工作,我单独测试了i4001 ROM实现。它似乎起作用了,所以我把重点放在了i4004CPU上。现在我已经将i4004CPU切换回使用时钟触发器,我尝试了一个更广泛的测试。我实例化了一个CPU、一个ROM和一个RAM,并使用默认加载到i400x分析器中的基本功能测试加载了ROM。此测试从子例程调用和返回开始,然后在测试ALU函数之前检查条件跳转。我的目的是查看每个CLK1或CLK2脉冲是否有足够的触发器时钟边沿,以便根据需要传播所有内容。这是我最担心的通过ALU的路径。我首先从行为模拟开始,并注意到前几条指令按预期执行。这让我有信心尝试P&;R后的模拟,但失败了。然而,与最初的故障不同的是,放置在4位数据总线上的地址在000和001之间交替,而总线上的ROM地址似乎是正确的。但是,提供给包含指令的块RAM的地址始终为零。这表明i4001 ROM仿真不起作用。这对我来说毫无意义。我在P&P;R之后的模拟和真实的斯巴达-6中测试了基于闩锁的i4001,它似乎工作得很好,但当与其他模块结合使用时,它似乎失败了。在我作为一名专业软件工程师的职业生涯中,我有时会遇到一些代码,作者声称这些代码因为优化器中的一个错误而无法工作。现在,我发现了几个非常真实的编译器错误,但它们在常用编译器中极为罕见。这类问题几乎总是由程序员不理解语言的细微细节引起的,而不是由编译器中的错误引起的。考虑到这一点,我决定将i4001改回使用边缘时钟的触发器;这是我本来就想做的,但一直没有做到。当然,这件事很快就奏效了。我想我不会再玩这些芯片的锁存实现了。正如我以前说过的,我对这些芯片的边沿时钟触发器版本的问题是,最初的设计通常假设数据可以在单个CLK1或CLK2脉冲期间流经多个锁存器。由于数据只能通过时钟边沿上的触发器传播,因此CLK1或CLK2脉冲期间的时钟边沿必须多于串联触发器的数量。一个指令周期使用8级移位寄存器划分为8个子周期,这些寄存器产生单热输出(意味着任何时候只有一个输出有效,唯一标识子周期)。I4004中的移位寄存器是自初始化的,并产生同步信号输出,i4001和i4002中的移位寄存器使用该信号输出使自身与i4004中的移位寄存器同步。我没有在几个地方重复这个关键代码,而是将定时生成器和定时恢复逻辑都提取到单独的Verilog模块中。这允许我单独测试它们,并使用它们来测试其他模块。我的担忧之一是,使用边沿时钟触发器会导致发生器和恢复输出之间的时序出现一个时钟偏差。这将消耗CLK1或CLK2时钟脉冲内的触发器看到的时钟沿的数量,并导致数据不能及时到达或三态输出驱动器重叠。子周期定时信号响应于CLK1变为有效而改变。在我目前的设计中,CLK1(和CLK2)是触发器的输出。驱动CLK1的触发器响应于上升时钟沿而改变状态,因此落后时钟沿约一纳秒。这意味着子周期移位寄存器中的触发器不会改变状态,因为当时钟上升沿出现时,CLK1还没有改变。相反,子周期移位寄存器在下一个上升时钟沿改变状态,导致一个时钟周期时间的延迟。这又意味着,依赖于子周期定时信号的逻辑不会改变,直到之后的上升时钟沿,或者在引起CLK1改变的时钟沿之后的两个时钟沿。我的八个上升时钟边沿中的两个已经被消耗掉了。[编辑:它实际上只有一个时钟边沿。组合逻辑获得从CLK1脉冲变为有效到下一个要更新的时钟边沿之间的整个周期,但触发器在该时钟边沿出现之前不会对结果起作用。]。明白为什么我担心i4004和其他芯片的子周期信号之间可能出现周期偏差了吗?幸运的是,i4001和i4002中的移位寄存器与i4004中的移位寄存器具有相同的时序关系。因此,两个移位寄存器应该保持彼此同步。但在系列赛之后