本文整理匯總了Golang中app/simulator/processor/components/channel.Channel.Add方法的典型用法代碼示例。如果您正苦於以下問題:Golang Channel.Add方法的具體用法?Golang Channel.Add怎麽用?Golang Channel.Add使用的例子?那麽, 這裏精選的方法代碼示例或許可以為您提供幫助。您也可以進一步了解該方法所在類app/simulator/processor/components/channel.Channel
的用法示例。
在下文中一共展示了Channel.Add方法的6個代碼示例,這些例子默認根據受歡迎程度排序。您可以為喜歡或者感覺有用的代碼點讚,您的評價將有助於係統推薦出更棒的Golang代碼示例。
示例1: Run
func (this *Decoder) Run(input, output channel.Channel) {
// Launch each unit as a goroutine
logger.Print(" => Initializing decoder unit %d", this.Index())
go func() {
for {
value, running := <-input.Channel()
if !running || !this.IsActive() {
logger.Print(" => Flushing decoder unit %d", this.Index())
return
}
op := operation.Cast(value)
// Iterate instructions received via the channel
instruction, err := this.decodeInstruction(op)
if err != nil {
logger.Error(err.Error())
break
}
// Send data to output
op.SetInstruction(instruction)
output.Add(op)
// Release one item from input Channel
input.Release()
}
}()
}
示例2: Run
func (this *Executor) Run(input map[info.CategoryEnum]channel.Channel, commonDataBus channel.Channel) {
// Launch each unit as a goroutine
unit, event := this.getUnitFromCategory(this.Category())
logger.Print(" => Initializing execution unit (%s) %d", this.Category(), this.Index())
go func() {
for {
value, running := <-input[this.Category()].Channel()
if !running || !this.IsActive() {
logger.Print(" => Flushing execution unit (%s) %d", this.Category(), this.Index())
return
}
op := operation.Cast(value)
for i := uint8(0); i < op.Instruction().Info.Cycles; i++ {
this.Processor().Wait(1)
}
// Iterate instructions received via the channel
op, _ = this.executeOperation(unit, event, op)
// Send data to common bus for reservation station feedback
commonDataBus.Add(op)
// Release one item from input Channel
input[this.Category()].Release()
}
}()
}
示例3: runCommonBusMultiplexer
func (this *Dispatcher) runCommonBusMultiplexer(input, output1, output2 channel.Channel) {
// For each result got from execution units in the common data bus send to RS and ROB
for {
value, running := <-input.Channel()
if !running {
output1.Close()
output2.Close()
logger.Print(" => Flushing dispatcher unit %d (CDB Mux)", this.Index())
return
}
output1.Add(value)
output2.Add(value)
input.Release()
}
}
示例4: Run
func (this *Fetcher) Run(input, output channel.Channel) {
logger.Print(" => Initializing fetcher unit %d", this.Index())
// Launch each unit as a goroutine
go func() {
for {
value, running := <-input.Channel()
if !running || !this.IsActive() {
logger.Print(" => Flushing fetcher unit %d", this.Index())
return
}
// Release item from input Channel
input.Release()
// Initial operation (address)
op := operation.Cast(value)
// Load instructions data from memory
data := this.Processor().InstructionsMemory().Load(op.Address(), consts.BYTES_PER_WORD*this.InstructionsFetchedPerCycle())
// Fetch instructions
startCycles := this.Processor().Cycles()
operations, err := this.fetchInstructions(op, data, input)
if err != nil {
logger.Error(err.Error())
break
}
// Wait cycles of a fetch stage
this.Processor().Wait(consts.FETCH_CYCLES)
// After wait cycle, notify decode channel with new operations
for _, op := range operations {
if this.IsActive() {
this.Processor().LogEvent(consts.FETCH_EVENT, this.Index(), op.Id(), startCycles)
output.Add(op)
}
}
}
}()
}
示例5: fetchInstructions
func (this *Fetcher) fetchInstructions(op *operation.Operation, bytes []byte, input channel.Channel) ([]*operation.Operation, error) {
initialAddress := op.Address()
totalInstructions := len(bytes) / consts.BYTES_PER_WORD
ops := []*operation.Operation{}
// Analyze each instruction loaded
for i := 0; i < totalInstructions; i += 1 {
data := bytes[i*consts.BYTES_PER_WORD : (i+1)*consts.BYTES_PER_WORD]
// Check program reach end
if this.Processor().ReachedEnd(data) {
this.processor.Finish()
return ops, nil
}
// Do fetch once a new address is received
msg := fmt.Sprintf(" => [FE%d][%03d]: INS[%#04X] = %#04X", this.Index(), this.Processor().InstructionsFetchedCounter(), op.Address(), data)
value, ok := this.Processor().InstructionsMap()[op.Address()]
if ok {
msg = fmt.Sprintf("%s // %s", msg, strings.TrimSpace(strings.Split(value, "=>")[1]))
}
logger.Collect(msg)
// Log event
this.Processor().LogInstructionFetched(op.Address())
// Update data into operation and add to array for post-events
op.SetWord([]byte{data[0], data[1], data[2], data[3]})
// Add operation to be sent to decode channel
ops = append(ops, op)
// Do pre-decode
needsWait, instruction := this.BranchPredictor().PreDecodeInstruction(op.Address())
// If is not pipelined than wait instruction to finish
if !this.Processor().Config().Pipelined() {
go func() {
address, _, err := this.BranchPredictor().GetNextAddress(op.Address(), instruction, true)
newOp := operation.New(this.Processor().InstructionsFetchedCounter(), address)
if err == nil {
input.Add(newOp)
}
}()
return ops, nil
}
// Add next instruction for fetching (as many instructions as it supports per cycle)
if needsWait {
logger.Collect(" => [FE%d][%03d]: Wait detected, no fetching more instructions this cycle", this.Index(), this.Processor().InstructionsFetchedCounter()-1)
// Add next instruction in a go routine as it need to be stalled
go func() {
address, _, err := this.BranchPredictor().GetNextAddress(op.Address(), instruction, false)
newOp := operation.New(this.Processor().InstructionsFetchedCounter(), address)
if err == nil {
input.Add(newOp)
}
}()
return ops, nil
} else {
address, predicted, err := this.BranchPredictor().GetNextAddress(op.Address(), instruction, false)
// Set current operation added to be decoded the predicted address
if predicted {
ops[len(ops)-1].SetNextPredictedAddress(address)
}
// Create new operation object
op = operation.New(this.Processor().InstructionsFetchedCounter(), address)
// If is the last instruction from the package or the predicted address is outside of the address package
if err == nil && (i >= totalInstructions-1 || initialAddress+(uint32(i+1)*consts.BYTES_PER_WORD) != op.Address()) {
input.Add(op)
return ops, nil
}
}
}
return ops, nil
}
示例6: Run
func (this *ReorderBuffer) Run(commonDataBus channel.Channel, recoveryBus channel.Channel) {
// Launch unit as a goroutine
logger.Print(" => Initializing re-order buffer unit %d", this.Index())
opId := this.StartOperationId()
misprediction := false
clockAllowed := this.Processor().Cycles()
forceClose := false
go func() {
for {
_, running := <-commonDataBus.Channel()
if !running || misprediction {
forceClose = true
logger.Print(" => Flushing re-order buffer unit %d", this.Index())
return
}
commonDataBus.Release()
}
}()
go func() {
for {
if forceClose {
return
}
if this.Processor().Cycles() < clockAllowed {
this.Processor().Wait(1)
continue
}
// Commit in order, if missing an operation, wait for it
computedAddress := uint32(0)
robEntries := []RobEntry{}
for robEntry, exists := this.Buffer()[opId]; exists; robEntry, exists = this.Buffer()[opId] {
if uint32(len(robEntries)) >= this.InstructionsWrittenPerCycle() {
break
}
// Ensure we can write results the next cycle result was written into ROB
if this.Processor().Cycles() > robEntry.Cycle+1 {
// Check for misprediction
misprediction, computedAddress = this.checkForMisprediction(this.Buffer()[opId], robEntries)
// Decrement speculative jumps
this.Processor().DecrementSpeculativeJump()
// Add to queue for commit
robEntries = append(robEntries, robEntry)
opId += 1
// If misprediction, do not process more rob entries
if misprediction {
break
}
}
}
this.commitRobEntries(robEntries)
if misprediction {
this.Processor().Wait(consts.WRITEBACK_CYCLES)
recoveryBus.Add(operation.New(opId, computedAddress))
}
clockAllowed = this.Processor().Cycles() + 1
}
}()
}