How Do You Simulate Hardware In Python?
Solution 1:
You are almost there. The function names are a bit confusing - I'd prefer capture()
and update()
instead. memory.getIstruction()
shall definitely be hidden inside IF.capture()
(IF job is to fetch an instruction, right?). PC update also seem to belong to IF stage.
A "no more instructions" condition doesn't happen in real life, and shall be abandoned. A right way to break the loop is EX stage to raise an exception (say, on a reserved instruction from an illegal range; keep in mind that other exceptions may and will be raised legitimately).
Otherwise, looks good as a starting point.
Solution 2:
It was suggested in the comments to use some special purpose language like VHDL or so, but I guess that for some simple exercise, where speed probably does not matter, using Python is perfectly fine.
Your code looks almost ok, I just don't understand why your getOutput
functions need clock
as an input, since supposedly the functionality of a block is time-invariant and only depends on its inputs. I think the only trick you need to do is to make two versions of every register that exists in your processor, one set representing their current state, and one representing the state after one click tick. All functions that simulate your hardware should then only use the 'current' registers as inputs, and save their outputs to the 'next' registers. Then at the end of the loop, you copy all the next registers into the current ones and you start all over again. Something like this:
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
Note that in this way, all 'simulate' functions only use the current register values and not any of the values of the next clock cycle. You can therefore change the order in which they are executed without changing the results, as if they were all running in parallel.
Solution 3:
Consider purpose-specific languages like VHDL or Verilog; possibly with a combination/extension such as PyHVL or Cocotb ..
.. however, if this must be created from scratch and/or a pure-Python implementation, consider using the same concepts as in the high-level hardware languages. In particular, consider a reactive design. Both Verilog and VHDL support this notion - where a change to input, such as the clock, drives the behaviors and new output state.
Each "reactive callback" then simply takes in the input state and emits a particular output state in isolation from the other components. Dependencies are then established only by state changes and reactive triggers around changes.
Things that might be used in triggers/guards:
- Line or data change states
- Signaling events
- Cycle counts (e.g. minimum, after, random)
Post a Comment for "How Do You Simulate Hardware In Python?"