编写指令集模拟器的主要步骤是什么?

发布于 2024-10-09 20:15:13 字数 194 浏览 6 评论 0原文

我将从事一个需要为特定指令集编写模拟器(可能不适用于真正的处理器)的项目。最好这个模拟器类似于 MIPS ISA 的 SPIM 模拟器。它将显示所有寄存器、内存位置等的内容,并让我逐步执行指令。是否有编写模拟器的标准步骤集?从哪里开始?

我了解 Java 和 C++,并且完成了两门计算机体系结构课程并在 3 人团队中工作。

I will work on a project which requires to write a simulator for a specific instruction set(that may not be for a real processor). Preferably this simulator will be something like SPIM simulator for MIPS ISA . It would show the contents of all the registers, memory locations etc, and let me step through instructions.Are there standard set of steps for writing simulators ? Where to start ?

I know Java and C++ and I finished two courses in computer architecture and working in a team of 3.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

跨年 2024-10-16 20:15:13

我想说你需要先使用反汇编程序。模拟器是反汇编程序的下一步。例如,x86(或其他可变字长指令集)反汇编器将需要跟踪代码的执行。首先,它必须根据操作码知道该指令使用了多少字节,其次这是一个分支,如果是的话,是什么类型,有条件或无条件,并做出相应的反应。模拟器除了模拟寄存器之外,还完成了所有这些工作。反汇编程序将用于教育目的,而不是在 sourceforge 上进行精美的发布。足以了解如何在位级别解析指令、计算跳转偏移量。

我将从一个简单的指令集开始,例如 12 位 pic 或 6502 或类似的指令集(msp430 是另一个可能的候选者)。如果您使用现有的指令集来学习如何编写模拟器,则可以利用该 isa 的现有工具链(汇编器,也许还有编译器)。将任务分成两半。对于新的指令集,如果您想手动编码机器代码,您在某些时候将需要一个工具链,或者至少需要一个好的反汇编器(反汇编器双重检查您是否拥有您认为想要的机器代码)。或者,您可以在模拟器中选择按执行顺序输出反汇编代码,无论如何都有利于调试。

首先不要担心中断,但请注意,您将需要一种机制来停止模拟流程、保存状态并在如此多的时钟周期内重新使用模拟器。您将看到很多模拟器基本上单步执行每条指令。由于周期性中断或需要与模拟处理器同步的其他模拟硬件的硬件原因,评估每条指令的时钟滴答数。因此,最好首先以这种方式进行建模,然后根据需要提出性能改进。

如果您还没有使用状态机进行编程,我强烈建议您了解一些状态机并编写一些练习程序。

我正在开展一个项目,我希望发布该项目,如果我完成的话可能会对此类主题有所帮助。我现在的指令集模拟器实际上是用硬件设计语言编写的(例如 verilog,不是我使用的 hdl,但它会转换为 verilog),然后使用类似 verilator 和 C/C++ 包装器的东西。因此,与提取操作码和位相关的工作是由专门用于管理该工作的语言来处理的。想要模拟外围设备或提供图形用户界面或其他方式显示正在发生的事情的部分由为此设计的语言处理。如果您碰巧正在从事一个在 vhdl 或 verilog 中实现新指令集的项目,我强烈推荐混合 hdl 模拟器加软件解决方案,如果它是商业 hdl 模拟器,则通过 VPI;如果您使用 verilator,则通过其他更简单的方法或 icarus verilog 或 ghdl 或其他。 (icarus可能需要像vpi这样的商业接口)。这里的美妙之处在于,您更接近真实的硬件,硬件中的错误/缺陷等可以在进入芯片之前找到并处理,硬件的更改或改进可以在模拟中立即实现,而不必进行匹配模拟器等方面的更改或改进。hdl 模拟器具有脚本语言或系统 C 等,这对于对硬件进行功能测试很有用,但无法在硅上运行它。如果您不鼓励使用这些工具并在模拟逻辑上运行真实的二进制文件,并为真实工具提供抽象层来加载、调试或监视(例如,向 openocd 编写后端以通过主机传递到 hdl sim 层并与芯片上的模拟 jtag 调试器进行对话,具体取决于此设计的复杂性(非常可行,因为我自己已经完成了))。这些真实的程序既可以在模拟中运行,也可以在硅片上运行,从而节省了编写测试的时间,并在硅片到达之前就编写好了测试软件,而不是在硅片到达之后才开始。

