diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/abstract_hardware_model.h | 78 | ||||
| -rw-r--r-- | src/gpgpu-sim/gpu-sim.cc | 13 | ||||
| -rw-r--r-- | src/gpgpu-sim/shader.cc | 147 | ||||
| -rw-r--r-- | src/gpgpu-sim/shader.h | 88 |
4 files changed, 245 insertions, 81 deletions
diff --git a/src/abstract_hardware_model.h b/src/abstract_hardware_model.h index 4bfdda9..28dc6cb 100644 --- a/src/abstract_hardware_model.h +++ b/src/abstract_hardware_model.h @@ -862,6 +862,84 @@ class core_t { class ptx_thread_info ** m_thread; }; + +//register that can hold multiple instructions. +class register_set { +public: + register_set(unsigned num, const char* name){ + for( unsigned i = 0; i < num; i++ ) { + regs.push_back(new warp_inst_t()); + } + m_name = name; + } + bool has_free(){ + for( unsigned i = 0; i < regs.size(); i++ ) { + if( regs[i]->empty() ) { + return true; + } + } + return false; + } + bool has_ready(){ + for( unsigned i = 0; i < regs.size(); i++ ) { + if( not regs[i]->empty() ) { + return true; + } + } + return false; + } + + void move_in( warp_inst_t *&src ){ + warp_inst_t** free = get_free(); + move_warp(*free, src); + } + //void copy_in( warp_inst_t* src ){ + // src->copy_contents_to(*get_free()); + //} + void move_out_to( warp_inst_t *&dest ){ + warp_inst_t **ready=get_ready(); + move_warp(dest, *ready); + } + + warp_inst_t** get_ready(){ + warp_inst_t** ready; + ready = NULL; + for( unsigned i = 0; i < regs.size(); i++ ) { + if( not regs[i]->empty() ) { + if( ready and (*ready)->get_uid() < regs[i]->get_uid() ) { + // ready is oldest + } else { + ready = ®s[i]; + } + } + } + return ready; + } + + void print(FILE* fp) const{ + fprintf(fp, "%s : @%p\n", m_name, this); + for( unsigned i = 0; i < regs.size(); i++ ) { + fprintf(fp, " "); + regs[i]->print(fp); + fprintf(fp, "\n"); + } + } + + warp_inst_t ** get_free(){ + for( unsigned i = 0; i < regs.size(); i++ ) { + if( regs[i]->empty() ) { + return ®s[i]; + } + } + assert(0 && "No free registers found"); + return NULL; + } + +private: + std::vector<warp_inst_t*> regs; + const char* m_name; +}; + #endif // #ifdef __cplusplus #endif // #ifndef ABSTRACT_HARDWARE_MODEL_INCLUDED diff --git a/src/gpgpu-sim/gpu-sim.cc b/src/gpgpu-sim/gpu-sim.cc index c33ef17..83c57b2 100644 --- a/src/gpgpu-sim/gpu-sim.cc +++ b/src/gpgpu-sim/gpu-sim.cc @@ -245,6 +245,19 @@ void shader_core_config::reg_options(class OptionParser * opp) option_parser_register(opp, "-gpgpu_simt_core_sim_order", OPT_INT32, &simt_core_sim_order, "Select the simulation order of cores in a cluster (0=Fix, 1=Round-Robin)", "1"); + option_parser_register(opp, "-gpgpu_pipeline_widths", OPT_CSTR, &pipeline_widths_string, + "Pipeline widths " + "ID_OC_SP,ID_OC_SFU,ID_OC_MEM,OC_EX_SP,OC_EX_SFU,OC_EX_MEM,EX_WB", + "1,1,1,1,1,1,1" ); + option_parser_register(opp, "-gpgpu_num_sp_units", OPT_INT32, &gpgpu_num_sp_units, + "Number of SP units (default=1)", + "1"); + option_parser_register(opp, "-gpgpu_num_sfu_units", OPT_INT32, &gpgpu_num_sfu_units, + "Number of SF units (default=1)", + "1"); + option_parser_register(opp, "-gpgpu_num_mem_units", OPT_INT32, &gpgpu_num_mem_units, + "Number if ldst units (default=1) WARNING: not hooked up to anything", + "1"); } void gpgpu_sim_config::reg_options(option_parser_t opp) diff --git a/src/gpgpu-sim/shader.cc b/src/gpgpu-sim/shader.cc index 527fdcb..1bc0064 100644 --- a/src/gpgpu-sim/shader.cc +++ b/src/gpgpu-sim/shader.cc @@ -82,9 +82,10 @@ shader_core_ctx::shader_core_ctx( class gpgpu_sim *gpu, m_sid = shader_id; m_tpc = tpc_id; - m_pipeline_reg = new warp_inst_t*[N_PIPELINE_STAGES]; - for (int j = 0; j<N_PIPELINE_STAGES; j++) - m_pipeline_reg[j] = new warp_inst_t(config); + m_pipeline_reg.reserve(N_PIPELINE_STAGES); + for (int j = 0; j<N_PIPELINE_STAGES; j++) { + m_pipeline_reg.push_back(register_set(m_config->pipe_widths[j],pipeline_stage_name_decode[j])); + } m_threadState = (thread_ctx_t*) calloc(sizeof(thread_ctx_t), config->n_thread_per_shader); m_thread = (ptx_thread_info**) calloc(sizeof(ptx_thread_info*), config->n_thread_per_shader); @@ -186,24 +187,30 @@ shader_core_ctx::shader_core_ctx( class gpgpu_sim *gpu, m_operand_collector.init( m_config->gpgpu_num_reg_banks, this ); // execute - m_num_function_units = 3; // sp_unit, sfu, ldst_unit - m_dispatch_port = new enum pipeline_stage_name_t[ m_num_function_units ]; - m_issue_port = new enum pipeline_stage_name_t[ m_num_function_units ]; + m_num_function_units = m_config->gpgpu_num_sp_units + m_config->gpgpu_num_sfu_units + 1; // sp_unit, sfu, ldst_unit + //m_dispatch_port = new enum pipeline_stage_name_t[ m_num_function_units ]; + //m_issue_port = new enum pipeline_stage_name_t[ m_num_function_units ]; - m_fu = new simd_function_unit*[m_num_function_units]; + //m_fu = new simd_function_unit*[m_num_function_units]; - m_fu[0] = new sp_unit( &m_pipeline_reg[EX_WB], m_config ); - m_dispatch_port[0] = ID_OC_SP; - m_issue_port[0] = OC_EX_SP; + for (int k = 0; k < m_config->gpgpu_num_sp_units; k++) { + m_fu.push_back(new sp_unit( &m_pipeline_reg[EX_WB], m_config )); + m_dispatch_port.push_back(ID_OC_SP); + m_issue_port.push_back(OC_EX_SP); + } - m_fu[1] = new sfu( &m_pipeline_reg[EX_WB], m_config ); - m_dispatch_port[1] = ID_OC_SFU; - m_issue_port[1] = OC_EX_SFU; + for (int k = 0; k < m_config->gpgpu_num_sfu_units; k++) { + m_fu.push_back(new sfu( &m_pipeline_reg[EX_WB], m_config )); + m_dispatch_port.push_back(ID_OC_SFU); + m_issue_port.push_back(OC_EX_SFU); + } m_ldst_unit = new ldst_unit( m_icnt, m_mem_fetch_allocator, this, &m_operand_collector, m_scoreboard, config, mem_config, stats, shader_id, tpc_id ); - m_fu[2] = m_ldst_unit; - m_dispatch_port[2] = ID_OC_MEM; - m_issue_port[2] = OC_EX_MEM; + m_fu.push_back(m_ldst_unit); + m_dispatch_port.push_back(ID_OC_MEM); + m_issue_port.push_back(OC_EX_MEM); + + assert(m_num_function_units == m_fu.size() and m_fu.size() == m_dispatch_port.size() and m_fu.size() == m_issue_port.size()); m_last_inst_gpu_sim_cycle = 0; m_last_inst_gpu_tot_sim_cycle = 0; @@ -505,21 +512,24 @@ void shader_core_ctx::func_exec_inst( warp_inst_t &inst ) inst.generate_mem_accesses(); } -void shader_core_ctx::issue_warp( warp_inst_t *&pipe_reg, const warp_inst_t *next_inst, const active_mask_t &active_mask, unsigned warp_id ) +void shader_core_ctx::issue_warp( register_set& pipe_reg_set, const warp_inst_t* next_inst, const active_mask_t &active_mask, unsigned warp_id ) { + warp_inst_t** pipe_reg = pipe_reg_set.get_free(); + assert(pipe_reg); + m_warp[warp_id].ibuffer_free(); assert(next_inst->valid()); - *pipe_reg = *next_inst; // static instruction information - pipe_reg->issue( active_mask, warp_id, gpu_tot_sim_cycle + gpu_sim_cycle ); // dynamic instruction information - m_stats->shader_cycle_distro[2+pipe_reg->active_count()]++; - func_exec_inst( *pipe_reg ); + **pipe_reg = *next_inst; // static instruction information + (*pipe_reg)->issue( active_mask, warp_id, gpu_tot_sim_cycle + gpu_sim_cycle ); // dynamic instruction information + m_stats->shader_cycle_distro[2+(*pipe_reg)->active_count()]++; + func_exec_inst( **pipe_reg ); if( next_inst->op == BARRIER_OP ) m_barriers.warp_reaches_barrier(m_warp[warp_id].get_cta_id(),warp_id); else if( next_inst->op == MEMORY_BARRIER_OP ) m_warp[warp_id].set_membar(); - updateSIMTStack(warp_id,m_config->warp_size,pipe_reg); - m_scoreboard->reserveRegisters(pipe_reg); + updateSIMTStack(warp_id,m_config->warp_size,*pipe_reg); + m_scoreboard->reserveRegisters(*pipe_reg); m_warp[warp_id].set_next_pc(next_inst->pc + next_inst->isize); } @@ -565,15 +575,15 @@ void scheduler_unit::cycle() const active_mask_t &active_mask = m_simt_stack[warp_id]->get_active_mask(); assert( warp(warp_id).inst_in_pipeline() ); if ( (pI->op == LOAD_OP) || (pI->op == STORE_OP) || (pI->op == MEMORY_BARRIER_OP) ) { - if( (*m_mem_out)->empty() ) { + if( m_mem_out->has_free() ) { m_shader->issue_warp(*m_mem_out,pI,active_mask,warp_id); issued++; issued_inst=true; warp_inst_issued = true; } } else { - bool sp_pipe_avail = (*m_sp_out)->empty(); - bool sfu_pipe_avail = (*m_sfu_out)->empty(); + bool sp_pipe_avail = m_sp_out->has_free(); + bool sfu_pipe_avail = m_sfu_out->has_free(); if( sp_pipe_avail && (pI->op != SFU_OP) ) { // always prefer SP pipe for operations that can use both SP and SFU pipelines m_shader->issue_warp(*m_sp_out,pI,active_mask,warp_id); @@ -694,12 +704,13 @@ void shader_core_ctx::execute() for( unsigned c=0; c < multiplier; c++ ) m_fu[n]->cycle(); enum pipeline_stage_name_t issue_port = m_issue_port[n]; - warp_inst_t *& issue_inst = m_pipeline_reg[ issue_port ]; - if( !issue_inst->empty() && m_fu[n]->can_issue( *issue_inst ) ) { + register_set& issue_inst = m_pipeline_reg[ issue_port ]; + warp_inst_t** ready_reg = issue_inst.get_ready(); + if( issue_inst.has_ready() && m_fu[n]->can_issue( **ready_reg ) ) { bool schedule_wb_now = !m_fu[n]->stallable(); - if( schedule_wb_now && !m_result_bus.test( issue_inst->latency ) ) { - assert( issue_inst->latency < MAX_ALU_LATENCY ); - m_result_bus.set( issue_inst->latency ); + if( schedule_wb_now && !m_result_bus.test( (*ready_reg)->latency ) ) { + assert( (*ready_reg)->latency < MAX_ALU_LATENCY ); + m_result_bus.set( (*ready_reg)->latency ); m_fu[n]->issue( issue_inst ); } else if( !schedule_wb_now ) { m_fu[n]->issue( issue_inst ); @@ -730,8 +741,9 @@ void shader_core_ctx::warp_inst_complete(const warp_inst_t &inst) void shader_core_ctx::writeback() { - warp_inst_t *&pipe_reg = m_pipeline_reg[EX_WB]; - if( !pipe_reg->empty()) { + warp_inst_t** preg = m_pipeline_reg[EX_WB].get_ready(); + warp_inst_t* pipe_reg = (preg==NULL)? NULL:*preg; + if( preg and !pipe_reg->empty() ) { /* * The operand collector writeback can generally generate a stall * However, here, the pipelines should be un-stallable. This is @@ -910,20 +922,20 @@ simd_function_unit::simd_function_unit( const shader_core_config *config ) m_dispatch_reg = new warp_inst_t(config); } -sfu::sfu( warp_inst_t **result_port, const shader_core_config *config ) +sfu::sfu( register_set* result_port, const shader_core_config *config ) : pipelined_simd_unit(result_port,config,config->max_sfu_latency) { m_name = "SFU"; } -sp_unit::sp_unit( warp_inst_t **result_port, const shader_core_config *config ) +sp_unit::sp_unit( register_set* result_port, const shader_core_config *config ) : pipelined_simd_unit(result_port,config,config->max_sp_latency) { m_name = "SP "; } -pipelined_simd_unit::pipelined_simd_unit( warp_inst_t **result_port, const shader_core_config *config, unsigned max_latency ) +pipelined_simd_unit::pipelined_simd_unit( register_set* result_port, const shader_core_config *config, unsigned max_latency ) : simd_function_unit(config) { m_result_port = result_port; @@ -1054,8 +1066,11 @@ unsigned ldst_unit::clock_multiplier() const return m_config->mem_warp_parts; } -void ldst_unit::issue( warp_inst_t *&inst ) -{ +/* Seems to be not used by anything + * */ +void ldst_unit::issue( register_set ®_set ) +{ + warp_inst_t* inst = *(reg_set.get_ready()); // stat collection m_core->mem_instruction_stats(*inst); @@ -1072,7 +1087,7 @@ void ldst_unit::issue( warp_inst_t *&inst ) } } - pipelined_simd_unit::issue(inst); + pipelined_simd_unit::issue(reg_set); } void ldst_unit::cycle() @@ -1309,7 +1324,8 @@ void warp_inst_t::print( FILE *fout ) const void shader_core_ctx::print_stage(unsigned int stage, FILE *fout ) const { - m_pipeline_reg[stage]->print(fout); + m_pipeline_reg[stage].print(fout); + //m_pipeline_reg[stage].print(fout); } void shader_core_ctx::display_simt_state(FILE *fout, int mask ) const @@ -1414,26 +1430,39 @@ void shader_core_ctx::display_pipeline(FILE *fout, int print_mem, int mask ) con } fprintf(fout,"\n"); display_simt_state(fout,mask); - + fprintf(fout, "-------------------------- Scoreboard\n"); m_scoreboard->printContents(); - +/* fprintf(fout,"ID/OC (SP) = "); print_stage(ID_OC_SP, fout); fprintf(fout,"ID/OC (SFU) = "); print_stage(ID_OC_SFU, fout); fprintf(fout,"ID/OC (MEM) = "); print_stage(ID_OC_MEM, fout); - +*/ + fprintf(fout, "-------------------------- OP COL\n"); m_operand_collector.dump(fout); - - fprintf(fout, "OC/EX (SP) = "); +/* fprintf(fout, "OC/EX (SP) = "); print_stage(OC_EX_SP, fout); fprintf(fout, "OC/EX (SFU) = "); print_stage(OC_EX_SFU, fout); fprintf(fout, "OC/EX (MEM) = "); print_stage(OC_EX_MEM, fout); - for( unsigned n=0; n < m_num_function_units; n++ ) +*/ + fprintf(fout, "-------------------------- Pipe Regs\n"); + + for (unsigned i = 0; i < N_PIPELINE_STAGES; i++) { + fprintf(fout,"--- %s ---\n",pipeline_stage_name_decode[i]); + print_stage(i,fout);fprintf(fout,"\n"); + } + + fprintf(fout, "-------------------------- Fu\n"); + for( unsigned n=0; n < m_num_function_units; n++ ){ m_fu[n]->print(fout); + fprintf(fout, "---------------\n"); + } + fprintf(fout, "-------------------------- other:\n"); + std::string bits = m_result_bus.to_string(); fprintf(fout, "EX/WB sched= %s\n", bits.c_str() ); fprintf(fout, "EX/WB = "); @@ -1978,19 +2007,20 @@ void opndcoll_rfu_t::allocate_cu( unsigned port_num ) { input_port_t& inp = m_in_ports[port_num]; for (unsigned i = 0; i < inp.m_in.size(); i++) { - if( !(*inp.m_in[i])->empty() ) { - //find a free cu + if( (*inp.m_in[i]).has_ready() ) { + //find a free cu for (unsigned j = 0; j < inp.m_cu_sets.size(); j++) { - std::vector<collector_unit_t> & cu_set = m_cus[inp.m_cu_sets[j]]; + std::vector<collector_unit_t> & cu_set = m_cus[inp.m_cu_sets[j]]; + bool allocated = false; for (unsigned k = 0; k < cu_set.size(); k++) { if(cu_set[k].is_free()) { collector_unit_t *cu = &cu_set[k]; - cu->allocate(inp.m_in[i],inp.m_out[i]); + allocated = cu->allocate(inp.m_in[i],inp.m_out[i]); m_arbiter.add_read_requests(cu); break; } } - if ((*inp.m_in[i])->empty()) break; //cu has been allocated, no need to search more. + if (allocated) break; //cu has been allocated, no need to search more. } break; // can only service a single input, if it failed it will fail for others. } @@ -2021,7 +2051,7 @@ void opndcoll_rfu_t::allocate_reads() bool opndcoll_rfu_t::collector_unit_t::ready() const { - return (!m_free) && m_not_ready.none() && (*m_output_register)->empty(); + return (!m_free) && m_not_ready.none() && (*m_output_register).has_free(); } void opndcoll_rfu_t::collector_unit_t::dump(FILE *fp, const shader_core_ctx *shader ) const @@ -2053,13 +2083,14 @@ void opndcoll_rfu_t::collector_unit_t::init( unsigned n, m_bank_warp_shift=log2_warp_size; } -void opndcoll_rfu_t::collector_unit_t::allocate( warp_inst_t** pipeline_reg, warp_inst_t** output_reg ) +bool opndcoll_rfu_t::collector_unit_t::allocate( register_set* pipeline_reg_set, register_set* output_reg_set ) { assert(m_free); assert(m_not_ready.none()); m_free = false; - m_output_register = output_reg; - if( !(*pipeline_reg)->empty() ) { + m_output_register = output_reg_set; + warp_inst_t **pipeline_reg = pipeline_reg_set->get_ready(); + if( (pipeline_reg) and !((*pipeline_reg)->empty()) ) { m_warp_id = (*pipeline_reg)->warp_id(); for( unsigned op=0; op < MAX_REG_OPERANDS; op++ ) { int reg_num = (*pipeline_reg)->arch_reg.src[op]; // this math needs to match that used in function_info::ptx_decode_inst @@ -2070,13 +2101,17 @@ void opndcoll_rfu_t::collector_unit_t::allocate( warp_inst_t** pipeline_reg, war m_src_op[op] = op_t(); } move_warp(m_warp,*pipeline_reg); + //pipeline_reg_set->move_out_to(m_warp); + return true; } + return false; } void opndcoll_rfu_t::collector_unit_t::dispatch() { assert( m_not_ready.none() ); - move_warp(*m_output_register,m_warp); + //move_warp(*m_output_register,m_warp); + m_output_register->move_in(m_warp); m_free=true; m_output_register = NULL; for( unsigned i=0; i<MAX_REG_OPERANDS*2;i++) diff --git a/src/gpgpu-sim/shader.h b/src/gpgpu-sim/shader.h index 1d481dd..5d6aa86 100644 --- a/src/gpgpu-sim/shader.h +++ b/src/gpgpu-sim/shader.h @@ -253,9 +253,9 @@ public: scheduler_unit(shader_core_stats* stats, shader_core_ctx* shader, Scoreboard* scoreboard, simt_stack** simt, std::vector<shd_warp_t>* warp, - warp_inst_t** sp_out, - warp_inst_t** sfu_out, - warp_inst_t** mem_out) + register_set* sp_out, + register_set* sfu_out, + register_set* mem_out) : supervised_warps(), m_last_sup_id_issued(0), m_stats(stats), m_shader(shader), m_scoreboard(scoreboard), m_simt_stack(simt), /*m_pipeline_reg(pipe_regs),*/ m_warp(warp), m_sp_out(sp_out),m_sfu_out(sfu_out),m_mem_out(mem_out){} @@ -275,9 +275,9 @@ private: simt_stack** m_simt_stack; //warp_inst_t** m_pipeline_reg; std::vector<shd_warp_t>* m_warp; - warp_inst_t** m_sp_out; - warp_inst_t** m_sfu_out; - warp_inst_t** m_mem_out; + register_set* m_sp_out; + register_set* m_sfu_out; + register_set* m_mem_out; }; @@ -294,7 +294,7 @@ public: m_initialized=false; } void add_cu_set(unsigned cu_set, unsigned num_cu, unsigned num_dispatch); - typedef std::vector<warp_inst_t**> port_vector_t; + typedef std::vector<register_set*> port_vector_t; typedef std::vector<unsigned int> uint_vector_t; void add_port( port_vector_t & input, port_vector_t & ouput, uint_vector_t cu_sets); void init( unsigned num_banks, shader_core_ctx *shader ); @@ -574,7 +574,7 @@ private: unsigned log2_warp_size, const core_config *config, opndcoll_rfu_t *rfu ); - void allocate( warp_inst_t** pipeline_reg, warp_inst_t** output_reg ); + bool allocate( register_set* pipeline_reg, register_set* output_reg ); void collect_operand( unsigned op ) { @@ -589,7 +589,7 @@ private: unsigned m_cuid; // collector unit hw id unsigned m_warp_id; warp_inst_t *m_warp; - warp_inst_t** m_output_register; // pipeline register to issue to when ready + register_set* m_output_register; // pipeline register to issue to when ready op_t *m_src_op; std::bitset<MAX_REG_OPERANDS*2> m_not_ready; unsigned m_num_banks; @@ -721,7 +721,7 @@ public: ~simd_function_unit() { delete m_dispatch_reg; } // modifiers - virtual void issue( warp_inst_t *&inst ) { move_warp(m_dispatch_reg,inst); } + virtual void issue( register_set& source_reg ) { source_reg.move_out_to(m_dispatch_reg); } virtual void cycle() = 0; // accessors @@ -741,13 +741,14 @@ protected: class pipelined_simd_unit : public simd_function_unit { public: - pipelined_simd_unit( warp_inst_t **result_port, const shader_core_config *config, unsigned max_latency ); + pipelined_simd_unit( register_set* result_port, const shader_core_config *config, unsigned max_latency ); //modifiers virtual void cycle() { if( !m_pipeline_reg[0]->empty() ) - move_warp(*m_result_port,m_pipeline_reg[0]); // non-stallable pipeline + //move_warp(*m_result_port,m_pipeline_reg[0]); // non-stallable pipeline + m_result_port->move_in(m_pipeline_reg[0]); for( unsigned stage=0; (stage+1)<m_pipeline_depth; stage++ ) move_warp(m_pipeline_reg[stage], m_pipeline_reg[stage+1]); if( !m_dispatch_reg->empty() ) { @@ -757,9 +758,11 @@ public: } } } - virtual void issue( warp_inst_t *&inst ) + + virtual void issue( register_set& source_reg ) { - move_warp(m_dispatch_reg,inst); + //move_warp(m_dispatch_reg,source_reg); + source_reg.move_out_to(m_dispatch_reg); } // accessors @@ -781,13 +784,13 @@ public: protected: unsigned m_pipeline_depth; warp_inst_t **m_pipeline_reg; - warp_inst_t **m_result_port; + register_set *m_result_port; }; class sfu : public pipelined_simd_unit { public: - sfu( warp_inst_t **result_port, const shader_core_config *config ); + sfu( register_set* result_port, const shader_core_config *config ); virtual bool can_issue( const warp_inst_t &inst ) const { switch(inst.op) { @@ -802,7 +805,7 @@ public: class sp_unit : public pipelined_simd_unit { public: - sp_unit( warp_inst_t **result_port, const shader_core_config *config ); + sp_unit( register_set* result_port, const shader_core_config *config ); virtual bool can_issue( const warp_inst_t &inst ) const { switch(inst.op) { @@ -834,7 +837,7 @@ public: unsigned sid, unsigned tpc ); // modifiers - virtual void issue( warp_inst_t *&inst ); + virtual void issue( register_set &inst ); virtual void cycle(); void fill( mem_fetch *mf ); @@ -907,8 +910,22 @@ enum pipeline_stage_name_t { N_PIPELINE_STAGES }; +const char* const pipeline_stage_name_decode[] = { + "ID_OC_SP", + "ID_OC_SFU", + "ID_OC_MEM", + "OC_EX_SP", + "OC_EX_SFU", + "OC_EX_MEM", + "EX_WB", + "N_PIPELINE_STAGES" +}; + struct shader_core_config : public core_config { + shader_core_config(){ + pipeline_widths_string = NULL; + } void init() { int ntok = sscanf(gpgpu_shader_core_pipeline_opt,"%d:%d", @@ -917,7 +934,21 @@ struct shader_core_config : public core_config if(ntok != 2) { printf("GPGPU-Sim uArch: error while parsing configuration string gpgpu_shader_core_pipeline_opt\n"); abort(); - } + } + + char* toks = new char[100]; + char* tokd = toks; + strcpy(toks,pipeline_widths_string); + + toks = strtok(toks,","); + for (unsigned i = 0; i < N_PIPELINE_STAGES; i++) { + assert(toks); + ntok = sscanf(toks,"%d", &pipe_widths[i]); + assert(ntok == 1); + toks = strtok(NULL,","); + } + delete tokd; + if (n_thread_per_shader > MAX_THREAD_PER_SM) { printf("GPGPU-Sim uArch: Error ** increase MAX_THREAD_PER_SM in abstract_hardware_model.h from %u to %u\n", MAX_THREAD_PER_SM, n_thread_per_shader); @@ -949,7 +980,10 @@ struct shader_core_config : public core_config unsigned n_thread_per_shader; unsigned max_warps_per_shader; unsigned max_cta_per_core; //Limit on number of concurrent CTAs in shader core - + + char* pipeline_widths_string; + int pipe_widths[N_PIPELINE_STAGES]; + cache_config m_L1I_config; cache_config m_L1T_config; cache_config m_L1C_config; @@ -976,6 +1010,10 @@ struct shader_core_config : public core_config unsigned int gpgpu_operand_collector_num_out_ports_mem; unsigned int gpgpu_operand_collector_num_out_ports_gen; + int gpgpu_num_sp_units; + int gpgpu_num_sfu_units; + int gpgpu_num_mem_units; + //Shader core resources unsigned gpgpu_shader_registers; int gpgpu_warpdistro_shader; @@ -1175,7 +1213,7 @@ private: void issue(); friend class scheduler_unit; //this is needed to use private issue warp. - void issue_warp( warp_inst_t *&warp, const warp_inst_t *pI, const active_mask_t &active_mask, unsigned warp_id ); + void issue_warp( register_set& warp, const warp_inst_t *pI, const active_mask_t &active_mask, unsigned warp_id ); void func_exec_inst( warp_inst_t &inst ); // Returns numbers of addresses in translated_addrs @@ -1224,7 +1262,7 @@ private: std::vector<shd_warp_t> m_warp; // per warp information array barrier_set_t m_barriers; ifetch_buffer_t m_inst_fetch_buffer; - warp_inst_t **m_pipeline_reg; + std::vector<register_set> m_pipeline_reg; Scoreboard *m_scoreboard; opndcoll_rfu_t m_operand_collector; @@ -1233,9 +1271,9 @@ private: // execute unsigned m_num_function_units; - enum pipeline_stage_name_t *m_dispatch_port; - enum pipeline_stage_name_t *m_issue_port; - simd_function_unit **m_fu; // stallable pipelines should be last in this array + std::vector<pipeline_stage_name_t> m_dispatch_port; + std::vector<pipeline_stage_name_t> m_issue_port; + std::vector<simd_function_unit*> m_fu; // stallable pipelines should be last in this array ldst_unit *m_ldst_unit; static const unsigned MAX_ALU_LATENCY = 64; std::bitset<MAX_ALU_LATENCY> m_result_bus; |
