Golang事件模型

So my problem stems from I thought I'd be awfully clever and try and model hardware in Golang. Yes, use it for the sort of thing that in my day job I write in Verilog.

To start off I'm trying to do the simplest possible hardware pipeline. i.e. a data source that pushes data to a Reg stage which pushes it to the next Reg which pushes it to a sink stage. Things can only advance on the clock. The problem is the event manager seems to have it in for me. Starting at the data being sent on a clock

  select {
    case out_chan <- tmp:
      front_chan = saved_front_chan
      out_chan = nil
      fmt.Println("Sent Data, ", tmp, name)
    default:
      c.ckwg.Done() // Send failed so remove token
      if out_chan != nil {
        log.Fatal("Stalled, Can't send ", tmp, name)
       } else {
        fmt.Println("Nothing to send ", name)
      }
    }

i.e. if we can send the data, do, if we can't then fine; but if we can't send data then the front end receiver (see main code) doesn't get re-enabled for reception. This is sending to a front end which is a bit simpler

for itm := range in_chan {
        c.ckwg.Done()
        fmt.Println("Front Channel received", itm, name)
        saved_front_chan <- itm
    }

Note the use of a sync.WaitGroup to make sure that this code is run before the end of the clock evaluation phase. So far so good. The problem is sometimes one of these front ends will have sucessfully "saved_front_chan <- itm" but will not have got around back to listening on in_chan.

This will mean that the previous stage in the pipeline will think it is stalled. Now this would be fine in a data processing pipeline, but for something that's trying to model hardware to some degree of accuracy it is not. (For this test case I'm modelling a pipeline that tries to support stalls but has no need to stall, so doesn't) As far as I can see though there are no tricks left to me to force the scheduler to have the loop ready to read. Fundamentally I need to know the difference between "Channel can't receive because of pipeline back pressure" and "Channel can't receive because the scheduler hasn't got around to that routine yet."

So the full code is here:

https://github.com/cbehopkins/cbhdl/blob/master/pipe_test.go

For context, the specification I am actually trying to meet is a stage that only advances the data on a clock pulse, and that clock pulse is supplied to all stages "Simultaneously". Yes I know nothing is really in parallel but I'm trying to fake that behavior. Specifically it must appear that the inputs are sampled at the start of the clock phase and then the data is output at the end of the clock phase. Crucially in the faking of the parallelism it must not matter which order the reg stages receive their clock pulses. I have also experimented with the flow control not being done by golang channel back pressure but by a separate token system - but that got stupendously complex and error prone.

FWIW I have another trial version of this where the broadcast of the clock pulse is done with sync package broadcast structure - but that code got in the way of demonstrating the problem I'm having.

Thanks in advance.