抱歉 HDL 切线。如果这是一个新的或没有工具链指令集的其他工具,您将不得不花时间在该工具链上,至少是一个汇编器和链接器,我会做某种反汇编器,然后将该反汇编器或其部分转换为第一个片段在模拟器上。就我在指令集模拟器中看到的标准事物而言,基本上是从单步角度考虑,以便您可以处理时钟和中断以及其他模拟硬件。模拟的核心功能要么模拟一个可能不是完整指令的时钟周期(状态机方法),要么核心功能模拟单个指令并返回按指令要求修改寄存器、标志和内存(并对模拟时钟进行计数) )。根据您希望该模拟器从一开始就实现的功能丰富程度,您可以读写 ram/rom 和寄存器功能,以便您可以在一个地方捕获内存和寄存器更改以显示给用户。仅通过这些抽象函数访问或至少修改寄存器和RAM。除此之外,它只是大量的输入,指令集越复杂,指令越多,需要输入的代码行就越多。

I would say you need to work on a disassembler first. The simulator is the next step beyond a disassembler. For example an x86 (or other variable word length instruction sets) disassembler would for need to follow the execution of the code. First it has to know based on the opcodes how many bytes are used by that instruction, second is this a branch and if so what kind, conditional or unconditional and react accordingly. The simulator does all this plus it simulates the registers. The disassembler would be for educational purposes, not a polished publish on sourceforge thing. Just enough to get the feel for how to parse the instructions at the bit level, compute jump offsets.

I would start with a simple instruction set like the 12 bit pic or 6502 or something like that (msp430 is another possible candidate). If you go with an existing instruction set for learning how to write the simulator, you can capitalize on the existing toolchains (assemblers and maybe compilers) for that isa. Divide the task in half. For a new instruction set you will need a toolchain at some point or at least a good disassembler if you want to hand code the machine code (the disassembler double checks you have the machine code you thought you wanted). Or you could have an option in the simulator to output disassembled code in execution order, good for debugging anyway.

Dont worry about interrupts at first, but be aware that you are going to need to have a mechanism for stopping the flow of the simulation, save state and re-use the simulator for so many clock cycles. You will see a lot of simulators essentially single step each instruction. Evaluating the number of clock ticks on each instruction for hardware reasons either for periodic interrupts, or other simulated hardware that needs to be in sync with the simulated processor. So it would be a good ideal to start by modelling yours that way and then coming up with performance improvements later as needed.

If you have not programmed using state machines I highly recommend learning a little about them and writing some practice programs.

I am working on a project I hope to publish that if I ever finish may help with topics like this. My instruction set simulators these days are actually written in a hardware design language (verilog for example, not the hdl I use but it converts to verilog) then use something like verilator with a C/C++ wrapper. So the work related to extracting opcodes and bits is handled by a language designed to manage just that. And the parts that want to simulate peripherals or provide guis or other ways of displaying what is going on are handled by a language designed for that. If you happen to be working on a project where this new instruction set is realized in vhdl or verilog I highly recommend a hybrid hdl simulator plus software solution either through VPI if it is a commercial hdl simulator or through other simpler methods if you go with verilator or icarus verilog or ghdl or others. (icarus may need the commercial like vpi interface). The beauty here is that you are closer to the real hardware, bugs/warts, etc in the hardware can be found and dealt with before going to silicon, changes or improvements in the hardware are instantly realized in the simulation instead of having to make matching changes or improvements in the simulator, etc. The hdl simulators have scripty languages, or system C, etc, which are fine for getting the hardware functionally tested but you cant run it on silicon. If you discourage the use of these tools and have real binaries run on the simulated logic, and provide an abstraction layer to real tools to load or debug or monitor (for example write a back end to openocd to pass through the host to hdl sim layer and talk to the simulated jtag debugger on the chip, depending on the complexity of this design(quite doable as I have done it myself)). These real programs can be run both in simulation and on silicon, saving time in writing tests, and getting test software written well before silicon arrives instead of starting after it arrives.

Sorry for the HDL tangent. If this is a new or otherwise without toolchain instruction set you are going to have to spend time on that toolchain, at least an assembler and linker and I would do some sort of disassembler and then turn that disassembler or portions of it into the first cut at the simulator. As far as standard things I have seen in instruction set simulators, basically think in terms of single stepping so that you can handle clocks and interrupts and other simulated hardware. the core function of the simulation either simulates one clock cycle which may not be a complete instruction (a state machine approach) or the core function simulates a single instruction and returns modifying registers, flags and memory as demanded by the instruction (and counting simulated clocks). Depending on how feature rich you want this simulator from the very beginning make your reads and writes of ram/rom and registers functions so that you can in one place trap memory and register changes for displaying to the user. Only access or at least modify registers and ram through these abstract functions. Beyond that it is just a ton of typing, the more complicated the instruction set, the more instructions the more lines of code to type.

