如何用Python模拟硬件?

如何用Python模拟硬件?,python,mips,Python,Mips,有点让人困惑,但我的任务是用高级语言编写一个4阶段的MIPS处理器(IF、ID、EX、WB)(我可能最了解python)。除了我还没有开始尝试缓存和暂停的困难之外,您如何处理应该并行运行的代码并使其按顺序运行?考虑这个代码片段。 pc = 0x0 IFinput, IDinput, EXinput, WBinput = None, None, None, None while True: IFinput = self.memory.getInstruction(pc) if no

有点让人困惑,但我的任务是用高级语言编写一个4阶段的MIPS处理器(IF、ID、EX、WB)(我可能最了解python)。除了我还没有开始尝试缓存和暂停的困难之外,您如何处理应该并行运行的代码并使其按顺序运行?考虑这个代码片段。

pc = 0x0
IFinput, IDinput, EXinput, WBinput = None, None, None, None
while True:
    IFinput = self.memory.getInstruction(pc)
    if not IFinput: #No more instructions
        break

    self.IF.giveInput(IFinput)
    self.ID.giveInput(IDinput)
    self.EX.giveInput(EXinput)
    self.WB.giveInput(WBinput)

    instruction += 0x4
    clock += 1

    IDinput = self.IF.getOutput(clock)
    EXinput = self.ID.getOutput(clock)
    WBinput = self.EX.getOutput(clock)
    result  = self.WB.getOutput(clock)
result.printToFile()

我试图将输入和输出分为两个不同的阶段,这样我就不会在“clock+=1”命令执行之前通过获取输出来“欺骗”硬件。这是实现这一目标的正确方式吗?是否有适合此任务的python库?谢谢。

你就快到了。函数名有点混乱-我更喜欢
capture()
update()
memory.getIstruction()
肯定会隐藏在
IF.capture()
中(如果任务是获取指令,对吧?)。PC更新似乎也属于IF阶段

“不再有指令”的情况在现实生活中不会发生,应该放弃。打破循环的一个正确方法是在后台引发异常(例如,在来自非法范围的保留指令上;请记住,其他异常可能也将合法引发)


否则,作为一个起点看起来不错

评论中建议使用一些特殊用途的语言,如VHDL或其他语言,但我想对于一些简单的练习,速度可能并不重要,使用Python是非常好的

你的代码看起来几乎没问题,我只是不明白为什么你的
getOutput
函数需要
clock
作为输入,因为假定块的功能是时不变的,只依赖于它的输入。我认为您需要做的唯一技巧是为处理器中存在的每个寄存器制作两个版本,一个表示当前状态,另一个表示单击勾选后的状态。所有模拟硬件的功能应仅使用“当前”寄存器作为输入,并将其输出保存到“下一个”寄存器。然后在循环结束时,将所有下一个寄存器复制到当前寄存器中,然后重新开始。大概是这样的:

pc = 0
IF2ID_cur, ID2EX_cur, EX2WB_cur = 0 # values of registers after a reset

while True:
    instruction = memory[pc]
    IF2ID_nxt = simulate_IF(instruction)
    ID2EX_nxt = simulate_ID(IF2ID_cur)
    EX2WB_nxt = simulate_EX(ID2EX_cur)
    result =    simulate_WB(EX2WB_cur)

    pc += 1
    IF2ID_cur, ID2EX_cur, EX2WB_cur = IF2ID_nxt, ID2EX_nxt, EX2WB_nxt

请注意,通过这种方式,所有“模拟”功能仅使用当前寄存器值,而不使用下一个时钟周期的任何值。因此,您可以在不更改结果的情况下更改它们的执行顺序,就好像它们都并行运行一样。

考虑特定用途的语言,如VHDL或Verilog;可能带有组合/扩展名,如或

。。但是,如果必须从头创建和/或纯Python实现,请考虑使用与高级硬件语言相同的概念。特别是,考虑反应性设计。Verilog和VHDL都支持这个概念,即对输入(如时钟)的更改驱动行为和新的输出状态

然后,每个“反应式回调”只接收输入状态并发出与其他组件隔离的特定输出状态。然后,依赖关系仅由状态更改和围绕更改的反应触发器建立

触发器/防护装置中可能使用的内容:

  • 行或数据更改状态
  • 信号事件
  • 循环计数(例如,最小、之后、随机)

考虑特定用途的语言,如VHDL或Verilog;可能与诸如@user2864740之类的组合/扩展一起使用。虽然我很想使用硬件语言,但我正在使用的服务器(我没有根目录)不包括以下任何一项:(羞耻。那么[local]呢虚拟机/环境运行任何合理完成任务所需的工具?无论如何-如果我从零开始,并尝试用“通用”高级语言模拟硬件线路,我可能会围绕“反应式”设计系统时钟滴答作响。由于它是一个原始的模拟器,我不会考虑任何形式的并发或并行,除此之外。确保不要对分配/任务读太多。传递时钟以“获取结果”的原因是否产生结果取决于经过了多少个周期?例如,如果一条指令在5时进入EX阶段,那么它将需要2-20个周期,这取决于它的a ALU op、FP op等。此外,我不能确切地确定事情将在何时完成,因为即使在EX操作“完成”之后,它可能会在等待WB端口释放时暂停。啊,你没有这么说,我假设所有阶段都是单周期的。但如果是这样,你可以为每个项目添加一个具有适当长度的队列,而无需传递绝对时钟数。@SetLapshot我真的会研究反应式设置,即仅在ce上执行的回调确定条件(如时钟上的线路状态或x滴答声后)。有一个被调用的子代正在积极维护,并提供各种优势和改进-例如,它与VHDL和Verilog一起工作。值得考虑新的设计。