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()
		}
	}()
}
Beispiel #2
0
func runCommand(c *cli.Context) {

	printHeader()
	logger.SetVerboseDebug(c.Bool("verbose"))

	if len(c.Args()) != 1 {
		logger.Error("Expecting <assembly-filename> and got %d parameters", len(c.Args()))
		os.Exit(1)
	}

	assemblyFilename, _ := filepath.Abs(c.Args()[0])
	if _, err := os.Stat(assemblyFilename); os.IsNotExist(err) {
		logger.Error("File %s does not exists", assemblyFilename)
		os.Exit(1)
	}

	outputFolder, _ := filepath.Abs(c.String("output-folder"))
	if outputFolder == "" {
		outputFolder = filepath.Join(filepath.Dir(assemblyFilename), getFileName(assemblyFilename))
	}

	configFilename, _ := filepath.Abs(c.String("config-filename"))
	if configFilename == "" {
		logger.Error("Configuration file not provided, please provide a valid configuration file")
		os.Exit(1)
	}

	cfg, err := config.Load(configFilename)
	if err != nil {
		logger.Error("Failed loading config. %s", err.Error())
		os.Exit(1)
	}
	logger.Print(" => Configuration file: %s", configFilename)

	err = runProgram(assemblyFilename, c.Bool("step-by-step"), outputFolder, cfg, uint32(c.Int("max-cycles")))
	if err != nil {
		logger.Error(err.Error())
		os.Exit(1)
	}
}
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)
				}
			}
		}
	}()
}