霓裳挽歌倾城醉 2024-10-16 20:15:13

第一步是为您的 CPU 创建一个汇编程序。汇编器与模拟器没有任何关系,在我看来,在模拟器中包含汇编解析器会使事情变得不必要的复杂化。

使用单独的汇编器可以保持模块化,并且允许您的模拟器将简单的二进制代码作为输入 - 您甚至可以单独创建、验证和修改这些代码。也是符合现在的做法的。

至于你的模拟器,在 Google 中搜索编写 CPU 模拟器这个 作为第一次点击,还有很多更有趣的结果。

The first step would be to create an assembler for your CPU. The assembler has no relation whatsoever to the simulator and in my opinion including an assembly parser in the simulator would needlessly complicate things.

Using a separate assembler keeps things modular and it allows your simulator to have simple binary code as its input - code that you can even create, verify and modify separately. It is also in accordance with the current practices.

As for your simulator, searching Google for writing a CPU simulator has this as a first hit and there are quite a few more interesting results.

橘味果▽酱 2024-10-16 20:15:13
  1. 起点是指令集本身&处理器的内部架构[有时称为“编程模型”]和寻址模式有哪些。
  2. 全面了解每条指令的预期功能[在处理器内]和处理器预计将向内存或 I/O 端口发送什么输出 为该指令
  3. 设计机器代码指令的指令格式:指令的机器代码中应有多少位/字节;其中,需要确定多少位构成操作码、多少位用于指示寻址模式、多少位用于指示操作数[寄存器、数据或地址]等。还决定顺序和这些位组的组合。您保留总数会很方便。机器代码指令中的位数为 8 的倍数[即大小为 1 或 2 或 3 字节的机器代码指令对 u 来说比 12 位或 17 位更方便]。
  4. 在模拟器软件中[你可以用c/cpp/java或任何你最喜欢的语言编写],你将分配变量来表示CPU的内部寄存器; ALU 的工作将由 SW 中的功能来完成;您的软件将从二进制/ascii-hex 文件中读取机器代码指令;每条指令都根据不同位组的指示进行分析];然后根据这些指示调用必要的函数。
  5. 为模拟器软件设计一个良好的用户界面。我想您可能会使用模拟器进行演示/教学/培训。显示 sw 的动作 [CPU 内部发生的动作],因为动作正在进行;例如,当从堆栈内存位置或寄存器写入或读取数据时,您可以显示这些位置。它将有助于用户更好地了解CPU操作。更重要的是,它将帮助您在开发/测试模拟器软件时轻松定位错误。
  1. the starting point is the instruction set itself & the internal architecture of the processor [sometimes called 'prograaming model'] & what are the addressing modes.
  2. thorough knowledge of what each instruction is expected to do [inside the processor] & what output the processor is expected to send out [to memory or i/o port] for that instruction
  3. design an instruction format for the machine code instruction: how many bits/bytes should be there in the machine code of the instruction; out of that, how many bits constitute the opcode, how many bits for indicating the addressing mode, how many bits for indicating the operand [register, data or address] etc. have to be decided. also decide the order & combinations of these groups of bits. It will be convenient for u to keep the total no. of bits in the machine code instruction as a multiple of 8 [that is a machine code instruction whose size is 1 or 2 or 3 bytes is more convenient for u than 12 bits or 17 bits].
  4. in the simulator software [which u may write in c/cpp/java or whatever is your favourite language], u will be assigning variables to represent the cpu's internal registers; the job of ALU will be done by the functions in your SW; your SW will read the machine code instructions from a binary/ascii-hex file; each instruction is to analysed based on what the different groups of bits indicate]; then call the necessary function(s) based on these indications.
  5. design a good user interface for the simulator sw. I guess u will probably use the simulator for demo/teaching/training. display the actions of the sw [the actions going on inside the cpu] as the actions are in progress; for example, u may display the stack memory locations or the registers when data is written or read from these locations. it will help in better understanding of the cpu operations by the users. more important, it will help u when u develop/test the simulator sw, to easily locate mistakes.
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文