func (this *Dispatcher) Run(input channel.Channel, output map[info.CategoryEnum]channel.Channel, commonDataBus, recoveryBus channel.Channel) {

	// Create register alias table
	rat := registeraliastable.New(this.Index(), this.RegisterAliasTableEntries())

	// Create re-order buffer
	rob := reorderbuffer.New(this.Index(),
		this.Processor(),
		this.StartOperationId(),
		this.ReorderBufferEntries(),
		this.InstructionsWrittenPerCycle(),
		rat)
	commonDataBusROB := channel.New(commonDataBus.Capacity())

	// Create reservation station
	rs := reservationstation.New(this.Index(), this.Processor(),
		this.Registers(),
		this.ReservationStationEntries(),
		this.InstructionsFetchedPerCycle(),
		rat, rob.Bus())
	commonDataBusRS := channel.New(commonDataBus.Capacity())

	// Create storage bus
	this.dispatcher.bus = rob.Bus()

	// Launch each unit as a goroutine
	logger.Print(" => Initializing dispatcher unit %d", this.Index())

	// Start dispatcher of operations to be executed into reservation station
	go this.runDispatcherToReservationStation(input, rs, rat, rob)
	// Start common bus multiplexer to send ack to reservation station and reorder buffer
	go this.runCommonBusMultiplexer(commonDataBus, commonDataBusRS, commonDataBusROB)

	// Run reservation station
	rs.Run(commonDataBusRS, output)
	// Run re-order buffer
	rob.Run(commonDataBusROB, recoveryBus)
}
Esempio n. 2
0
func (this *Processor) Start() {

	logger.CleanBuffer()
	logger.Print("\n Simulation:")
	logger.Print("\n => Starting program...")

	// Launch pipeline units and execute instruction 0x0000
	recoveryChannel := channel.New(1)
	flushFunc := this.StartPipelineUnits(this.Config(), recoveryChannel, 0, 0x0000)

	// Launch clock
	go this.RunClock()

	// Launch recovery
	go this.RunRecovery(recoveryChannel, flushFunc)

	logger.Print(" => Program is running...")
	logger.SetVerboseQuiet(true)
}
func New(index uint32, processor iprocessor.IProcessor, registers uint32, reservationStationEntries uint32,
	instructionsDispatchedPerCycle uint32, rat *registeraliastable.RegisterAliasTable, robBus *storagebus.StorageBus) *ReservationStation {
	rs := &ReservationStation{
		&reservationStation{
			index:                       index,
			processor:                   processor,
			entries:                     make([]RsEntry, reservationStationEntries),
			input:                       channel.New(reservationStationEntries),
			lock:                        make(chan bool, 1),
			isActive:                    true,
			instructionsDispatchedStack: 0,
			instructionsDispatchedMax:   instructionsDispatchedPerCycle,
			registerAliasTable:          rat,
			bus:                         robBus,
		},
	}
	for entryIndex, _ := range rs.Entries() {
		rs.Entries()[entryIndex] = RsEntry{
			Free: true,
			Busy: false,
		}
	}
	return rs
}
Esempio n. 4
0
func (this *Processor) StartPipelineUnits(config *config.Config, recoveryChannel channel.Channel, operationId, address uint32) func() {

	// Initialize channels
	addressChannel := channel.New(config.InstructionsFetchedPerCycle()) // Branch Predictor -> Fetch
	instructionChannel := channel.New(config.InstructionsQueue())       // Fetch -> Decode
	operationChannel := channel.New(config.InstructionsDecodedQueue())  // Decode -> Dispatch
	executionChannels := map[info.CategoryEnum]channel.Channel{         // Dispatch -> Execute
		info.Aritmetic:     channel.New(config.AluUnits()),
		info.LoadStore:     channel.New(config.LoadStoreUnits()),
		info.Control:       channel.New(config.BranchUnits()),
		info.FloatingPoint: channel.New(config.FpuUnits()),
	}
	commonDataBusChannel := channel.New(channel.INFINITE) // Execute -> Dispatcher (RS & ROB)

	closeUnitsHandlers := []func(){}

	/////////////////////////////////////////////////////////////////////////////
	// Run stage units in parallel                                             //
	//  - Units are executed as go routines https://blog.golang.org/pipelines) //
	/////////////////////////////////////////////////////////////////////////////

	// ---------- Fetch ------------ //
	fe := fetcher.New(uint32(0), this, config.InstructionsFetchedPerCycle(), config.BranchPredictorType())
	fe.Run(addressChannel, instructionChannel)
	closeUnitsHandlers = append(closeUnitsHandlers, fe.Close)

	// ---------- Decode ------------ //
	for index := uint32(0); index < config.DecoderUnits(); index++ {
		de := decoder.New(index, this)
		de.Run(instructionChannel, operationChannel)
		closeUnitsHandlers = append(closeUnitsHandlers, de.Close)
	}

	// ----- Dispatch / RS / ROB ---- //
	di := dispatcher.New(uint32(0), this, operationId, config.TotalRegisters(),
		config.ReservationStationEntries(), config.ReorderBufferEntries(), config.InstructionsDispatchedPerCycle(),
		config.InstructionsWrittenPerCycle(), config.RegisterAliasTableEntries())
	di.Run(operationChannel, executionChannels, commonDataBusChannel, recoveryChannel)
	closeUnitsHandlers = append(closeUnitsHandlers, di.Close)

	// ------- Execute (Alu) -------- //
	for index := uint32(0); index < config.AluUnits(); index++ {
		ex := executor.New(index, this, di.Bus(), info.Aritmetic)
		ex.Run(executionChannels, commonDataBusChannel)
		closeUnitsHandlers = append(closeUnitsHandlers, ex.Close)
	}

	// ---- Execute (Load Store) ---- //
	for index := uint32(0); index < config.LoadStoreUnits(); index++ {
		ex := executor.New(index, this, di.Bus(), info.LoadStore)
		ex.Run(executionChannels, commonDataBusChannel)
		closeUnitsHandlers = append(closeUnitsHandlers, ex.Close)
	}

	// ------ Execute (Branch) ------ //
	for index := uint32(0); index < config.BranchUnits(); index++ {
		ex := executor.New(index, this, di.Bus(), info.Control)
		ex.Run(executionChannels, commonDataBusChannel)
		closeUnitsHandlers = append(closeUnitsHandlers, ex.Close)
	}

	// ------- Execute (FPU) -------- //
	for index := uint32(0); index < config.FpuUnits(); index++ {
		ex := executor.New(index, this, di.Bus(), info.FloatingPoint)
		ex.Run(executionChannels, commonDataBusChannel)
		closeUnitsHandlers = append(closeUnitsHandlers, ex.Close)
	}

	// Set instruction for fetching to start pipeline
	go addressChannel.Add(operation.New(operationId, address))

	// Return flush function for all channels
	return func() {
		// Close units & channels
		for _, closeUnitHandler := range closeUnitsHandlers {
			closeUnitHandler()
		}

		// Close channels
		addressChannel.Close()
		instructionChannel.Close()
		operationChannel.Close()
		executionChannels[info.Aritmetic].Close()
		executionChannels[info.LoadStore].Close()
		executionChannels[info.Control].Close()
		executionChannels[info.FloatingPoint].Close()
		commonDataBusChannel.Close()
	}
}