ujamjar / hardcaml

[Deprecated see github.com/janestreet/hardcaml] Register Transfer Level Hardware Design in OCaml
https://github.com/janestreet/hardcaml
ISC License
119 stars 8 forks source link

simulation semantics (again) #4

Closed andrewray closed 8 years ago

andrewray commented 9 years ago

We've tried 2 different semantics for the simulator;

  1. comb -> seq
  2. comb -> seq -> comb

The problem isn't the correctness of the simulation as such but what values you can read on the outputs after a simulation step

for ...
   set inputs;
   cycle sim;
   read outputs;

with (1) we read outputs computed from the old register state and inputs while with (2) we read outputs computed from the new register state and inputs.

The real problem actually relates more to the set inputs stage - sometimes we need to read an output in order to set an input and the exact output value you want to read depends on the waveform you are trying to set up. For example;

  1. Drive a request line on the same cycle the hardware generates a ready you need (2)
  2. Remove a request given a grant combinatorially generated by a priority driven round robin arbiter you need (1)

(to some extent these are implementation specific issues depending on where combinational logic is relative to registers and any feedback loops, but we need some way to deal with them)

To some extent this can already be worked around;

for ...
   set inputs;
   cycle_comb0 sim;
   cycle_seq sim;
   read outputs computed from old register values;
   cycle_comb1 sim;
   read outputs computed from new register values;

This does complicate matters though. I think an overall better way would be to provide the output ports computed both ways.

The standard outputs would revert to the old update method. When we need an output computed from the next state it can be computed on demand. For the higher level wrappers we could return output ports as an object with cur and next methods.

andrewray commented 9 years ago

Fixed by addition of out_port_next api 7314aac.

The next issue is to try and avoid the 2 combinational update steps when in the general case only 1 is necessary (the next values could be computed on demand). This requires analysing the logic cones for each output and determining whether they touch a register, and if so what logic nodes need to be updated. Once we can do that though its a small step to classifying the registers by their clocks and supporting multiple clock domains, so let's defer that for a MultiCyclesim implementation.