diff options
| -rw-r--r-- | inc/instrDTO.h | 21 | ||||
| -rw-r--r-- | inc/response.h | 1 | ||||
| -rw-r--r-- | inc/stage.h | 40 | ||||
| -rw-r--r-- | src/sim/id.cc | 37 | ||||
| -rw-r--r-- | src/sim/instrDTO.cc | 4 | ||||
| -rw-r--r-- | src/sim/stage.cc | 53 | ||||
| -rw-r--r-- | src/utils/response.cc | 2 | 
7 files changed, 120 insertions, 38 deletions
diff --git a/inc/instrDTO.h b/inc/instrDTO.h index 2a6ab1f..77a223e 100644 --- a/inc/instrDTO.h +++ b/inc/instrDTO.h @@ -1,9 +1,10 @@  #ifndef INSTRDTO_H  #define INSTRDTO_H -#include <string> +#include "accessor.h" +#include "instr.h"  #include <functional> +#include <string>  #include <unordered_map> -#include "accessor.h"  class InstrDTO  { @@ -39,9 +40,9 @@ class InstrDTO  	 */  	signed int get_s3();  	/** -	 * @return the string representation of oper. +	 * @return the mnemonic of the instruction  	 */ -	std::string get_oper_name(); +	Mnemonic get_mnemonic();  	/**  	 * @param set hist key @@ -63,6 +64,10 @@ class InstrDTO  	 * @param s3  	 */  	void set_s3(signed int); +	/** +	 * @param the mnemonic of the instruction +	 */ +	void set_mnemonic(Mnemonic);    private:  	/** @@ -82,10 +87,10 @@ class InstrDTO  	signed int s1;  	signed int s2;  	signed int s3; -  /** -   * The operation to be conducted during the execute phase. -   */ -	std::function<void()> instr; +	/** +	 * The mnemonic of the operation. +	 */ +	Mnemonic mnemonic;  };  #endif /* INSTRDTO_H_INCLUDED */ diff --git a/inc/response.h b/inc/response.h index 6cd6678..05e9352 100644 --- a/inc/response.h +++ b/inc/response.h @@ -6,6 +6,7 @@ enum Response {  	OK,  	WAIT,  	BLOCKED, +	STALLED,  };  std::ostream &operator<<(std::ostream &os, Response r); diff --git a/inc/stage.h b/inc/stage.h index f6bad41..0348263 100644 --- a/inc/stage.h +++ b/inc/stage.h @@ -1,11 +1,12 @@  #ifndef STAGE_H  #define STAGE_H +#include "accessor.h"  #include "definitions.h"  #include "instrDTO.h"  #include "response.h"  #include "storage.h" -#include "accessor.h"  #include <array> +#include <set>  class Stage  { @@ -28,6 +29,16 @@ class Stage    protected:  	/** +	 * Facilitates register checkout. +	 * It does this by checking that the register passed in is not currently +	 * checked out. If true, then replaces r with the value of the register and +	 * returns OK. If false, returns STALLED. +	 * +	 * @param the registers number, to be dereferenced. +	 * @return OK if `r` is not checked out, STALLED otherwise. +	 */ +	Response check_out(unsigned int &r); +	/**  	 * The name of the pipeline stage.  	 */  	Accessor id; @@ -59,6 +70,33 @@ class Stage  	 * The current clock cycle.  	 */  	static int clock_cycle; + +  private: +	/** +	 * Helper for `check_out`. +	 * Returns true if r are not checked out, false otherwise. +	 * @param a list of register numbers. +	 * @return true if registers are not in checked_out, false otherwise. +	 */ +	bool is_checked_out(unsigned int r); +	/** +	 * Helper for `check_out`. +	 * Checks out a single register, and places it in checked_out. +	 * @param a register number. +	 * @return the value in the register. +	 */ +	signed int check_out_register(unsigned int r); +	// TODO fix this comment after writeback stage +	/** +	 * Helper for `check_out_register` +	 * @param the register number. +	 * @return the value in the associated register. +	 */ +	signed int dereference_register(unsigned int r); +	/** +	 * The set of registers currently checked out. +	 */ +	static std::set<unsigned int> checked_out;  };  #endif /* STAGE_H_INCLUDED */ diff --git a/src/sim/id.cc b/src/sim/id.cc index c6e42d5..e9c48df 100644 --- a/src/sim/id.cc +++ b/src/sim/id.cc @@ -5,13 +5,20 @@  #include "logger.h"  #include "response.h"  #include "stage.h" -#include "utils.h" - -static Logger *global_log = Logger::getInstance();  ID::ID(Stage *stage) : Stage(stage) { this->id = DCDE; } -Response ID::advance(InstrDTO &i) { Response r; } +Response ID::advance(InstrDTO &i) +{ +	Response r; +	signed int s1, s2, s3; +	Mnemonic m; + +	s1 = i.get_instr_bits(); + +	get_instr_fields(s1, s2, s3, m); +	return r; +}  // TODO this function is ugly  void ID::get_instr_fields( @@ -53,30 +60,10 @@ void ID::split_instr(signed int &raw, unsigned int &type, Mnemonic &m)  	opcode_size = (type == 0b0) ? R_OPCODE_SIZE : OPCODE_SIZE;  	opcode = GET_MID_BITS(raw, TYPE_SIZE, TYPE_SIZE + opcode_size);  	try { -		m = instr::mnemonic_map.at((opcode << 2) + type); +		m = instr::mnemonic_map.at((opcode << TYPE_SIZE) + type);  	} catch (std::out_of_range const &) {  		m = NOP;  	}  	raw = (unsigned int)raw >> (TYPE_SIZE + opcode_size);  } - -Response ID::dereference_register(signed int &v) -{ -	Response r; -	r = OK; - -	if (v < 0 || v >= GPR_NUM + V_NUM) { -		global_log->log( -			ERROR, string_format( -					   "instruction tried to access register %d, which does " -					   "not exist", -					   v)); -		exit(EXIT_FAILURE); -	} else if (v >= GPR_NUM) -		v = this->vrs[v % GPR_NUM]; -	else -		v = this->gprs[v]; - -	return r; -} diff --git a/src/sim/instrDTO.cc b/src/sim/instrDTO.cc index 7864eb4..7418033 100644 --- a/src/sim/instrDTO.cc +++ b/src/sim/instrDTO.cc @@ -19,6 +19,8 @@ signed int InstrDTO::get_s2() { return this->s2; }  signed int InstrDTO::get_s3() { return this->s3; } +Mnemonic InstrDTO::get_mnemonic() { return this->mnemonic; } +  void InstrDTO::set_time_of(Accessor a, int i) { this->hist[a] = i; }  void InstrDTO::set_instr_bits(signed int instr) { this->instr_bits = instr; } @@ -28,3 +30,5 @@ void InstrDTO::set_s1(signed int s) { this->s1 = s; }  void InstrDTO::set_s2(signed int s) { this->s2 = s; }  void InstrDTO::set_s3(signed int s) { this->s3 = s; } + +void InstrDTO::set_mnemonic(Mnemonic m) { this->mnemonic = m; } diff --git a/src/sim/stage.cc b/src/sim/stage.cc index 560cc41..8d9dfc0 100644 --- a/src/sim/stage.cc +++ b/src/sim/stage.cc @@ -1,12 +1,59 @@  #include "stage.h" +#include "utils.h" +#include <array> +#include <set> -Stage::Stage(Stage *next) { -	this->next = next; -} +static Logger *global_log = Logger::getInstance(); + +Stage::Stage(Stage *next) { this->next = next; }  std::array<int, GPR_NUM> Stage::gprs;  std::array<int, V_NUM> Stage::vrs; +std::set<unsigned int> Stage::checked_out;  unsigned int Stage::pc;  Storage *Stage::storage;  bool Stage::is_pipelined;  int Stage::clock_cycle; + +Response Stage::check_out(unsigned int &v) +{ +	Response r; +	if (this->is_checked_out(v)) +		r = STALLED; +	else { +		r = OK; +		v = this->check_out_register(v); +	} +	return r; +} + +bool Stage::is_checked_out(unsigned int r) +{ +	return this->checked_out.find(r) != this->checked_out.end(); +} + +signed int Stage::check_out_register(unsigned int v) +{ +	signed int r; +	this->checked_out.insert(v); + +	r = this->dereference_register(v); +	return r; +} + +signed int Stage::dereference_register(unsigned int v) +{ +	signed int r; + +	if (v >= GPR_NUM + V_NUM) { +		global_log->log( +			ERROR, string_format( +					   "instruction tried to access register %d, which does " +					   "not exist", +					   v)); +		exit(EXIT_FAILURE); +	} + +	r = (v >= GPR_NUM) ? this->vrs[v % GPR_NUM] : this->gprs[v]; +	return r; +} diff --git a/src/utils/response.cc b/src/utils/response.cc index def6578..3d6e439 100644 --- a/src/utils/response.cc +++ b/src/utils/response.cc @@ -3,6 +3,6 @@  std::ostream &operator<<(std::ostream &os, Response r)  { -	const std::string nameR[] = {"OK", "WAIT", "BLOCKED"}; +	const std::string nameR[] = {"OK", "WAIT", "BLOCKED", "STALLED"};  	return os << nameR[r];  }  | 
