diff options
Diffstat (limited to 'src/sim')
| -rw-r--r-- | src/sim/ex.cc | 14 | ||||
| -rw-r--r-- | src/sim/id.cc | 20 | ||||
| -rw-r--r-- | src/sim/instrDTO.cc | 2 | ||||
| -rw-r--r-- | src/sim/mm.cc | 1 | ||||
| -rw-r--r-- | src/sim/stage.cc | 25 | ||||
| -rw-r--r-- | src/sim/wb.cc | 75 | 
6 files changed, 93 insertions, 44 deletions
| diff --git a/src/sim/ex.cc b/src/sim/ex.cc index 3d95917..ec4c47f 100644 --- a/src/sim/ex.cc +++ b/src/sim/ex.cc @@ -4,6 +4,7 @@  #include "instrDTO.h"  #include "response.h"  #include "stage.h" +#include "utils.h"  #include <unordered_map>  // clang-format off @@ -185,6 +186,7 @@ EX::EX(Stage *stage) : Stage(stage)  			ADDI,  			{  				s1 = s1 + s3; +				std::cout << "= " << s2 << std::endl;  				(void)s2;  				(void)this;  			}), @@ -282,28 +284,32 @@ EX::EX(Stage *stage) : Stage(stage)  		INIT_INSTRUCTION(  			BEQ,  			{ -				(this->get_condition(EQ)) ? s1 = this->pc + s2 : s1 = this->pc; +				(this->get_condition(EQ)) ? s1 = wrap_address(this->pc + s2) +										  : s1 = -1;  				(void)s3;  			}),  		INIT_INSTRUCTION(  			BGT,  			{ -				(this->get_condition(GT)) ? s1 = this->pc + s2 : s1 = this->pc; +				(this->get_condition(GT)) ? s1 = wrap_address(this->pc + s2) +										  : s1 = -1;  				(void)s3;  			}),  		INIT_INSTRUCTION(  			BUF,  			{ -				(this->get_condition(UF)) ? s1 = this->pc + s2 : s1 = this->pc; +				(this->get_condition(UF)) ? s1 = wrap_address(this->pc) + s2 +										  : s1 = -1;  				(void)s3;  			}),  		INIT_INSTRUCTION(  			BOF,  			{ -				(this->get_condition(OF)) ? s1 = this->pc + s2 : s1 = this->pc; +				(this->get_condition(OF)) ? s1 = wrap_address(this->pc + s2) +										  : s1 = -1;  				(void)s3;  			}), diff --git a/src/sim/id.cc b/src/sim/id.cc index 4a55d04..ddac35b 100644 --- a/src/sim/id.cc +++ b/src/sim/id.cc @@ -48,14 +48,18 @@ void ID::advance_helper()  	Mnemonic m;  	Type t; -	s1 = curr_instr->get_instr_bits(); -	get_instr_fields(s1, s2, s3, m, t); -	if (this->status == OK) { -		curr_instr->set_s1(s1); -		curr_instr->set_s2(s2); -		curr_instr->set_s3(s3); -		curr_instr->set_mnemonic(m); -		curr_instr->set_type(t); +	if (curr_instr->get_mnemonic() == NOP) +		this->status = OK; +	else { +		s1 = curr_instr->get_instr_bits(); +		get_instr_fields(s1, s2, s3, m, t); +		if (this->status == OK) { +			curr_instr->set_s1(s1); +			curr_instr->set_s2(s2); +			curr_instr->set_s3(s3); +			curr_instr->set_mnemonic(m); +			curr_instr->set_type(t); +		}  	}  } diff --git a/src/sim/instrDTO.cc b/src/sim/instrDTO.cc index 28364b7..7324ba9 100644 --- a/src/sim/instrDTO.cc +++ b/src/sim/instrDTO.cc @@ -7,7 +7,7 @@ InstrDTO::InstrDTO()  	this->s1 = 0;  	this->s2 = 0;  	this->s3 = 0; -	this->mnemonic = NOP; +	this->mnemonic = ADD;  	this->type = INV;  } diff --git a/src/sim/mm.cc b/src/sim/mm.cc index c83ae7d..e29bf90 100644 --- a/src/sim/mm.cc +++ b/src/sim/mm.cc @@ -10,6 +10,7 @@ void MM::advance_helper()  {  	signed int data; +	std::cout << "mem" << this->curr_instr->get_s2() << std::endl;  	switch (this->curr_instr->get_mnemonic()) {  	case LOAD:  		this->status = this->storage->read_word( diff --git a/src/sim/stage.cc b/src/sim/stage.cc index 31d7d0d..b10a206 100644 --- a/src/sim/stage.cc +++ b/src/sim/stage.cc @@ -2,7 +2,6 @@  #include "utils.h"  #include <array>  #include <deque> -#include <iostream>  Stage::Stage(Stage *next)  { @@ -28,10 +27,12 @@ void Stage::set_pc(unsigned int pc) { this->pc = pc; }  InstrDTO *Stage::advance(Response p)  {  	InstrDTO *r = nullptr; +	InstrDTO *s = nullptr;  	Response n; -	if (this->curr_instr && this->status != OK) +	if (this->curr_instr && this->status != OK) {  		this->advance_helper(); +	}  	if (this->status == OK && p == WAIT && this->curr_instr) {  		// mutual consent  		this->curr_instr->set_time_of(this->id, this->clock_cycle); @@ -42,8 +43,9 @@ InstrDTO *Stage::advance(Response p)  	}  	n = (p != WAIT || this->status != WAIT) ? STALLED : WAIT; -	// the power of consent -	this->curr_instr = this->next->advance(n); +	s = this->next->advance(n); +	if (s) +		this->curr_instr = s;  	return r;  } @@ -70,6 +72,21 @@ signed int Stage::dereference_register(signed int v)  	return r;  } +void Stage::store_register(signed int v, signed int d) +{ +	if (v < 0 || v >= GPR_NUM + V_NUM) { +		throw std::out_of_range(string_format( +			"instruction tried to access register %d, which does " +			"not exist", +			v)); +	} + +	if (v >= GPR_NUM) +		this->vrs[v % GPR_NUM] = d; +	else +		this->gprs[v] = d; +} +  bool Stage::is_checked_out(signed int r)  {  	return std::find(this->checked_out.begin(), this->checked_out.end(), r) != diff --git a/src/sim/wb.cc b/src/sim/wb.cc index 276d1d0..01768e8 100644 --- a/src/sim/wb.cc +++ b/src/sim/wb.cc @@ -8,33 +8,54 @@ WB::WB(Stage *stage) : Stage(stage) { this->id = WRITE; }  void WB::advance_helper()  { -	if (this->curr_instr->get_type() == R || -		this->curr_instr->get_type() == I) { -		if (this->checked_out.size() > 0) { -			signed int reg = this->checked_out.front(); -			this->checked_out.pop_front(); -			if (reg >= GPR_NUM) { -				// TODO: handle vector instructions -			} else { -				if (this->curr_instr->get_mnemonic() != STORE && -					this->curr_instr->get_mnemonic() != STOREV) { -					this->gprs[reg] = this->curr_instr->get_s1(); -				} -			} -		} -	} else if (this->curr_instr->get_type() == J) { -		// TODO:handle push pop -		// branch taken -		if (this->pc != this->curr_instr->get_s1()) { -			if (this->curr_instr->get_mnemonic() == JAL) { -				// set link register to next instruction -				this->gprs[1] = this->pc + 1; -			} -			this->pc = this->curr_instr->get_s1(); -			// clear pending registers and squash pipeline -			this->checked_out = {}; -			this->next->squash(); -		} +	if (this->curr_instr->get_mnemonic() != NOP && +		this->curr_instr->get_type() != INV) { +		if (this->should_write()) +			this->write_handler(); +		else if (this->should_jump()) +			this->jump_handler();  	}  	this->status = OK;  } + +void WB::write_handler() +{ +	signed int reg; + +	if (this->checked_out.size() < 1) +		throw std::runtime_error("instruction tried to pop a register out of " +								 "an empty queue during writeback."); + +	reg = this->checked_out.front(); +	this->checked_out.pop_front(); +	this->store_register(reg, this->curr_instr->get_s1()); +} + +void WB::jump_handler() +{ +	if (this->curr_instr->get_s1() > 0) { +		if (this->curr_instr->get_mnemonic() == JAL) +			this->gprs[1] = this->pc + 1; +		this->pc = this->curr_instr->get_s1(); +		this->checked_out = {}; +		this->next->squash(); +	} +} + +bool WB::should_jump() +{ +	Type t; + +	t = this->curr_instr->get_type(); +	return t == J; +} + +bool WB::should_write() +{ +	Mnemonic m; +	Type t; + +	m = this->curr_instr->get_mnemonic(); +	t = this->curr_instr->get_type(); +	return (t == R || t == I) && (m != STORE && m != STOREV); +} | 
