URL
https://opencores.org/ocsvn/sardmips/sardmips/trunk
Subversion Repositories sardmips
Compare Revisions
- This comparison shows the changes necessary to convert path
/
- from Rev 1 to Rev 2
- ↔ Reverse comparison
Rev 1 → Rev 2
/trunk/cpu/cpu/id_stage/reg_id.h
0,0 → 1,79
#include "systemc.h" |
#include "../../constants/constants.h" |
|
SC_MODULE(reg_id) |
{ |
sc_in<bool> in_clk; |
sc_in<bool> reset; |
sc_in<bool> datahold; |
sc_in<bool> insthold; |
|
sc_out<sc_lv<32> > id_ex_alu1; |
sc_in<sc_lv<32> > id_alu1; |
|
sc_out<sc_lv<32> > id_ex_alu2; |
sc_in<sc_lv<32> > id_alu2; |
|
sc_out<sc_lv<32> > id_ex_datastore; |
sc_in<sc_lv<32> > id_mux_fw2; |
|
sc_out<sc_lv<6> > id_ex_alu_ctrl; |
sc_in<sc_lv<6> > id_alu_ctrl; |
|
sc_out<sc_lv<5> > id_ex_alu_sa; |
sc_in<sc_lv<5> > id_alu_sa; |
|
sc_out<sc_logic> id_ex_equal; |
sc_in<sc_logic> id_equal; |
|
sc_out<sc_logic> id_ex_datareq; |
sc_in<sc_logic> id_datareq; |
|
sc_out<sc_logic> id_ex_datarw; |
sc_in<sc_logic> id_datarw; |
|
sc_out<sc_logic> id_ex_memtoreg; |
sc_in<sc_logic> id_memtoreg; |
|
sc_out<sc_lv<5> > id_ex_writeregister_out; |
sc_in<sc_lv<5> > id_writeregister; |
|
sc_out<sc_lv<5> > id_ex_writeregister; |
//sc_in<sc_lv<5> > id_writeregister; |
|
sc_out<sc_logic> id_ex_regwrite_out; |
sc_in<sc_logic> id_regwrite; |
|
sc_out<sc_logic> id_ex_regwrite; |
//sc_in<sc_logic> id_regwrite; |
|
sc_out<sc_lv<2> > id_ex_byteselect; |
sc_in<sc_lv<2> > id_byteselect; |
|
sc_out<sc_logic> id_ex_bssign; |
sc_in<sc_logic> id_bssign; |
|
// EXCEPTIONS SIGNALS |
sc_in<sc_logic> illegal_instruction; |
sc_in<sc_logic> syscall_exception; |
sc_in<sc_logic> if_id_IBUS; |
sc_in<sc_logic> if_id_inst_addrl; |
sc_out<sc_logic> id_ex_IBUS; |
sc_out<sc_logic> id_ex_inst_addrl; |
sc_out<sc_logic> id_ex_syscall_exception; |
sc_out<sc_logic> id_ex_illegal_instruction; |
|
sc_in<sc_uint<32> > if_id_instaddr; |
sc_out<sc_uint<32> > id_ex_instaddr; |
|
sc_in<sc_logic> enable_decode; |
|
void do_reg_id(); |
|
SC_CTOR(reg_id) |
{ |
SC_METHOD(do_reg_id); |
sensitive_pos << reset; |
sensitive_pos << in_clk; |
} |
}; |
/trunk/cpu/cpu/id_stage/mux_alu1.h
0,0 → 1,23
#include "systemc.h" |
#include "../../constants/constants.h" |
|
SC_MODULE(mux_alu1) |
{ |
sc_in<sc_lv<32> > if_id_inst; |
sc_in<sc_logic> id_shamt_ctrl; |
sc_in<sc_logic> id_pc_store; |
sc_out<sc_lv<32> > id_alu1; |
sc_in<sc_lv<32> > if_id_next_pc; |
sc_in<sc_lv<32> > cp0_reg_out; |
sc_in<sc_lv<32> > id_mux_fw1; |
sc_in<sc_logic> id_mfc0; |
|
void do_mux_alu1(); |
|
SC_CTOR(mux_alu1) |
{ |
SC_METHOD(do_mux_alu1); |
sensitive << id_pc_store << id_shamt_ctrl << if_id_inst << id_mux_fw1; |
sensitive << if_id_next_pc << cp0_reg_out << id_mfc0; |
} |
}; |
/trunk/cpu/cpu/id_stage/mux_forward_select.h
0,0 → 1,21
#include "systemc.h" |
#include "../../constants/constants.h" |
|
SC_MODULE(mux_forward_select) |
{ |
sc_in<sc_lv<32> > id_reg; |
sc_in<sc_lv<32> > ex_id_forward; |
sc_in<sc_lv<32> > m_id_forward; |
sc_in<sc_lv<32> > wb_id_forward; |
sc_in<sc_lv<2> > id_fw_ctrl; |
|
sc_out<sc_lv<32> > id_mux_fw; |
|
void do_mux_forward_select(); |
|
SC_CTOR(mux_forward_select) |
{ |
SC_METHOD(do_mux_forward_select); |
sensitive << id_reg << ex_id_forward << m_id_forward << wb_id_forward << id_fw_ctrl; |
} |
}; |
/trunk/cpu/cpu/id_stage/mux_alu2.h
0,0 → 1,19
#include "systemc.h" |
#include "../../constants/constants.h" |
|
SC_MODULE(mux_alu2) |
{ |
sc_in<sc_lv<32> > id_sign_extend; |
sc_in<sc_lv<2> > id_sign_ctrl; |
sc_out<sc_lv<32> > id_alu2; |
sc_out<sc_lv<32> > cp0_reg_rs; |
sc_in<sc_lv<32> > id_mux_fw2; |
|
void do_mux_alu2(); |
|
SC_CTOR(mux_alu2) |
{ |
SC_METHOD(do_mux_alu2); |
sensitive << id_mux_fw2 << id_sign_extend << id_sign_ctrl; |
} |
}; |
/trunk/cpu/cpu/id_stage/forwarding_control.cpp
0,0 → 1,21
#include "forwarding_control.h" |
|
void forwarding_control::do_forwarding_control() |
{ |
if ((id_ex_writeregister.read() == rs.read()) && (id_ex_regwrite.read() == 1)) |
{ |
id_fw_ctrl.write("01"); |
} |
else if ((id_ex_m_writeregister.read() == rs.read()) && (id_ex_m_regwrite.read() == 1)) |
{ |
id_fw_ctrl.write("10"); |
} |
else if ((id_ex_m_wb_writeregister.read() == rs.read()) && (id_ex_m_wb_regwrite.read() == 1)) |
{ |
id_fw_ctrl.write("11"); |
} |
else |
{ |
id_fw_ctrl.write("00"); |
} |
} |
/trunk/cpu/cpu/id_stage/mux_jump.cpp
0,0 → 1,16
#include "mux_jump.h" |
|
void mux_jump::do_mux_jump() |
{ |
sc_lv<32> iinp = if_id_next_pc.read(); |
sc_lv<32> iii = if_id_inst.read(); |
|
if(id_select_jump == SC_LOGIC_0) |
{ |
id_jmp_tar.write((iinp.range(31,28),iii.range(25,0),"00")); |
} |
else |
{ |
id_jmp_tar.write(id_mux_fw1.read()); |
} |
} |
/trunk/cpu/cpu/id_stage/sign_extend.cpp
0,0 → 1,23
#include "sign_extend.h" |
|
void sign_extend::do_sign_extend() |
{ |
sc_lv<32> inst = if_id_inst.read(); |
sc_lv<2> iec = id_extend_ctrl.read(); |
|
if( iec == "00") |
if(inst[15] == SC_LOGIC_1) |
id_sign_extend = (HALFWORD_ONE,inst.range(15,0)); |
else |
id_sign_extend = (HALFWORD_ZERO,inst.range(15,0)); |
|
else |
if( iec == "01") |
id_sign_extend = (HALFWORD_ZERO,inst.range(15,0)); |
else |
if( iec == "10") |
id_sign_extend = (inst.range(15,0),HALFWORD_ZERO); |
else |
id_sign_extend = WORD_ZERO; |
|
} |
/trunk/cpu/cpu/id_stage/comparator.cpp
0,0 → 1,61
#include "comparator.h" |
|
void comparator::do_comparator() |
{ |
sc_logic result; |
|
sc_lv<32> ss = id_mux_fw1.read(); |
sc_lv<32> tt = id_mux_fw2.read(); |
|
|
sc_int<32> sss = ss; |
sc_int<32> ttt = tt; |
sc_lv<3> ibs = id_branch_select.read(); |
result = SC_LOGIC_0; |
|
if(ibs == "000") |
result = SC_LOGIC_0; |
else if(ibs == "001") |
{ |
result = SC_LOGIC_0; |
PRINT("***** ERROR COMPARATOR ****** "); |
} |
else if(ibs == "010") // beq |
if( sss == ttt ) |
result = SC_LOGIC_1; |
else |
result = SC_LOGIC_0; |
else if(ibs == "011") // bne |
if( sss != ttt) |
result = SC_LOGIC_1; |
else |
result = SC_LOGIC_0; |
else if(ibs == "100") // bltz |
if( sss < 0) |
result = SC_LOGIC_1; |
else |
result = SC_LOGIC_0; |
else if(ibs == "101") // blez |
if( sss <= 0) |
result = SC_LOGIC_1; |
else |
result = SC_LOGIC_0; |
else if(ibs == "110") // bgtz |
// Vil ikke godtage sss > 0 til verilog |
// if( !(sss <= 0) ) |
if ( sss > 0 ) |
result = SC_LOGIC_1; |
else |
result = SC_LOGIC_0; |
else if(ibs == "111") |
if( sss >= 0) |
result = SC_LOGIC_1; |
else |
result = SC_LOGIC_0; |
else |
result = SC_LOGIC_0; |
|
id_equal.write(result); |
id_branch.write(result); |
} |
|
/trunk/cpu/cpu/id_stage/decode_ctrl.cpp
0,0 → 1,13
#include "decode_ctrl.h" |
|
void decode_ctrl::do_decode_ctrl() |
{ |
if((if_id_IBUS.read() == SC_LOGIC_1) || |
(if_id_inst_addrl.read() == SC_LOGIC_1) || |
(syscall_exception.read() == SC_LOGIC_1) || |
(illegal_instruction.read() == SC_LOGIC_1)) |
id_exception.write(SC_LOGIC_1); |
else |
id_exception.write(SC_LOGIC_0); |
|
}; |
/trunk/cpu/cpu/id_stage/forwarding_control.h
0,0 → 1,24
#include "systemc.h" |
#include "../../constants/constants.h" |
|
SC_MODULE(forwarding_control) |
{ |
sc_in<sc_lv<5> > id_ex_writeregister; |
sc_in<sc_lv<5> > id_ex_m_writeregister; |
sc_in<sc_lv<5> > id_ex_m_wb_writeregister; |
sc_in<sc_logic> id_ex_regwrite; |
sc_in<sc_logic> id_ex_m_regwrite; |
sc_in<sc_logic> id_ex_m_wb_regwrite; |
sc_in<sc_lv<5> > rs; |
sc_out<sc_lv<2> > id_fw_ctrl; |
|
void do_forwarding_control(); |
|
SC_CTOR(forwarding_control) |
{ |
SC_METHOD(do_forwarding_control); |
sensitive << id_ex_writeregister << id_ex_m_writeregister; |
sensitive << id_ex_m_wb_writeregister << id_ex_regwrite; |
sensitive << id_ex_m_regwrite << id_ex_m_wb_regwrite << rs; |
} |
}; |
/trunk/cpu/cpu/id_stage/mux_jump.h
0,0 → 1,20
#include "systemc.h" |
#include "../../constants/constants.h" |
#include "../../constants/config.h" |
|
SC_MODULE(mux_jump) |
{ |
sc_in<sc_lv<32> > if_id_next_pc; |
sc_in<sc_lv<32> > if_id_inst; |
sc_in<sc_logic> id_select_jump; |
sc_in<sc_lv<32> > id_mux_fw1; |
sc_out<sc_lv<32> > id_jmp_tar; |
|
void do_mux_jump(); |
|
SC_CTOR(mux_jump) |
{ |
SC_METHOD(do_mux_jump); |
sensitive << id_select_jump << if_id_inst << if_id_next_pc << id_mux_fw1; |
} |
}; |
/trunk/cpu/cpu/id_stage/sign_extend.h
0,0 → 1,18
#include "systemc.h" |
#include "../../constants/constants.h" |
#include "../../constants/config.h" |
|
SC_MODULE(sign_extend) |
{ |
sc_in<sc_lv<32> > if_id_inst; |
sc_in<sc_lv<2> > id_extend_ctrl; |
sc_out<sc_lv<32> > id_sign_extend; |
|
void do_sign_extend(); |
|
SC_CTOR(sign_extend) |
{ |
SC_METHOD(do_sign_extend); |
sensitive << if_id_inst << id_extend_ctrl; |
} |
}; |
/trunk/cpu/cpu/id_stage/regfile_high.cpp
0,0 → 1,44
//! |
/* |
No description |
*/ |
#include "../../constants/config.h" |
|
// #ifdef _HIGH_LEVEL_SIM_ |
#include "regfile_high.h" |
|
void regfile::storeregister() |
{ |
sc_lv<5> d = rd; |
if(reset.read() == true) |
{ |
for(int i = 0; i<32; i++) |
r[i] = WORD_ZERO; |
} |
else |
{ |
if(wr == SC_LOGIC_1) |
r[(sc_uint<5>) d] = rd_in; |
} |
} |
|
//! Load register outputs |
/*! |
Sets the register file output signals according the inputs |
*/ |
void regfile::loadregister() |
{ |
sc_lv<5> t = rt; |
sc_lv<5> s = rs; |
|
if(s == "00000") |
rs_out = WORD_ZERO; |
else |
rs_out = r[(sc_uint<5>) s]; |
|
if(t == "00000") |
rt_out = WORD_ZERO; |
else |
rt_out = r[(sc_uint<5>) t]; |
} |
// #endif |
/trunk/cpu/cpu/id_stage/comparator.h
0,0 → 1,20
#include "systemc.h" |
#include "../../constants/constants.h" |
|
SC_MODULE(comparator) |
{ |
sc_in<sc_lv<32> > id_mux_fw1; |
sc_in<sc_lv<32> > id_mux_fw2; |
sc_in<sc_lv<3> > id_branch_select; |
sc_out<sc_logic> id_equal; |
sc_out<sc_logic> id_branch; |
|
void do_comparator(); |
|
SC_CTOR(comparator) |
{ |
SC_METHOD(do_comparator); |
sensitive << id_mux_fw1 << id_mux_fw2; |
sensitive << id_branch_select; |
} |
}; |
/trunk/cpu/cpu/id_stage/decode_ctrl.h
0,0 → 1,20
#include "systemc.h" |
#include "../../constants/constants.h" |
|
SC_MODULE(decode_ctrl) |
{ |
sc_in<sc_logic> if_id_IBUS; |
sc_in<sc_logic> if_id_inst_addrl; |
sc_in<sc_logic> illegal_instruction; |
sc_in<sc_logic> syscall_exception; |
sc_out<sc_logic> id_exception; |
|
void do_decode_ctrl(); |
|
SC_CTOR(decode_ctrl) |
{ |
SC_METHOD(do_decode_ctrl); |
sensitive << if_id_IBUS << if_id_inst_addrl; |
sensitive << syscall_exception << illegal_instruction; |
} |
}; |
/trunk/cpu/cpu/id_stage/id_stage.cpp
0,0 → 1,20
#include "id_stage.h" |
/trunk/cpu/cpu/id_stage/control.cpp
0,0 → 1,476
#include "control.h" |
|
|
void control::do_control() |
{ |
|
sc_logic n0 = SC_LOGIC_0; |
sc_logic n1 = SC_LOGIC_1; |
|
sc_lv<32> inst = if_id_inst; |
sc_lv<6> func = inst.range(5,0); |
sc_lv<6> op = inst.range(31,26); |
|
sc_lv<5> lrs, lrt, lrd, lsa; // lv version of reg # |
sc_uint<5> uirs, uirt, uird, uisa; // unsigned integer version of reg # |
sc_int<32> is, it, id; // integer version of register contents... |
|
//! The immediate value in an instruction |
sc_lv<16> imm; |
sc_lv<32> imm_sign, imm_zero; |
sc_int<32> iimm_sign, iimm_zero; |
sc_uint<32> uiimm_sign, uiimm_zero; |
sc_lv<28> instr_index; |
sc_uint<28> uiinstr_index; |
|
// register destinations and recipients |
rs.write(inst.range(25,21)); |
rt.write(inst.range(20,16)); |
rd.write(inst.range(15,11)); |
|
uirs = lrs = inst.range(25,21); |
uirt = lrt = inst.range(20,16); |
uird = lrd = inst.range(15,11); |
uisa = lsa = inst.range(10,6); |
|
// signals for selection bytes and sign of lw/sw instructions |
sc_lv<2> byteselect = "00"; |
sc_logic id_bssign = SC_LOGIC_0; |
|
#ifdef _HIGH_LEVEL_SIM_ |
is = 0; // localreg->r[uirs]; |
it = 0; // localreg->r[uirt]; |
id = 0; // localreg->r[uird]; |
#endif |
|
|
// Immediate values |
imm = inst.range(15,0); |
uiimm_zero = iimm_zero = imm_zero = (HALFWORD_ZERO,imm); |
if( imm[15] == '1') |
uiimm_sign = iimm_sign = imm_sign = (HALFWORD_ONE,imm); |
else |
uiimm_sign = iimm_sign = imm_sign = (HALFWORD_ZERO,imm); |
|
uiinstr_index = instr_index = (inst.range(25,0), "00"); |
|
id_alu_ctrl.write(func); |
id_alu_sa.write(inst.range(10,6)); |
id_ctrl.write(n0); |
id_extend_ctrl.write("00"); |
id_sign_ctrl.write("00"); |
regdest.write("00"); |
id_select_jump.write(n0); |
id_pc_store.write(n0); |
id_branch_select.write("000"); |
id_regwrite.write(n0); |
id_shamt_ctrl.write(n0); |
id_datarw.write(n0); |
id_datareq.write(n0); |
id_memtoreg.write(n0); |
|
// Signals to cp0 |
cp0_inst.write(CP0_NOTHING); // 4 bit... |
// cp0_reg_rs will be set directly from forward-MUX |
cp0_reg_no.write(uird); |
cp0_reg_rw.write(SC_LOGIC_0); // default value...don't write! |
id_mfc0.write(SC_LOGIC_0); |
sc_logic cpo_co = inst[25]; |
|
illegal_instruction.write(SC_LOGIC_0); |
syscall_exception.write(SC_LOGIC_0); |
|
#ifdef ONEHOT_DEBUG |
inst_addiu.write(SC_LOGIC_0); |
inst_jalr.write(SC_LOGIC_0); |
inst_lw.write(SC_LOGIC_0); |
inst_mfc0.write(SC_LOGIC_0); |
inst_mtc0.write(SC_LOGIC_0); |
inst_nop.write(SC_LOGIC_0); |
inst_sw.write(SC_LOGIC_0); |
inst_wait.write(SC_LOGIC_0); |
#endif |
|
//switch stage |
if(op == OP_RFORMAT) |
{ |
if(func == FUNC_JR) |
{ |
id_ctrl.write(n1); |
id_select_jump.write(n1); |
id_alu_ctrl.write("000000"); |
} |
else if(func == FUNC_JALR) |
{ |
#ifdef ONEHOT_DEBUG |
inst_jalr.write(SC_LOGIC_1); |
#endif |
id_ctrl.write(n1); |
id_select_jump.write(n1); |
id_pc_store.write(n1); |
id_regwrite.write(n1); |
id_alu_ctrl.write(FUNC_ADDU); |
id_sign_ctrl.write("10"); |
} |
|
else |
if(func == FUNC_MULT) |
{ |
id_alu_ctrl.write(FUNC_MULT); |
id_regwrite.write(n0); |
} |
else if(func == FUNC_MFLO) |
{ |
id_alu_ctrl.write(FUNC_MFLO); |
id_regwrite.write(n1); |
} |
|
else if(func == FUNC_MTHI) |
{ |
id_alu_ctrl.write(FUNC_MTHI); |
id_regwrite.write(n1); |
} |
|
else if(func == FUNC_MULTU) |
{ |
id_alu_ctrl.write(FUNC_MULTU); |
id_regwrite.write(n0); |
} |
|
|
else if(func == FUNC_DIV) |
{ |
id_alu_ctrl.write(FUNC_DIV); |
} |
|
else if(func == FUNC_DIVU) |
{ |
id_alu_ctrl.write(FUNC_DIVU); |
} |
|
else if(func == FUNC_SLL || |
func == FUNC_SRL || |
func == FUNC_SRA) |
{ |
id_shamt_ctrl.write(n1); |
id_regwrite.write(n1); |
#ifdef ONEHOT_DEBUG |
inst_nop.write(SC_LOGIC_1); |
#endif |
} |
else if(func == FUNC_SLLV || |
func == FUNC_SRLV || |
func == FUNC_SRAV || |
func == FUNC_MFHI || |
func == FUNC_MFLO || |
func == FUNC_ADD || |
func == FUNC_ADDU || |
func == FUNC_SUB || |
func == FUNC_SUBU || |
func == FUNC_AND || |
func == FUNC_OR || |
func == FUNC_XOR || |
func == FUNC_NOR || |
func == FUNC_SLT || |
func == FUNC_SLTU) |
{ |
id_regwrite.write(n1); |
} |
#ifdef _INCLUDE_CP0_ |
else if (func == FUNC_BREAK) |
{ |
cp0_inst.write(CP0_BREAK); |
} |
else if (func == FUNC_SYSCALL) |
{ |
cp0_inst.write(CP0_SYSCALL); |
syscall_exception.write(SC_LOGIC_1); |
} |
#else |
else if (func == FUNC_BREAK || func == FUNC_SYSCALL) |
{ |
|
//sc_stop(); |
} |
#endif |
else |
{ |
illegal_instruction.write(SC_LOGIC_1); |
cout << " illegal instruction " << endl; |
//sc_stop(); |
} |
} |
else if(op == OP_BRANCH) |
{ |
// PRINTLN("Branch format"); |
if(lrt.range(1,0) == BRANCH_BLTZ) |
{ |
id_branch_select.write("100"); |
} |
else if(lrt.range(1,0) == BRANCH_BGEZ) |
{ |
id_branch_select.write("111"); |
} |
else if(lrt.range(1,0) == BRANCH_BLTZAL) |
{ |
id_branch_select.write("100"); |
id_pc_store.write(n1); |
id_sign_ctrl.write("10"); |
regdest.write("10"); |
id_regwrite.write(n1); |
id_alu_ctrl.write(FUNC_ADDU); |
} |
else if(lrt.range(1,0) == BRANCH_BGEZAL) |
{ |
id_branch_select.write("111"); |
id_pc_store.write(n1); |
id_sign_ctrl.write("10"); |
regdest.write("10"); |
id_regwrite.write(n1); |
id_alu_ctrl.write(FUNC_ADDU); |
} |
else illegal_instruction.write(SC_LOGIC_1); |
} |
else if(op == OP_J) |
{ |
id_ctrl.write(n1); |
} |
else if(op == OP_JAL) |
{ |
id_ctrl.write(n1); |
id_pc_store.write(n1); |
// add 8 in total |
id_alu_ctrl.write(FUNC_ADDU); |
id_sign_ctrl.write("10"); |
regdest.write("10"); |
id_regwrite.write(n1); |
} |
else if(op == OP_BEQ) |
{ |
id_branch_select.write("010"); |
} |
else if(op == OP_BNE) |
{ |
id_branch_select.write("011"); |
} |
else if(op == OP_BLEZ) |
{ |
id_branch_select.write("101"); |
} |
else if(op == OP_BGTZ) |
{ |
id_branch_select.write("110"); |
} |
else if(op == OP_ADDI) |
{ |
id_alu_ctrl.write(FUNC_ADD); |
regdest.write("01"); |
id_sign_ctrl.write("01"); |
id_regwrite.write(n1); |
} |
else if(op == OP_ADDIU) |
{ |
id_alu_ctrl.write(FUNC_ADDU); |
regdest.write("01"); |
id_sign_ctrl.write("01"); |
id_regwrite.write(n1); |
#ifdef ONEHOT_DEBUG |
inst_addiu.write(SC_LOGIC_1); |
#endif |
} |
else if(op == OP_SLTI) |
{ |
id_alu_ctrl.write(FUNC_SLT); |
regdest.write("01"); |
id_sign_ctrl.write("01"); |
id_regwrite.write(n1); |
} |
else if(op == OP_SLTIU) |
{ |
id_alu_ctrl.write(FUNC_SLTU); |
regdest.write("01"); |
id_sign_ctrl.write("01"); |
id_regwrite.write(n1); |
} |
else if(op == OP_ANDI) |
{ |
id_alu_ctrl.write(FUNC_AND); |
regdest.write("01"); |
id_sign_ctrl.write("01"); |
id_extend_ctrl.write("01"); |
id_regwrite.write(n1); |
} |
else if(op == OP_ORI) |
{ |
id_alu_ctrl.write(FUNC_OR); |
regdest.write("01"); |
id_sign_ctrl.write("01"); |
id_extend_ctrl.write("01"); |
id_regwrite.write(n1); |
} |
else if(op == OP_XORI) |
{ |
id_alu_ctrl.write(FUNC_XOR); |
regdest.write("01"); |
id_sign_ctrl.write("01"); |
id_extend_ctrl.write("01"); |
id_regwrite.write(n1); |
} |
else if(op == OP_LUI) |
{ |
id_alu_ctrl.write(FUNC_ADDU); |
regdest.write("01"); |
id_sign_ctrl.write("01"); |
id_extend_ctrl.write("10"); |
id_regwrite.write(n1); |
} |
else if(op == OP_LB || |
op == OP_LH || |
op == OP_LWL || |
op == OP_LW || |
op == OP_LBU || |
op == OP_LHU || |
op == OP_LWR) |
{ |
id_alu_ctrl.write(FUNC_ADDU); |
id_regwrite.write(n1); |
regdest.write("01"); |
id_datareq.write(n1); |
id_memtoreg.write(n1); |
id_sign_ctrl.write("01"); |
// Select bytes to be read! |
if (op == OP_LB || op == OP_LBU) |
byteselect = "01"; |
else if (op == OP_LH || op == OP_LHU) |
byteselect = "10"; |
else |
byteselect = "00"; |
// select to sign_extend or not |
if ((op == OP_LBU) || (op == OP_LHU)) |
id_bssign = SC_LOGIC_1; |
#ifdef ONEHOT_DEBUG |
inst_lw = SC_LOGIC_1; |
#endif |
} |
else if(op == OP_SB || |
op == OP_SH || |
op == OP_SWL || |
op == OP_SW || |
op == OP_SWR) |
{ |
id_alu_ctrl.write(FUNC_ADDU); |
id_datarw.write(n1); |
id_datareq.write(n1); |
id_memtoreg.write(n1); |
id_sign_ctrl.write("01"); |
// Select bytes to be written |
if (op == OP_SB) |
byteselect = "01"; |
else if (op == OP_SH) |
byteselect = "10"; |
else |
byteselect = "00"; |
#ifdef ONEHOT_DEBUG |
inst_sw = SC_LOGIC_1; |
#endif |
} |
#ifdef _INCLUDE_CP0_ |
else if(op == OP_CACHE) |
{ |
cp0_inst.write(CP0_CACHE); |
} |
#endif |
/*! |
In order to include co-processor you need to enable it in the config file. |
*/ |
else |
if(op == OP_COPROC0) |
{ |
if(cpo_co == SC_LOGIC_1) |
{ |
if(func == FUNC_TLBR) |
{ |
cp0_inst.write(CP0_TLBR); |
} |
else |
if(func == FUNC_TLBWI) |
{ |
cp0_inst.write(CP0_TLBWI); |
} |
else |
if(func == FUNC_TLBWR) |
{ |
cp0_inst.write(CP0_TLBWR); |
} |
else |
if(func == FUNC_TLBP) |
{ |
cp0_inst.write(CP0_TLBP); |
} |
else |
if(func == FUNC_ERET) |
{ |
cp0_inst.write(CP0_ERET); |
} |
else |
if(func == FUNC_DERET) |
{ |
cp0_inst.write(CP0_DERET); |
} |
else |
if(func == FUNC_WAIT) |
{ |
cp0_inst.write(CP0_WAIT); |
// Do same actions as jalr...except jump! |
id_ctrl.write(n0); |
id_select_jump.write(n0); |
id_pc_store.write(n1); |
id_regwrite.write(n1); |
id_alu_ctrl.write(FUNC_ADDU); |
id_sign_ctrl.write("10"); |
#ifdef ONEHOT_DEBUG |
inst_wait.write(SC_LOGIC_1); |
#endif |
} |
} |
else |
{ |
if(lrs == RS_MFC0) |
{ |
cp0_inst.write(CP0_MFC0); |
cp0_reg_rw.write(SC_LOGIC_0); |
id_mfc0.write(SC_LOGIC_1); |
|
id_alu_ctrl.write(FUNC_ADDU); |
regdest.write("01"); |
id_sign_ctrl.write("00"); |
id_regwrite.write(n1); |
#ifdef ONEHOT_DEBUG |
inst_mfc0.write(SC_LOGIC_1); |
#endif |
} |
else |
if(lrs == RS_MTC0) |
{ |
cp0_inst.write(CP0_MTC0); |
cp0_reg_rw.write(SC_LOGIC_1); |
id_alu_ctrl.write(FUNC_ADDU); |
cp0_reg_no.write(uird); |
id_mfc0.write(SC_LOGIC_0); |
#ifdef ONEHOT_DEBUG |
inst_mtc0.write(SC_LOGIC_1); |
#endif |
} |
} |
//cout << "illegal instruction " << endl; |
//illegal_instruction.write(SC_LOGIC_1); |
} |
|
else |
{ |
illegal_instruction.write(SC_LOGIC_1); |
cout << " illegal instruction " << endl; |
//sc_stop(); |
} |
id_byteselect = byteselect; |
} |
/trunk/cpu/cpu/id_stage/regfile_high.h
0,0 → 1,44
// |
// $Id: regfile_high.h,v 1.1 2006-01-21 03:37:36 igorloi Exp $ |
// |
|
#ifndef _REGFILE_H |
#define _REGFILE_H |
|
#include <systemc.h> |
#include "../../constants/config.h" |
#include "../../constants/constants.h" |
|
SC_MODULE(regfile) |
{ |
// default input |
sc_in<bool> in_clk; |
sc_in<bool> reset; |
sc_in<sc_lv<5> > rs; |
sc_in<sc_lv<5> > rt; |
sc_in<sc_logic> wr; |
sc_in<sc_lv<32> > rd_in; |
sc_in<sc_lv<5> > rd; |
sc_out<sc_lv<32> > rs_out; |
sc_out<sc_lv<32> > rt_out; |
|
sc_signal<sc_lv<32> > r[32]; |
|
void storeregister(); |
void loadregister(); |
|
SC_CTOR(regfile) |
{ |
SC_METHOD(storeregister); |
sensitive_neg << in_clk; |
|
SC_METHOD(loadregister); |
sensitive << rs << rt << in_clk; |
} |
}; |
|
#endif |
|
|
|
|
/trunk/cpu/cpu/id_stage/add_new_pc.cpp
0,0 → 1,6
#include "add_new_pc.h" |
|
void add_new_pc::do_add_new_pc() |
{ |
id_new_pc.write(((sc_int<32>) (if_id_next_pc.read())) + (((sc_int<32>) (id_sign_extend.read()) << 2))); |
} |
/trunk/cpu/cpu/id_stage/id_stage.h
0,0 → 1,311
#include "systemc.h" |
#include "./id_stage/control.h" |
#include "./id_stage/mux_writeregister.h" |
#include "./id_stage/sign_extend.h" |
#include "./id_stage/add_new_pc.h" |
#include "./id_stage/mux_jump.h" |
#include "./id_stage/mux_forward_select.h" |
#include "./id_stage/mux_alu1.h" |
#include "./id_stage/mux_alu2.h" |
#include "./id_stage/comparator.h" |
#include "./id_stage/forwarding_control.h" |
#include "./id_stage/reg.h" |
|
#include "./id_stage/regfile_high.h" |
|
#include "../constants/config.h" |
#include "../constants/constants.h" |
|
SC_MODULE(id_stage) |
{ |
sc_in<bool> in_clk; |
sc_in<bool> reset; |
|
sc_in<bool> insthold; |
sc_in<bool> datahold; |
|
sc_in<sc_lv<32> > if_id_next_pc; |
sc_in<sc_lv<32> > if_id_inst; |
|
// signal to if_stage NOT clk |
sc_out<sc_lv<32> > id_jmp_tar; |
sc_out<sc_lv<32> > id_new_pc; |
sc_out<sc_logic> id_branch; |
sc_out<sc_logic> id_ctrl; |
|
// signal to ex_stage |
sc_out<sc_lv<32> > id_ex_alu1; |
sc_out<sc_lv<32> > id_ex_alu2; |
sc_out<sc_lv<32> > id_ex_datastore; |
sc_out<sc_lv<6> > id_ex_alu_ctrl; |
sc_out<sc_logic> id_ex_equal; |
sc_out<sc_lv<2> > id_ex_byteselect; |
sc_out<sc_logic> id_ex_bssign; |
sc_out<sc_lv<5> > id_ex_alu_sa; |
|
// signal to mem_stage throught ex_stage |
sc_out<sc_logic> id_ex_datareq; |
sc_out<sc_logic> id_ex_datarw; |
sc_out<sc_logic> id_ex_memtoreg; |
|
sc_signal<sc_lv<2> > id_byteselect; |
sc_signal<sc_logic> id_bssign; |
sc_signal<sc_lv<5> > id_alu_sa; |
|
// signal to control save in register |
sc_out<sc_lv<5> > id_ex_writeregister_out; |
sc_out<sc_logic> id_ex_regwrite_out; |
|
// forwarding control signal |
sc_signal<sc_lv<5> > id_ex_writeregister; |
sc_in<sc_lv<5> > id_ex_m_writeregister; |
sc_in<sc_lv<5> > id_ex_m_wb_writeregister; |
sc_signal<sc_logic> id_ex_regwrite; |
sc_in<sc_logic> id_ex_m_regwrite; |
sc_in<sc_logic> id_ex_m_wb_regwrite; |
sc_in<sc_lv<32> > ex_id_forward; |
sc_in<sc_lv<32> > m_id_forward; |
sc_in<sc_lv<32> > wb_id_forward; |
|
// signals to cp0 |
sc_out<sc_lv<4> > cp0_inst; // Current instruction |
sc_out<sc_uint<5> > cp0_reg_no; // Register to read/write in cp0 |
sc_out<sc_logic> cp0_reg_rw; // Read/Write signal, 1 for write |
sc_out<sc_lv<32> > cp0_reg_rs; // Contents of register rd in instruction for mtc0 |
sc_in<sc_lv<32> > cp0_reg_out; // For reading out from cp0 - for mfc0 |
|
// signals used in control |
sc_signal<sc_lv<5> > rt, rs, rd, sa; |
|
/* sc_lv<5> lrs, lrt, lrd, lsa; // lv version of reg # */ |
/* sc_uint<5> uirs, uirt, uird, uisa; // unsigned integer version of reg # */ |
/* sc_int<32> is, it, id; // integer version of register contents... */ |
|
// sign/zero extend and lui control |
sc_signal<sc_lv<32> > id_sign_extend; |
sc_signal<sc_lv<2> > id_extend_ctrl; |
|
sc_signal<sc_lv<32> > id_mux_fw1; |
sc_signal<sc_lv<32> > id_mux_fw2; |
|
sc_signal<sc_lv<32> > id_reg1; |
sc_signal<sc_lv<32> > id_reg2; |
|
sc_signal<sc_lv<32> > id_alu1; |
sc_signal<sc_lv<32> > id_alu2; |
|
sc_signal<sc_logic> id_equal; |
|
// signal from control unit |
sc_signal<sc_lv<5> > id_writeregister; |
sc_signal<sc_logic> id_regwrite; |
sc_signal<sc_lv<2> > regdest; |
sc_signal<sc_logic> id_select_jump; |
sc_signal<sc_logic> id_pc_store; |
sc_signal<sc_lv<2> > id_sign_ctrl; |
sc_signal<sc_lv<3> > id_branch_select; |
sc_signal<sc_lv<6> > id_alu_ctrl; |
sc_signal<sc_logic> id_datareq; |
sc_signal<sc_logic> id_datarw; |
sc_signal<sc_logic> id_memtoreg; |
sc_signal<sc_logic> id_shamt_ctrl; |
sc_signal<sc_logic> id_mfc0; |
|
// forwarding ctrl unit |
sc_signal<sc_lv<2> > id_fw_ctrl1; |
sc_signal<sc_lv<2> > id_fw_ctrl2; |
|
#ifdef ONEHOT_DEBUG |
sc_signal<sc_logic> inst_addiu; |
sc_signal<sc_logic> inst_jalr; |
sc_signal<sc_logic> inst_lw; |
sc_signal<sc_logic> inst_mfc0; |
sc_signal<sc_logic> inst_mtc0; |
sc_signal<sc_logic> inst_nop; |
sc_signal<sc_logic> inst_sw; |
sc_signal<sc_logic> inst_wait; |
#endif |
|
|
control *control1; |
mux_writeregister *mux_writeregister1; |
sign_extend *sign_extend1; |
add_new_pc *add_new_pc1; |
mux_jump *mux_jump1; |
mux_forward_select *mux_forward_select1; |
mux_forward_select *mux_forward_select2; |
mux_alu1 *mux_alu_1; |
mux_alu2 *mux_alu_2; |
comparator *comparator1; |
forwarding_control *forwarding_control1; |
forwarding_control *forwarding_control2; |
reg *reg1; |
regfile *localreg; |
|
|
SC_CTOR(id_stage) |
{ |
control1 = new control("control"); |
control1->if_id_inst(if_id_inst); |
control1->rs(rs); |
control1->rt(rt); |
control1->rd(rd); |
control1->id_alu_ctrl(id_alu_ctrl); |
control1->id_alu_sa(id_alu_sa); |
control1->id_ctrl(id_ctrl); |
control1->id_extend_ctrl(id_extend_ctrl); |
control1->id_sign_ctrl(id_sign_ctrl); |
control1->regdest(regdest); |
control1->id_select_jump(id_select_jump); |
control1->id_pc_store(id_pc_store); |
control1->id_branch_select(id_branch_select); |
control1->id_regwrite(id_regwrite); |
control1->id_shamt_ctrl(id_shamt_ctrl); |
control1->id_datarw(id_datarw); |
control1->id_datareq(id_datareq); |
control1->id_memtoreg(id_memtoreg); |
control1->id_byteselect(id_byteselect); |
control1->cp0_inst(cp0_inst); |
control1->cp0_reg_no(cp0_reg_no); |
control1->cp0_reg_rw(cp0_reg_rw); |
control1->id_mfc0(id_mfc0); |
#ifdef ONEHOT_DEBUG |
control1->inst_addiu(inst_addiu); |
control1->inst_jalr(inst_jalr); |
control1->inst_lw(inst_lw); |
control1->inst_mfc0(inst_mfc0); |
control1->inst_mtc0(inst_mtc0); |
control1->inst_nop(inst_nop); |
control1->inst_sw(inst_sw); |
control1->inst_wait(inst_wait); |
#endif |
|
mux_writeregister1 = new mux_writeregister("mux_writeregister"); |
mux_writeregister1->regdest(regdest); |
mux_writeregister1->rt(rt); |
mux_writeregister1->rd(rd); |
mux_writeregister1->id_writeregister(id_writeregister); |
|
sign_extend1 = new sign_extend("sign_extend"); |
sign_extend1->if_id_inst(if_id_inst); |
sign_extend1->id_extend_ctrl(id_extend_ctrl); |
sign_extend1->id_sign_extend(id_sign_extend); |
|
add_new_pc1 = new add_new_pc("add_new_pc"); |
add_new_pc1->if_id_next_pc(if_id_next_pc); |
add_new_pc1->id_sign_extend(id_sign_extend); |
add_new_pc1->id_new_pc(id_new_pc); |
|
mux_jump1 = new mux_jump("mux_jump"); |
mux_jump1->if_id_next_pc(if_id_next_pc); |
mux_jump1->if_id_inst(if_id_inst); |
mux_jump1->id_select_jump(id_select_jump); |
mux_jump1->id_mux_fw1(id_mux_fw1); |
mux_jump1->id_jmp_tar(id_jmp_tar); |
|
mux_forward_select1 = new mux_forward_select("mux_forward_select1"); |
mux_forward_select1->id_reg(id_reg1); |
mux_forward_select1->ex_id_forward(ex_id_forward); |
mux_forward_select1->m_id_forward(m_id_forward); |
mux_forward_select1->wb_id_forward(wb_id_forward); |
mux_forward_select1->id_fw_ctrl(id_fw_ctrl1); |
mux_forward_select1->id_mux_fw(id_mux_fw1); |
|
mux_forward_select2 = new mux_forward_select("mux_forward_select2"); |
mux_forward_select2->id_reg(id_reg2); |
mux_forward_select2->ex_id_forward(ex_id_forward); |
mux_forward_select2->m_id_forward(m_id_forward); |
mux_forward_select2->wb_id_forward(wb_id_forward); |
mux_forward_select2->id_fw_ctrl(id_fw_ctrl2); |
mux_forward_select2->id_mux_fw(id_mux_fw2); |
|
mux_alu_1 = new mux_alu1("mux_alu1"); |
mux_alu_1->if_id_inst(if_id_inst); |
mux_alu_1->id_shamt_ctrl(id_shamt_ctrl); |
mux_alu_1->id_pc_store(id_pc_store); |
mux_alu_1->id_alu1(id_alu1); |
mux_alu_1->if_id_next_pc(if_id_next_pc); |
mux_alu_1->cp0_reg_out(cp0_reg_out); |
mux_alu_1->id_mux_fw1(id_mux_fw1); |
mux_alu_1->id_mfc0(id_mfc0); |
|
mux_alu_2 = new mux_alu2("mux_alu2"); |
mux_alu_2->id_sign_extend(id_sign_extend); |
mux_alu_2->id_sign_ctrl(id_sign_ctrl); |
mux_alu_2->id_alu2(id_alu2); |
mux_alu_2->cp0_reg_rs(cp0_reg_rs); |
mux_alu_2->id_mux_fw2(id_mux_fw2); |
|
comparator1 = new comparator("comparator"); |
comparator1->id_mux_fw1(id_mux_fw1); |
comparator1->id_mux_fw2(id_mux_fw2); |
comparator1->id_branch_select(id_branch_select); |
comparator1->id_equal(id_equal); |
comparator1->id_branch(id_branch); |
|
forwarding_control1 = new forwarding_control("forwarding_control1"); |
forwarding_control1->id_ex_writeregister(id_ex_writeregister); |
forwarding_control1->id_ex_m_writeregister(id_ex_m_writeregister); |
forwarding_control1->id_ex_m_wb_writeregister(id_ex_m_wb_writeregister); |
forwarding_control1->id_ex_regwrite(id_ex_regwrite); |
forwarding_control1->id_ex_m_regwrite(id_ex_m_regwrite); |
forwarding_control1->id_ex_m_wb_regwrite(id_ex_m_wb_regwrite); |
forwarding_control1->rs(rs); |
forwarding_control1->id_fw_ctrl(id_fw_ctrl1); |
|
forwarding_control2 = new forwarding_control("forwarding_control2"); |
forwarding_control2->id_ex_writeregister(id_ex_writeregister); |
forwarding_control2->id_ex_m_writeregister(id_ex_m_writeregister); |
forwarding_control2->id_ex_m_wb_writeregister(id_ex_m_wb_writeregister); |
forwarding_control2->id_ex_regwrite(id_ex_regwrite); |
forwarding_control2->id_ex_m_regwrite(id_ex_m_regwrite); |
forwarding_control2->id_ex_m_wb_regwrite(id_ex_m_wb_regwrite); |
forwarding_control2->rs(rt); |
forwarding_control2->id_fw_ctrl(id_fw_ctrl2); |
|
reg1 = new reg("reg"); |
reg1->in_clk(in_clk); |
reg1->reset(reset); |
reg1->datahold(datahold); |
reg1->insthold(insthold); |
reg1->id_ex_alu1(id_ex_alu1); |
reg1->id_alu1(id_alu1); |
reg1->id_ex_alu2(id_ex_alu2); |
reg1->id_alu2(id_alu2); |
reg1->id_ex_datastore(id_ex_datastore); |
reg1->id_mux_fw2(id_mux_fw2); |
reg1->id_ex_alu_ctrl(id_ex_alu_ctrl); |
reg1->id_alu_ctrl(id_alu_ctrl); |
reg1->id_ex_alu_sa(id_ex_alu_sa); |
reg1->id_alu_sa(id_alu_sa); |
reg1->id_ex_equal(id_ex_equal); |
reg1->id_equal(id_equal); |
reg1->id_ex_datareq(id_ex_datareq); |
reg1->id_datareq(id_datareq); |
reg1->id_ex_datarw(id_ex_datarw); |
reg1->id_datarw(id_datarw); |
reg1->id_ex_memtoreg(id_ex_memtoreg); |
reg1->id_memtoreg(id_memtoreg); |
reg1->id_ex_writeregister_out(id_ex_writeregister_out); |
reg1->id_writeregister(id_writeregister); |
reg1->id_ex_writeregister(id_ex_writeregister); |
reg1->id_ex_regwrite_out(id_ex_regwrite_out); |
reg1->id_regwrite(id_regwrite); |
reg1->id_ex_regwrite(id_ex_regwrite); |
reg1->id_ex_byteselect(id_ex_byteselect); |
reg1->id_byteselect(id_byteselect); |
reg1->id_ex_bssign(id_ex_bssign); |
reg1->id_bssign(id_bssign); |
|
localreg = new regfile("regfiles"); |
localreg->in_clk(in_clk); |
localreg->reset(reset); |
localreg->rs(rs); |
localreg->rt(rt); |
localreg->wr(id_ex_m_wb_regwrite); |
localreg->rd_in(wb_id_forward); |
localreg->rd(id_ex_m_wb_writeregister); |
localreg->rs_out(id_reg1); |
localreg->rt_out(id_reg2); |
} |
}; |
/trunk/cpu/cpu/id_stage/control.h
0,0 → 1,50
#include "systemc.h" |
#include "../../constants/constants.h" |
#include "../../constants/config.h" |
|
SC_MODULE(control) |
{ |
sc_in<sc_lv<32> > if_id_inst; |
sc_out<sc_lv<5> > rs; |
sc_out<sc_lv<5> > rt; |
sc_out<sc_lv<5> > rd; |
sc_out<sc_lv<6> > id_alu_ctrl; |
sc_out<sc_lv<5> > id_alu_sa; |
sc_out<sc_logic> id_ctrl; |
sc_out<sc_lv<2> > id_extend_ctrl; |
sc_out<sc_lv<2> > id_sign_ctrl; |
sc_out<sc_lv<2> > regdest; |
sc_out<sc_logic> id_select_jump; |
sc_out<sc_logic> id_pc_store; |
sc_out<sc_lv<3> > id_branch_select; |
sc_out<sc_logic> id_regwrite; |
sc_out<sc_logic> id_shamt_ctrl; |
sc_out<sc_logic> id_datarw; |
sc_out<sc_logic> id_datareq; |
sc_out<sc_logic> id_memtoreg; |
sc_out<sc_lv<2> > id_byteselect; |
|
sc_out<sc_lv<4> > cp0_inst; |
sc_out<sc_uint<5> > cp0_reg_no; |
sc_out<sc_logic> cp0_reg_rw; |
sc_out<sc_logic> id_mfc0; |
sc_out<sc_logic> illegal_instruction; |
sc_out<sc_logic> syscall_exception; |
#ifdef ONEHOT_DEBUG |
sc_out<sc_logic> inst_addiu; |
sc_out<sc_logic> inst_jalr; |
sc_out<sc_logic> inst_lw; |
sc_out<sc_logic> inst_mfc0; |
sc_out<sc_logic> inst_mtc0; |
sc_out<sc_logic> inst_nop; |
sc_out<sc_logic> inst_sw; |
sc_out<sc_logic> inst_wait; |
#endif |
void do_control(); |
|
SC_CTOR(control) |
{ |
SC_METHOD(do_control); |
sensitive << if_id_inst; |
} |
}; |
/trunk/cpu/cpu/id_stage/add_new_pc.h
0,0 → 1,18
#include "systemc.h" |
#include "../../constants/constants.h" |
|
SC_MODULE(add_new_pc) |
{ |
sc_in<sc_lv<32> > if_id_next_pc; |
sc_in<sc_lv<32> > id_sign_extend; |
sc_out<sc_lv<32> > id_new_pc; |
|
void do_add_new_pc(); |
|
SC_CTOR(add_new_pc) |
{ |
SC_METHOD(do_add_new_pc); |
sensitive << if_id_next_pc << id_sign_extend; |
} |
|
}; |
/trunk/cpu/cpu/id_stage/mux_writeregister.cpp
0,0 → 1,19
//Multiplexer per scittura registri |
// Stabilisce il registro di destinazione, che puo' essere |
// il registro rt, rd o il registro 31! |
|
#include "mux_writeregister.h" |
|
void mux_writeregister::do_mux_writeregister() |
{ |
if(regdest.read() == "00") |
id_writeregister.write(rd); |
else |
if(regdest.read() == "01") |
id_writeregister.write(rt); |
else |
if(regdest.read() == "10") |
id_writeregister.write("11111"); |
else |
id_writeregister.write("00000"); |
} |
/trunk/cpu/cpu/id_stage/reg_id.cpp
0,0 → 1,97
#include "reg_id.h" |
|
void reg_id::do_reg_id() |
{ |
|
if(reset.read() == true) |
{ |
id_ex_alu1.write(WORD_ZERO); |
id_ex_alu2.write(WORD_ZERO); |
id_ex_datastore.write(WORD_ZERO); |
id_ex_alu_ctrl.write("000000"); |
id_ex_alu_sa.write("00000"); |
id_ex_equal.write(SC_LOGIC_0); |
id_ex_datareq.write(SC_LOGIC_0); |
id_ex_datarw.write(SC_LOGIC_0); |
id_ex_memtoreg.write(SC_LOGIC_0); |
id_ex_writeregister_out.write("00000"); |
id_ex_regwrite_out.write(SC_LOGIC_0); |
id_ex_writeregister.write("00000"); |
id_ex_regwrite.write(SC_LOGIC_0); |
id_ex_byteselect.write("00"); |
id_ex_bssign.write(SC_LOGIC_0); |
|
// EXCEPTION SIGNALS |
id_ex_IBUS.write(SC_LOGIC_0); |
id_ex_inst_addrl.write(SC_LOGIC_0); |
id_ex_syscall_exception.write(SC_LOGIC_0); |
id_ex_illegal_instruction.write(SC_LOGIC_0); |
id_ex_instaddr.write(0); |
|
} |
else |
if((datahold.read() == false) && (insthold.read() == false) && (enable_decode.read() == SC_LOGIC_1)) |
{ |
id_ex_alu1.write(id_alu1.read()); |
id_ex_alu2.write(id_alu2.read()); |
id_ex_datastore.write(id_mux_fw2.read()); |
id_ex_alu_ctrl.write(id_alu_ctrl.read()); |
id_ex_alu_sa.write(id_alu_sa.read()); |
id_ex_equal.write(id_equal.read()); |
id_ex_datareq.write(id_datareq.read()); |
id_ex_datarw.write(id_datarw.read()); |
id_ex_memtoreg.write(id_memtoreg.read()); |
id_ex_writeregister_out.write(id_writeregister.read()); |
id_ex_writeregister.write(id_writeregister.read()); |
id_ex_regwrite_out.write(id_regwrite.read()); |
id_ex_regwrite.write(id_regwrite.read()); |
id_ex_byteselect.write(id_byteselect.read()); |
id_ex_bssign.write(id_bssign.read()); |
// EXCEPTION SIGNALS |
id_ex_IBUS.write(if_id_IBUS.read()); |
id_ex_inst_addrl.write(if_id_inst_addrl.read()); |
id_ex_syscall_exception.write(syscall_exception.read()); |
id_ex_illegal_instruction.write(illegal_instruction.read()); |
id_ex_instaddr.write(if_id_instaddr); |
} |
else |
if((datahold.read() == false) && (insthold.read() == false) && (enable_decode.read() == SC_LOGIC_0)) |
{ |
id_ex_alu1.write(WORD_ZERO); |
id_ex_alu2.write(WORD_ZERO); |
id_ex_datastore.write(WORD_ZERO); |
id_ex_alu_ctrl.write("000000"); |
id_ex_alu_sa.write("00000"); |
id_ex_equal.write(SC_LOGIC_0); |
id_ex_datareq.write(SC_LOGIC_0); |
id_ex_datarw.write(SC_LOGIC_0); |
id_ex_memtoreg.write(SC_LOGIC_0); |
id_ex_writeregister_out.write("00000"); |
id_ex_regwrite_out.write(SC_LOGIC_0); |
id_ex_writeregister.write("00000"); |
id_ex_regwrite.write(SC_LOGIC_0); |
id_ex_byteselect.write("00"); |
id_ex_bssign.write(SC_LOGIC_0); |
id_ex_IBUS.write(if_id_IBUS.read()); |
id_ex_inst_addrl.write(if_id_inst_addrl.read()); |
id_ex_syscall_exception.write(syscall_exception.read()); |
id_ex_illegal_instruction.write(illegal_instruction.read()); |
id_ex_instaddr.write(if_id_instaddr); |
} |
else; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/trunk/cpu/cpu/id_stage/mux_alu1.cpp
0,0 → 1,28
#include "mux_alu1.h" |
|
void mux_alu1::do_mux_alu1() |
{ |
sc_logic isc = id_shamt_ctrl; |
sc_logic ips = id_pc_store; |
|
sc_lv<2> select; |
select[1] = isc; |
select[0] = ips; |
sc_lv<32> iii = if_id_inst; |
sc_lv<32> v_id_alu1; |
|
|
if (id_mfc0.read() == SC_LOGIC_1) |
v_id_alu1 = cp0_reg_out; |
else |
if(select == "00") |
v_id_alu1 = id_mux_fw1; |
else |
if(select == "01") |
v_id_alu1 = if_id_next_pc; |
else |
v_id_alu1 = ("00000000000000000000000000",iii.range(11,6)); |
|
|
id_alu1 = v_id_alu1; |
} |
/trunk/cpu/cpu/id_stage/mux_alu2.cpp
0,0 → 1,18
#include "mux_alu2.h" |
|
void mux_alu2::do_mux_alu2() |
{ |
sc_lv<2> isc = id_sign_ctrl; |
sc_lv<32> v_id_alu2; |
if(isc == "00") |
v_id_alu2 = id_mux_fw2; |
else |
if(isc == "01") |
v_id_alu2 = id_sign_extend; |
else |
v_id_alu2 = (sc_int<32>) 4; |
|
id_alu2 = v_id_alu2; |
cp0_reg_rs = v_id_alu2; |
|
} |
/trunk/cpu/cpu/id_stage/mux_forward_select.cpp
0,0 → 1,17
#include "mux_forward_select.h" |
|
void mux_forward_select::do_mux_forward_select() |
{ |
sc_lv<2> ifc = id_fw_ctrl.read(); |
|
if( ifc == "00") |
id_mux_fw.write(id_reg.read()); |
else |
if( ifc == "01") |
id_mux_fw.write(ex_id_forward.read()); |
else |
if( ifc == "10") |
id_mux_fw.write(m_id_forward.read()); |
else |
id_mux_fw.write(wb_id_forward.read()); |
} |
/trunk/cpu/cpu/id_stage/mux_writeregister.h
0,0 → 1,18
#include "systemc.h" |
#include "../../constants/constants.h" |
|
SC_MODULE(mux_writeregister) |
{ |
sc_in<sc_lv<2> > regdest; |
sc_in<sc_lv<5> > rt; |
sc_in<sc_lv<5> > rd; |
sc_out<sc_lv<5> > id_writeregister; |
|
void do_mux_writeregister(); |
|
SC_CTOR(mux_writeregister) |
{ |
SC_METHOD(do_mux_writeregister); |
sensitive << rt << rd << regdest; |
} |
}; |
/trunk/cpu/cpu/writeback_ctrl.cpp
0,0 → 1,25
#include "writeback_ctrl.h" |
|
void writeback_ctrl::do_writeback_ctrl() |
{ |
if((m_wb_IBUS.read() == SC_LOGIC_1) || |
(m_wb_inst_addrl.read() == SC_LOGIC_1) || |
(m_wb_syscall_exception.read() == SC_LOGIC_1) || |
(m_wb_illegal_instruction.read() == SC_LOGIC_1) || |
(m_wb_ovf_excep.read() == SC_LOGIC_1) || |
(m_wb_DBUS.read() == SC_LOGIC_1) || |
(m_wb_data_addrl.read() == SC_LOGIC_1) || |
(m_wb_data_addrs.read() == SC_LOGIC_1) || |
(m_wb_interrupt_signal.read() == SC_LOGIC_1)) |
wb_exception.write(SC_LOGIC_1); |
else |
wb_exception.write(SC_LOGIC_0); |
|
|
|
|
|
|
|
|
} |
/trunk/cpu/cpu/ex_stage.cpp
0,0 → 1,5
//! EX Stage module |
// |
// $Id: ex_stage.cpp,v 1.00 2004/12/23 22:253:00 DIEE Cagliari |
// |
#include "ex_stage.h" |
/trunk/cpu/cpu/if_stage/select_next_pc.cpp
0,0 → 1,29
#include "select_next_pc.h" |
|
void select_next_pc::do_select_next_pc() |
{ |
#ifdef _DOBRANCH_ |
|
//sc_lv<32> temp = new_pc; |
|
if (load_epc.read() == SC_LOGIC_1) |
{ |
pc_in.write(new_pc.read()); |
} |
else |
{ |
if ((id_ctrl.read() == 0) && (id_branch.read() == 0)) |
pc_in.write(if_pc_add.read()); |
else |
if ((id_ctrl.read() == 0) && (id_branch.read() == 1)) |
pc_in.write(id_new_pc.read()); |
else |
if ((id_ctrl.read() == 1) && (id_branch.read() == 0)) |
pc_in.write(id_jmp_tar.read()); |
else // 1 && 1 - should never happen! |
pc_in.write(id_jmp_tar.read()); |
} |
#else |
pc_in.write(if_pc_add.read()); |
#endif |
} |
/trunk/cpu/cpu/if_stage/reg_if.h
0,0 → 1,33
#include "systemc.h" |
#include "../../constants/constants.h" |
|
SC_MODULE(reg_if) |
{ |
sc_in<bool> in_clk; |
sc_in<bool> reset; |
sc_in<bool> insthold; |
sc_in<bool> datahold; |
|
sc_in<sc_lv<32> > instdataread; |
sc_in<sc_lv<32> > if_pc_add; |
|
sc_out<sc_lv<32> > if_id_inst; |
sc_out<sc_lv<32> > if_id_next_pc; |
|
sc_in<sc_logic> IBUS; |
sc_in<sc_logic> inst_addrl; |
sc_out<sc_logic> if_id_IBUS; |
sc_out<sc_logic> if_id_inst_addrl; |
|
sc_in<sc_uint<32> > pc_if_instaddr; |
sc_out<sc_uint<32> > if_id_instaddr; |
sc_in<sc_logic> enable_fetch; |
|
void do_reg_if(); |
|
SC_CTOR(reg_if) |
{ |
SC_METHOD(do_reg_if); |
sensitive_pos << in_clk; |
} |
}; |
/trunk/cpu/cpu/if_stage/if_stage.cpp
0,0 → 1,33
#include "if_stage.h" |
/trunk/cpu/cpu/if_stage/if_ctrl.cpp
0,0 → 1,10
#include "if_ctrl.h" |
|
void if_ctrl::do_if_ctrl() |
{ |
if((IBUS.read() == SC_LOGIC_1) || (inst_addrl.read() == SC_LOGIC_1)) |
if_exception.write(SC_LOGIC_1); |
else |
if_exception.write(SC_LOGIC_0); |
|
} |
/trunk/cpu/cpu/if_stage/select_next_pc.h
0,0 → 1,27
#include "systemc.h" |
#define _DOBRANCH_ 1 |
#include "../../constants/constants.h" |
#include "../../constants/config.h" |
|
SC_MODULE(select_next_pc) |
{ |
sc_in<sc_lv<32> > new_pc; |
sc_in<sc_logic> load_epc; |
sc_in<sc_logic> id_ctrl; |
sc_in<sc_logic> id_branch; |
sc_in<sc_lv<32> > if_pc_add; |
sc_in<sc_lv<32> > id_new_pc; |
sc_in<sc_lv<32> > id_jmp_tar; |
|
sc_out<sc_lv<32> > pc_in; |
|
|
void do_select_next_pc(); |
|
SC_CTOR(select_next_pc) |
{ |
SC_METHOD(do_select_next_pc); |
sensitive << if_pc_add << id_jmp_tar << id_new_pc << id_branch << id_ctrl << new_pc << load_epc; |
|
} |
}; |
/trunk/cpu/cpu/if_stage/if_stage.h
0,0 → 1,76
//! IF Stage module |
// |
// $Id: if_stage.h,v 1.1 2006-01-21 03:37:38 igorloi Exp $ |
// |
#ifndef _IF_STAGE_H |
#define _IF_STAGE_H |
|
#include <systemc.h> |
#include "./if_stage/add.h" |
#include "./if_stage/reg_if.h" |
#include "./if_stage/select_next_pc.h" |
|
SC_MODULE(if_stage) |
{ |
sc_in<bool> in_clk; |
sc_in<bool> reset; |
|
sc_in<bool> insthold; |
sc_in<bool> datahold; |
|
sc_in<sc_lv<32> > pc_out; |
sc_in<sc_lv<32> > id_new_pc; |
sc_in<sc_lv<32> > id_jmp_tar; |
sc_in<sc_logic> id_ctrl; |
sc_in<sc_logic> id_branch; |
|
sc_out<sc_lv<32> > pc_in; |
|
sc_in<sc_lv<32> > instdataread; |
sc_out<sc_lv<32> > if_id_inst; |
sc_out<sc_lv<32> > if_id_next_pc; |
|
// cp0 connections |
sc_in<sc_lv<32> > new_pc; |
sc_in<sc_logic> load_epc; |
|
// Signals |
sc_signal<sc_lv<32> > if_pc_add; |
|
reg_if *reg_if1; |
add *add1; |
select_next_pc *select_next_pc1; |
|
//! Constructor |
/*! |
No description |
*/ |
SC_CTOR(if_stage) |
{ |
reg_if1 = new reg_if("reg_if"); |
reg_if1->in_clk(in_clk); |
reg_if1->reset(reset); |
reg_if1->insthold(insthold); |
reg_if1->datahold(datahold); |
reg_if1->instdataread(instdataread); |
reg_if1->if_pc_add(if_pc_add); |
reg_if1->if_id_inst(if_id_inst); |
reg_if1->if_id_next_pc(if_id_next_pc); |
|
add1 = new add("add"); |
add1->if_pc_add(if_pc_add); |
add1->pc_out(pc_out); |
|
select_next_pc1 = new select_next_pc("select_next_pc"); |
select_next_pc1->new_pc(new_pc); |
select_next_pc1->load_epc(load_epc); |
select_next_pc1->id_ctrl(id_ctrl); |
select_next_pc1->id_branch(id_branch); |
select_next_pc1->if_pc_add(if_pc_add); |
select_next_pc1->id_new_pc(id_new_pc); |
select_next_pc1->id_jmp_tar(id_jmp_tar); |
select_next_pc1->pc_in(pc_in); |
} |
}; |
|
#endif |
/trunk/cpu/cpu/if_stage/if_ctrl.h
0,0 → 1,17
#include "systemc.h" |
#include "../../constants/constants.h" |
|
SC_MODULE(if_ctrl) |
{ |
sc_in<sc_logic> IBUS; |
sc_in<sc_logic> inst_addrl; |
sc_out<sc_logic> if_exception; |
|
void do_if_ctrl(); |
|
SC_CTOR(if_ctrl) |
{ |
SC_METHOD(do_if_ctrl); |
sensitive << IBUS << inst_addrl; |
} |
}; |
/trunk/cpu/cpu/if_stage/add.cpp
0,0 → 1,6
#include "add.h" |
|
void add::do_add() |
{ |
if_pc_add.write(((sc_uint<32>) pc_out.read()) + 4); |
} |
/trunk/cpu/cpu/if_stage/reg_if.cpp
0,0 → 1,42
#include "reg_if.h" |
/* |
enable_fetch: segnale posto ad 1 per il normale funzionamento della pipeline. |
Se si verifica un eccezione il coprocessore setta questo segnale a zero inibendo |
la scrittura sui registri di pipeline di questo stadio. |
Segnale per la gestione delle eccezioni IBUS e inst_addrl |
*/ |
|
|
void reg_if::do_reg_if() |
{ |
if(reset.read() == true) |
{ |
if_id_next_pc.write(0); |
if_id_inst.write(0); |
if_id_IBUS.write(SC_LOGIC_0); |
if_id_inst_addrl.write(SC_LOGIC_0); |
if_id_instaddr.write(0); |
} |
else |
{ |
if((insthold.read() == false) && (datahold.read() == false) && (enable_fetch.read() == SC_LOGIC_1)) |
{ |
if_id_next_pc.write(if_pc_add.read()); |
if_id_inst.write(instdataread.read()); |
if_id_IBUS.write(IBUS.read()); |
if_id_inst_addrl.write(inst_addrl.read()); |
if_id_instaddr.write(pc_if_instaddr.read()); |
} |
else |
if((insthold.read() == false) && (datahold.read() == false) && (enable_fetch.read() == SC_LOGIC_0)) |
{ |
// QUESTA PaRTE �DA RIVEDERE!!!! |
if_id_next_pc.write(0); |
if_id_inst.write(0); |
if_id_IBUS.write(IBUS.read()); |
if_id_inst_addrl.write(inst_addrl.read()); |
if_id_instaddr.write(pc_if_instaddr.read()); |
} |
else; |
} |
} |
/trunk/cpu/cpu/if_stage/add.h
0,0 → 1,15
#include "systemc.h" |
|
SC_MODULE(add) |
{ |
sc_out<sc_lv<32> > if_pc_add; |
sc_in<sc_lv<32> > pc_out; |
|
void do_add(); |
|
SC_CTOR(add) |
{ |
SC_METHOD(do_add); |
sensitive << pc_out; |
} |
}; |
/trunk/cpu/cpu/mux_instaddr.cpp
0,0 → 1,14
#include "mux_instaddr.h" |
|
void mux_instaddr::do_mux_instaddr() |
{ |
if(m_wb_interrupt_signal.read() == true) |
{ |
if((ex_m_instaddr.read() - m_wb_instaddr.read()) == 4) |
m_wb_instaddr_s.write(m_wb_instaddr.read()); |
else |
m_wb_instaddr_s.write(ex_m_instaddr.read()); |
} |
else |
m_wb_instaddr_s.write(m_wb_instaddr.read()); |
} |
/trunk/cpu/cpu/cp0/exception.cpp
0,0 → 1,101
#include "exception.h" |
|
void exception::compute_cause() |
{ |
sc_lv<5> cause_5; |
sc_lv<32> cause_32; |
|
if(m_wb_inst_addrl.read() == SC_LOGIC_1) |
cause_5 = "00100" ; |
else |
if(m_wb_IBUS.read() == SC_LOGIC_1) |
cause_5 = "00110" ; |
else |
if(m_wb_DBUS.read() == SC_LOGIC_1) |
cause_5 = "00111" ; |
else |
if(m_wb_data_addrl.read() == SC_LOGIC_1) |
cause_5 = "00100" ; |
else |
if(m_wb_data_addrs.read() == SC_LOGIC_1) |
cause_5 = "00101" ; |
else |
if(m_wb_syscall_exception.read() == SC_LOGIC_1) |
cause_5 = "01000" ; |
else |
if(m_wb_illegal_instruction.read() == SC_LOGIC_1) // RI |
cause_5 = "01010"; |
else |
if(m_wb_ovf_excep.read() == SC_LOGIC_1) |
cause_5 = "01100"; |
else |
if(m_wb_interrupt_signal.read() == SC_LOGIC_1) |
cause_5 = "00000"; |
else |
cause_5 = "00000"; |
|
cause_32 = WORD_ZERO; |
cause_32.range(6,2) = cause_5; |
cause.write(cause_32); |
} |
|
void exception::check_for_exception() |
{ |
if((m_wb_IBUS.read() == SC_LOGIC_1) || |
(m_wb_inst_addrl.read() == SC_LOGIC_1) || |
(m_wb_syscall_exception.read() == SC_LOGIC_1) || |
(m_wb_illegal_instruction.read() == SC_LOGIC_1) || |
(m_wb_ovf_excep.read() == SC_LOGIC_1) || |
(m_wb_DBUS.read() == SC_LOGIC_1) || |
(m_wb_data_addrl.read() == SC_LOGIC_1) || |
(m_wb_data_addrs.read() == SC_LOGIC_1) || |
(m_wb_interrupt_signal.read() == SC_LOGIC_1)) |
check_excep.write(true); |
else |
check_excep.write(false); |
} |
|
void exception::check_for_interrupt() |
{ |
/*if(interrupt_signal.read() == SC_LOGIC_1) |
interrupt_exception.write(SC_LOGIC_1); |
else |
interrupt_exception.write(SC_LOGIC_0);*/ |
} |
|
void exception::check_for_Page_fault() |
{ |
if((cause.read()).range(6,2) == "00110" ) |
to_BadVAddr.write(m_wb_instaddr.read()); |
else |
if((cause.read()).range(6,2) == "00111" ) |
to_BadVAddr.write(m_wb_dataaddr.read()); |
else |
to_BadVAddr.write(0); |
} |
|
void exception::save_EPC() |
{ |
if(check_excep.read() == SC_LOGIC_1) |
to_EPC.write(m_wb_instaddr.read()); |
else |
to_EPC.write(0); |
} |
|
//sensitive << m_wb_interrupt_signal; |
//sensitive << cp0_inst << reset; |
void exception::handling_status_register() |
{ |
if(reset.read() == true ) |
to_SR = SC_LOGIC_0; |
else |
{ |
if(m_wb_interrupt_signal.read() == SC_LOGIC_1) |
to_SR = SC_LOGIC_1; |
else |
if(cp0_inst.read() == CP0_ERET) |
to_SR = SC_LOGIC_0; |
else; |
} |
|
} |
/trunk/cpu/cpu/cp0/set_stop_pc.cpp
0,0 → 1,91
#include "set_stop_pc.h" |
|
void set_stop_pc::update_state() |
{ |
if (reset.read() == true) |
{ |
currentstate = 0; |
} |
else |
currentstate = nextstate; |
} |
|
void set_stop_pc::do_set_stop_pc() |
{ |
|
//insthold = x_insthold.read(); |
// FSM |
switch(currentstate) |
{ |
case 0: |
{ |
|
if( check_excep.read() == SC_LOGIC_1 ) |
{ |
cout << " ECCEZIONE " << endl; |
|
//sc_stop(); |
nextstate = 1 ; |
new_pc.write(WORD_ZERO); |
load_epc.write(SC_LOGIC_0); |
insthold.write(true); |
} |
else |
if(cp0_inst.read() == CP0_ERET) |
{ |
cout <<" CPO ERET" << endl; |
nextstate = 3; |
new_pc.write(WORD_ZERO); |
load_epc.write(SC_LOGIC_0); |
insthold.write(true); |
} |
else |
{ |
nextstate = 0; |
new_pc.write(WORD_ZERO); |
load_epc.write(SC_LOGIC_0); |
insthold = x_insthold.read(); |
} |
} |
break; |
|
case 1: |
{ |
insthold.write(false); |
new_pc.write(0x00000008); |
load_epc.write(SC_LOGIC_1); |
nextstate = 2; |
} |
break; |
|
case 2: |
{ |
nextstate = 0; |
insthold.write(x_insthold.read()); |
new_pc.write(0x00000008); |
load_epc.write(SC_LOGIC_1); |
} |
break; |
|
case 3: |
{ |
insthold.write(false); |
new_pc.write(EPC_FOR_RFE.read()); |
load_epc.write(SC_LOGIC_1); |
nextstate = 0; |
} |
break; |
|
case 4: |
{ |
nextstate = 0; |
insthold.write(x_insthold.read()); |
new_pc.write(EPC_FOR_RFE.read()); |
load_epc.write(SC_LOGIC_1); |
} |
break; |
|
default: nextstate = 0; |
break; |
} |
} |
/trunk/cpu/cpu/cp0/exception.h
0,0 → 1,74
#include "systemc.h" |
#include "../../constants/constants.h" |
|
SC_MODULE(exception) |
{ |
sc_in<bool> in_clk; |
sc_in<bool> reset; |
|
sc_in<sc_logic> m_wb_IBUS; |
sc_in<sc_logic> m_wb_inst_addrl; |
sc_in<sc_logic> m_wb_syscall_exception; |
sc_in<sc_logic> m_wb_illegal_instruction; |
sc_in<sc_logic> m_wb_ovf_excep; |
sc_in<sc_logic> m_wb_DBUS; |
sc_in<sc_logic> m_wb_data_addrl; |
sc_in<sc_logic> m_wb_data_addrs; |
sc_in<sc_uint<32> > m_wb_dataaddr; |
sc_in<sc_uint<32> > m_wb_instaddr; |
sc_in<sc_lv<4> > cp0_inst; |
|
//**************INTERRUPT**************** |
sc_in<bool> m_wb_interrupt_signal; |
//sc_out<sc_logic> interrupt_exception; |
//sc_in<sc_uint<32> > ex_m_instaddr; |
sc_signal<sc_logic> to_SR; |
//*************************************** |
|
sc_out<sc_lv<32> > cause; |
sc_out<bool> check_excep; |
sc_out<sc_uint<32> > to_EPC; |
sc_out<sc_uint<32> > to_BadVAddr; |
|
|
|
void compute_cause(); |
|
void check_for_exception(); |
|
void check_for_interrupt(); |
|
void check_for_Page_fault(); |
|
void save_EPC(); |
|
void handling_status_register(); |
|
SC_CTOR(exception) |
{ |
SC_METHOD(compute_cause); |
sensitive << m_wb_IBUS << m_wb_inst_addrl << m_wb_syscall_exception; |
sensitive << m_wb_illegal_instruction << m_wb_ovf_excep; |
sensitive << m_wb_DBUS << m_wb_data_addrl << m_wb_data_addrs; |
sensitive << m_wb_interrupt_signal; |
|
SC_METHOD(check_for_exception); |
sensitive << m_wb_IBUS << m_wb_inst_addrl << m_wb_syscall_exception; |
sensitive << m_wb_illegal_instruction << m_wb_ovf_excep; |
sensitive << m_wb_DBUS << m_wb_data_addrl << m_wb_data_addrs << m_wb_interrupt_signal; |
|
SC_METHOD(check_for_interrupt); |
//sensitive << interrupt_signal; |
|
SC_METHOD(check_for_Page_fault); |
sensitive << cause << m_wb_instaddr << m_wb_dataaddr; |
|
SC_METHOD(save_EPC); |
sensitive << check_excep; |
sensitive << m_wb_instaddr; |
|
SC_METHOD(handling_status_register); |
sensitive << m_wb_interrupt_signal; |
sensitive << cp0_inst << reset; |
} |
}; |
/trunk/cpu/cpu/cp0/cp0_register.cpp
0,0 → 1,117
#include "cp0_register.h" |
|
//! Read registers |
/*! |
sensitive << all registers, reg_wr and reg_no |
*/ |
void cp0_register::cp0_register_read() |
{ |
EPC_FOR_RFE.write( (sc_uint<32>) cp0regs[14]); |
|
if (reg_rw.read() == SC_LOGIC_0) |
{ |
reg_out = cp0regs[reg_no.read()]; |
} |
} |
|
//! Write registers |
/*! |
sensitive_neg << in_clk |
*/ |
void cp0_register::cp0_register_write() |
{ |
if (reset.read() == true) |
{ |
cp0regs[0] = WORD_ZERO; |
cp0regs[1] = WORD_ZERO; |
cp0regs[2] = WORD_ZERO; |
cp0regs[3] = WORD_ZERO; |
cp0regs[4] = WORD_ZERO; |
cp0regs[5] = WORD_ZERO; |
cp0regs[6] = WORD_ZERO; |
cp0regs[7] = WORD_ZERO; |
cp0regs[8] = WORD_ZERO; |
cp0regs[9] = WORD_ZERO; |
cp0regs[0] = WORD_ZERO; |
cp0regs[11] = WORD_ZERO; |
cp0regs[12] = WORD_ZERO; |
cp0regs[13] = WORD_ZERO; |
cp0regs[14] = WORD_ZERO; |
cp0regs[15] = WORD_ZERO; |
cp0regs[16] = WORD_ZERO; |
cp0regs[17] = WORD_ZERO; |
cp0regs[18] = WORD_ZERO; |
cp0regs[19] = WORD_ZERO; |
cp0regs[20] = WORD_ZERO; |
cp0regs[21] = WORD_ZERO; |
cp0regs[22] = WORD_ZERO; |
cp0regs[23] = WORD_ZERO; |
cp0regs[24] = WORD_ZERO; |
cp0regs[25] = WORD_ZERO; |
cp0regs[26] = WORD_ZERO; |
cp0regs[27] = WORD_ZERO; |
cp0regs[28] = WORD_ZERO; |
cp0regs[29] = WORD_ZERO; |
cp0regs[30] = WORD_ZERO; |
cp0regs[31] = WORD_ZERO; |
} |
else |
if(check_excep.read() == SC_LOGIC_1) |
{ |
cp0regs[13] = cause.read(); |
cp0regs[14] = (sc_lv<32>) to_EPC.read(); |
cp0regs[8] = (sc_lv<32>) to_BadVAddr.read(); |
cp0regs[12] = Temp_Status_Register.read(); |
} |
else |
if(cp0_inst.read() == CP0_ERET) |
cp0regs[12] = Temp_Status_Register.read(); |
else |
if ((reg_rw.read() == SC_LOGIC_1)) |
{ |
cp0regs[reg_no.read()] = reg_rs.read(); |
} |
} |
|
void cp0_register::cp0_status_register() |
{ |
|
sc_lv<6> temp; |
sc_lv<32> temp_32; |
|
if((check_excep.read() == SC_LOGIC_1) && (reset.read() == false) ) |
{ |
temp_32 = (cp0regs[12]).read(); |
|
temp.range(5,2) = temp_32.range(3,0); |
temp.range(1,0) = "00"; |
|
temp_32.range(5,0) = temp; |
|
Temp_Status_Register.write(temp_32); |
//(cp0regs[12]).write(temp_32); |
} |
else |
if((cp0_inst.read() == CP0_ERET) && (reset.read() == false)) |
{ |
temp_32 = (cp0regs[12]).read(); |
|
temp.range(3,0) = temp_32.range(5,2); |
temp.range(5,4) = temp_32.range(5,4); |
|
temp_32.range(5,0) = temp; |
|
Temp_Status_Register.write(temp_32); |
//(cp0regs[12]).write(temp_32); |
} |
else; |
} |
|
void cp0_register::enable_interrupt_and_OS() |
{ |
enable_interrupt.write(((cp0regs[12]).read())[0]); |
enable_kernel_mode.write(((cp0regs[12]).read())[1]); |
|
|
} |
|
/trunk/cpu/cpu/cp0/set_stop_pc.h
0,0 → 1,38
#include "systemc.h" |
|
#include "../../constants/constants.h" |
|
SC_MODULE(set_stop_pc) |
{ |
sc_in<bool> in_clk; |
sc_in<bool> reset; |
|
sc_in<bool> x_insthold; |
sc_out<bool> insthold; |
|
sc_in<sc_lv<32> > pc_in; |
sc_in<sc_lv<4> > cp0_inst; |
sc_out<sc_lv<32> > new_pc; |
sc_out<sc_logic> load_epc; |
sc_in<bool> check_excep; |
sc_in<sc_uint<32> > EPC_FOR_RFE; |
|
sc_signal<int> currentstate , nextstate; |
|
void update_state(); |
void do_set_stop_pc(); |
|
SC_CTOR(set_stop_pc) |
{ |
SC_METHOD(update_state); |
sensitive_pos << in_clk; |
|
SC_METHOD(do_set_stop_pc); |
sensitive << reset; |
sensitive << x_insthold; |
sensitive << check_excep; |
sensitive << currentstate; |
sensitive << cp0_inst; |
sensitive << EPC_FOR_RFE; |
} |
}; |
/trunk/cpu/cpu/cp0/cp0_register.h
0,0 → 1,61
#include "systemc.h" |
#include "../../constants/constants.h" |
|
SC_MODULE(cp0_register) |
{ |
sc_in<bool> in_clk; |
sc_in<bool> reset; |
|
sc_signal<sc_lv<32> > cp0regs[32]; |
|
sc_in<sc_uint<5> > reg_no; |
sc_in<sc_logic> reg_rw; |
sc_in<sc_lv<32> > reg_rs; |
sc_out<sc_lv<32> > reg_out; |
|
sc_in<bool> check_excep; |
//sc_in<sc_logic> interrupt_signal; |
sc_in<sc_lv<32> > cause; |
sc_in<sc_uint<32> > to_BadVAddr; |
sc_in<sc_uint<32> > to_EPC; |
|
sc_in<sc_lv<4> > cp0_inst; |
|
sc_out<sc_uint<32> > EPC_FOR_RFE; |
sc_signal<sc_lv<32> > Temp_Status_Register; |
|
sc_out<sc_logic> enable_interrupt; |
sc_out<sc_logic> enable_kernel_mode; |
|
void cp0_register_read(); |
void cp0_register_write(); |
void cp0_status_register(); |
void enable_interrupt_and_OS(); |
|
SC_CTOR(cp0_register) |
{ |
SC_METHOD(cp0_register_read); |
sensitive << reg_no << reg_rw << cp0regs[0] << cp0regs[1] << cp0regs[2]; |
sensitive << cp0regs[3] << cp0regs[4] << cp0regs[5] << cp0regs[6] << cp0regs[7]; |
sensitive << cp0regs[8] << cp0regs[9] << cp0regs[10] << cp0regs[11] << cp0regs[12]; |
sensitive << cp0regs[13] << cp0regs[14] << cp0regs[15] << cp0regs[16] << cp0regs[17]; |
sensitive << cp0regs[18] << cp0regs[19] << cp0regs[20] << cp0regs[21] << cp0regs[22]; |
sensitive << cp0regs[23] << cp0regs[24] << cp0regs[25] << cp0regs[26] << cp0regs[27]; |
sensitive << cp0regs[28] << cp0regs[29] << cp0regs[30] << cp0regs[31]; |
|
SC_METHOD(cp0_register_write); |
sensitive_neg << in_clk; |
//sensitive << cause << to_EPC << to_BadVAddr; |
//sensitive << check_excep; |
|
|
SC_METHOD(cp0_status_register); |
sensitive << check_excep << cp0_inst; |
|
SC_METHOD(enable_interrupt_and_OS); |
sensitive << cp0regs[12]; |
} |
|
|
|
}; |
/trunk/cpu/cpu/mem_stage.cpp
0,0 → 1,5
//! MEM Stage module |
// |
// $Id: mem_stage.cpp,v 1.1 2006-01-21 03:37:32 igorloi Exp $ |
// |
#include "mem_stage.h" |
/trunk/cpu/cpu/writeback_ctrl.h
0,0 → 1,28
#include "systemc.h" |
#include "../constants/constants.h" |
|
SC_MODULE(writeback_ctrl) |
{ |
sc_in<sc_logic> m_wb_IBUS; |
sc_in<sc_logic> m_wb_inst_addrl; |
sc_in<sc_logic> m_wb_syscall_exception; |
sc_in<sc_logic> m_wb_illegal_instruction; |
sc_in<sc_logic> m_wb_ovf_excep; |
sc_in<sc_logic> m_wb_DBUS; |
sc_in<sc_logic> m_wb_data_addrl; |
sc_in<sc_logic> m_wb_data_addrs; |
sc_in<bool> m_wb_interrupt_signal; |
|
|
sc_out<sc_logic> wb_exception; |
|
void do_writeback_ctrl(); |
|
SC_CTOR(writeback_ctrl) |
{ |
SC_METHOD(do_writeback_ctrl); |
sensitive << m_wb_IBUS << m_wb_inst_addrl << m_wb_syscall_exception; |
sensitive << m_wb_illegal_instruction << m_wb_ovf_excep; |
sensitive << m_wb_DBUS << m_wb_data_addrl << m_wb_data_addrs << m_wb_interrupt_signal; |
} |
}; |
/trunk/cpu/cpu/pc_stage/reg_pc.cpp
0,0 → 1,37
#include "reg_pc.h" |
|
void reg_pc::do_reg_pc() |
{ |
sc_lv<32> pc; |
|
instdatawrite = WORD_ZERO; |
|
if(reset.read() == true) |
{ |
instreq.write(SC_LOGIC_1); |
instrw.write(SC_LOGIC_0); |
|
instaddr = pc = PC_START; |
pc_out = pc = PC_START; |
} |
else |
{ |
if((datahold.read() == false) && (insthold.read() == false) && (enable_pc.read() == SC_LOGIC_1)) |
{ |
instreq.write(SC_LOGIC_1); |
instrw.write(SC_LOGIC_0); |
pc = pc_in.read(); |
instaddr.write(pc); |
pc_out.write(pc_in.read()); |
} |
else |
if((datahold.read() == false) && (insthold.read() == false) && (enable_pc.read() == SC_LOGIC_0)) |
{ |
instreq.write(SC_LOGIC_0); |
instrw.write(SC_LOGIC_0); |
|
instaddr = pc = PC_START; |
pc_out = pc = PC_START; |
} |
} |
} |
/trunk/cpu/cpu/pc_stage/reg_pc.h
0,0 → 1,31
#include "systemc.h" |
#include "../../constants/constants.h" |
#include "../../constants/config.h" |
SC_MODULE(reg_pc) |
{ |
sc_in<bool> in_clk; |
sc_in<bool> reset; |
|
sc_in<bool> insthold; |
sc_in<bool> datahold; |
|
sc_in<sc_logic> enable_pc; |
|
sc_in<sc_lv<32> > pc_in; |
sc_out<sc_lv<32> > pc_out; |
|
sc_out<sc_uint<32> > instaddr; |
sc_out<sc_lv<32> > instdatawrite; |
|
sc_out<sc_logic> instreq; |
sc_out<sc_logic> instrw; |
|
|
void do_reg_pc(); |
|
SC_CTOR(reg_pc) |
{ |
SC_METHOD(do_reg_pc); |
sensitive_pos << in_clk; |
} |
}; |
/trunk/cpu/cpu/ex_stage.h
0,0 → 1,211
// |
// $Id: ex_stage.h,v 1.1 2006-01-21 03:37:32 igorloi Exp $ |
// |
#ifndef _EX_STAGE_H |
#define _EX_STAGE_H |
|
#include <systemc.h> |
|
#include "./ex_stage/reg_ex.h" |
#include "./ex_stage/alu.h" |
#include "./ex_stage/backwrite.h" |
#include "./ex_stage/multiply.h" |
#include "./ex_stage/mux_lo.h" |
#include "./ex_stage/mux_hi.h" |
#include "./ex_stage/mux_rd.h" |
#include "./ex_stage/execute_ctrl.h" |
|
SC_MODULE(ex_stage) |
{ |
sc_in<bool> in_clk; |
sc_in<bool> reset; |
|
sc_in<bool> insthold; |
sc_in<bool> datahold; |
|
// signals from id_stage |
sc_in<sc_lv<32> > id_ex_alu1; |
sc_in<sc_lv<32> > id_ex_alu2; |
sc_in<sc_lv<32> > id_ex_datastore; |
sc_in<sc_lv<6> > id_ex_alu_ctrl; |
sc_in<sc_logic> id_ex_equal; |
sc_in<sc_lv<2> > id_ex_byteselect; |
sc_in<sc_logic> id_ex_bssign; |
sc_in<sc_lv<5> > id_ex_alu_sa; |
|
// signals to be sent on to mem_stage |
sc_in<sc_logic> id_ex_datareq; |
sc_in<sc_logic> id_ex_datarw; |
sc_in<sc_logic> id_ex_memtoreg; |
|
// signal to control save in register |
sc_in<sc_lv<5> > id_ex_writeregister_out; |
sc_in<sc_logic> id_ex_regwrite_out; |
|
sc_out<sc_lv<5> > id_ex_m_writeregister; |
sc_out<sc_logic> id_ex_m_regwrite; |
|
sc_out<sc_logic> id_ex_m_datareq; |
sc_out<sc_logic> id_ex_m_datarw; |
sc_out<sc_lv<32> > id_ex_m_datastore; |
sc_out<sc_lv<32> > ex_m_alu; |
|
sc_out<sc_logic> id_ex_m_memtoreg; |
|
sc_out<sc_lv<32> > ex_id_forward; |
|
// Signals directly to mem stage |
sc_out<sc_lv<2> > id_ex_m_byteselect; |
sc_out<sc_logic> id_ex_m_bssign; |
|
sc_signal<sc_logic> ovf_excep; |
|
sc_in<sc_logic> id_ex_IBUS; |
sc_in<sc_logic> id_ex_inst_addrl; |
sc_in<sc_logic> id_ex_syscall_exception; |
sc_in<sc_logic> id_ex_illegal_instruction; |
sc_out<sc_logic> ex_m_IBUS; |
sc_out<sc_logic> ex_m_inst_addrl; |
sc_out<sc_logic> ex_m_syscall_exception; |
sc_out<sc_logic> ex_m_illegal_instruction; |
sc_out<sc_logic> ex_m_ovf_excep; |
|
sc_out<sc_logic> ex_exception; |
sc_in<sc_logic> enable_execute; |
|
sc_in<sc_uint<32> > id_ex_instaddr; |
sc_out<sc_uint<32> > ex_m_instaddr; |
|
// Signals from cp0 |
// To prevent memory access in case of Address Error Exception or OCP action |
sc_in<sc_logic> addr_err; |
|
// sc_in<sc_lv<32> > cp0_data_from; |
|
sc_signal<sc_lv<32> > ex_alu_s; |
sc_signal<sc_lv<32> > ex_id_forward_s; |
sc_signal<sc_lv<32> > in_ex_alu_s; |
sc_signal<sc_lv<32> > in_ex_id_forward_s; |
|
// special registers |
sc_signal<sc_lv<32> > hi; |
sc_signal<sc_lv<32> > lo; |
sc_signal<sc_lv<32> > in_lo; |
sc_signal<sc_lv<32> > in_hi; |
sc_signal<sc_lv<32> > out_lo; |
sc_signal<sc_lv<32> > out_hi; |
|
|
|
sc_signal<sc_logic> carry; |
|
reg_ex *reg_ex1; |
alu *alu1; |
backwrite *backwrite1; |
multiply *multiply1; |
mux_lo *mux_lo1; |
mux_hi *mux_hi1; |
mux_rd *mux_rd1; |
execute_ctrl *execute_ctrl1; |
|
SC_CTOR(ex_stage) |
{ |
reg_ex1 = new reg_ex("reg_ex"); |
reg_ex1->in_clk(in_clk); |
reg_ex1->reset(reset); |
reg_ex1->insthold(insthold); |
reg_ex1->datahold(datahold); |
reg_ex1->addr_err(addr_err); |
reg_ex1->ex_alu_s(ex_alu_s); |
reg_ex1->ex_m_alu(ex_m_alu); |
reg_ex1->id_ex_datastore(id_ex_datastore); |
reg_ex1->id_ex_m_datastore(id_ex_m_datastore); |
reg_ex1->id_ex_datareq(id_ex_datareq); |
reg_ex1->id_ex_m_datareq(id_ex_m_datareq); |
reg_ex1->id_ex_datarw(id_ex_datarw); |
reg_ex1->id_ex_m_datarw(id_ex_m_datarw); |
reg_ex1->id_ex_memtoreg(id_ex_memtoreg); |
reg_ex1->id_ex_m_memtoreg(id_ex_m_memtoreg); |
reg_ex1->id_ex_writeregister_out(id_ex_writeregister_out); |
reg_ex1->id_ex_m_writeregister(id_ex_m_writeregister); |
reg_ex1->id_ex_regwrite_out(id_ex_regwrite_out); |
reg_ex1->id_ex_m_regwrite(id_ex_m_regwrite); |
reg_ex1->id_ex_byteselect(id_ex_byteselect); |
reg_ex1->id_ex_m_byteselect(id_ex_m_byteselect); |
reg_ex1->id_ex_bssign(id_ex_bssign); |
reg_ex1->id_ex_m_bssign(id_ex_m_bssign); |
reg_ex1->in_lo(in_lo); |
reg_ex1->out_lo(out_lo); |
reg_ex1->in_hi(in_hi); |
reg_ex1->out_hi(out_hi); |
//************************************************************** |
reg_ex1->id_ex_IBUS(id_ex_IBUS); |
reg_ex1->id_ex_inst_addrl(id_ex_inst_addrl); |
reg_ex1->id_ex_syscall_exception(id_ex_syscall_exception); |
reg_ex1->id_ex_illegal_instruction(id_ex_illegal_instruction); |
reg_ex1->ovf_excep(ovf_excep); |
reg_ex1->ex_m_IBUS(ex_m_IBUS); |
reg_ex1->ex_m_inst_addrl(ex_m_inst_addrl); |
reg_ex1->ex_m_syscall_exception(ex_m_syscall_exception); |
reg_ex1->ex_m_illegal_instruction(ex_m_illegal_instruction); |
reg_ex1->ex_m_ovf_excep(ex_m_ovf_excep); |
reg_ex1->id_ex_instaddr(id_ex_instaddr); |
reg_ex1->ex_m_instaddr(ex_m_instaddr); |
//************************************************************** |
reg_ex1->enable_execute(enable_execute); |
|
execute_ctrl1 = new execute_ctrl("execute_ctrl"); |
execute_ctrl1->id_ex_IBUS(id_ex_IBUS); |
execute_ctrl1->id_ex_inst_addrl(id_ex_inst_addrl); |
execute_ctrl1->id_ex_syscall_exception(id_ex_syscall_exception); |
execute_ctrl1->id_ex_illegal_instruction(id_ex_illegal_instruction); |
execute_ctrl1->ovf_excep(ovf_excep); |
execute_ctrl1->ex_exception(ex_exception); |
|
alu1 = new alu("alu"); |
alu1->id_ex_alu1(id_ex_alu1); |
alu1->id_ex_alu2(id_ex_alu2); |
alu1->id_ex_alu_ctrl(id_ex_alu_ctrl); |
alu1->id_ex_equal(id_ex_equal); |
alu1->id_ex_alu_sa(id_ex_alu_sa); |
alu1->ovf_excep(ovf_excep); |
alu1->carry(carry); |
alu1->ex_alu_s(in_ex_alu_s); |
alu1->ex_id_forward_s(in_ex_id_forward_s); |
|
backwrite1 = new backwrite("backwrite"); |
backwrite1->ex_id_forward_s(ex_id_forward_s); |
backwrite1->ex_id_forward(ex_id_forward); |
|
multiply1 = new multiply("multiply"); |
multiply1->id_ex_alu1(id_ex_alu1); |
multiply1->id_ex_alu2(id_ex_alu2); |
multiply1->id_ex_alu_ctrl(id_ex_alu_ctrl); |
multiply1->hi(hi); |
multiply1->lo(lo); |
|
mux_lo1 = new mux_lo("mux_lo"); |
mux_lo1->lo(lo); |
mux_lo1->rs(id_ex_alu1); |
mux_lo1->id_ex_alu_ctrl(id_ex_alu_ctrl); |
mux_lo1->out(in_lo); |
|
mux_hi1 = new mux_hi("mux_hi"); |
mux_hi1->hi(hi); |
mux_hi1->rs(id_ex_alu1); |
mux_hi1->id_ex_alu_ctrl(id_ex_alu_ctrl); |
mux_hi1->out(in_hi); |
|
mux_rd1 = new mux_rd("mux_rd"); |
mux_rd1->in_ex_id_forward_s(in_ex_id_forward_s); //dalla ALU |
mux_rd1->in_ex_alu_s(in_ex_alu_s); // dalla ALU |
mux_rd1->out_lo(out_lo); // dai registri LO |
mux_rd1->out_hi(out_hi); // dai registri HI |
mux_rd1->id_ex_alu_ctrl(id_ex_alu_ctrl); // selettore del MUX |
mux_rd1->out_ex_id_forward_s(ex_id_forward_s); // USCITE verso i registri di pipeline |
mux_rd1->out_ex_alu_s(ex_alu_s); |
} |
}; |
|
#endif |
|
/trunk/cpu/cpu/mux_instaddr.h
0,0 → 1,21
#include "systemc.h" |
#include "../constants/constants.h" |
|
SC_MODULE(mux_instaddr) |
{ |
sc_in<sc_uint<32> > m_wb_instaddr; |
sc_in<sc_uint<32> > ex_m_instaddr; |
|
sc_in<bool> m_wb_interrupt_signal; |
|
sc_out<sc_uint<32> > m_wb_instaddr_s; |
|
|
void do_mux_instaddr(); |
|
SC_CTOR(mux_instaddr) |
{ |
SC_METHOD(do_mux_instaddr); |
sensitive << m_wb_instaddr << ex_m_instaddr << m_wb_instaddr; |
} |
}; |
/trunk/cpu/cpu/mem_stage.h
0,0 → 1,190
//! MEM Stage module |
// |
// $Id: mem_stage.h,v 1.1 2006-01-21 03:37:32 igorloi Exp $ |
// |
#ifndef _MEM_STAGE_H |
#define _MEM_STAGE_H |
|
#include "systemc.h" |
|
#include "./mem_stage/select_mem.h" |
#include "./mem_stage/reg_mem.h" |
#include "./mem_stage/multiplexer_mem.h" |
#include "./mem_stage/memstage_ctrl.h" |
#include "./mem_stage/mux_interrupt.h" |
#include "./mem_stage/flag_interr.h" |
|
SC_MODULE(mem_stage) |
{ |
sc_in<bool> in_clk; |
sc_in<bool> reset; |
|
sc_in<bool> insthold; |
sc_in<bool> datahold; |
|
sc_in<sc_logic> id_ex_m_datareq; |
sc_in<sc_logic> id_ex_m_datarw; |
sc_in<sc_lv<32> > id_ex_m_datastore; |
sc_in<sc_lv<32> > ex_m_alu; |
|
// signal to mem_stage from ex_stage |
sc_in<sc_logic> id_ex_m_memtoreg; |
sc_in<sc_lv<2> > id_ex_m_byteselect; |
sc_in<sc_logic> id_ex_m_bssign; |
|
// signal to data memory |
sc_in<sc_lv<32> > dataread; |
sc_out<sc_lv<32> > datawrite; |
sc_out<sc_uint<32> > dataaddr; |
sc_out<sc_logic> datareq; |
sc_out<sc_logic> datarw; |
sc_out<sc_lv<2> > databs; |
|
// signal to control save in register |
sc_in<sc_lv<5> > id_ex_m_writeregister; |
sc_in<sc_logic> id_ex_m_regwrite; |
|
sc_out<sc_lv<5> > id_ex_m_wb_writeregister; |
sc_out<sc_logic> id_ex_m_wb_regwrite; |
|
sc_out<sc_lv<32> > m_id_forward; |
sc_out<sc_lv<32> > wb_id_forward; |
|
sc_in<sc_logic> enable_memstage; |
sc_out<sc_logic> mem_exception; |
|
sc_signal<sc_lv<32> > id_store; |
|
// EXCEPTION SIGNALS |
sc_in<sc_logic> ex_m_IBUS; |
sc_in<sc_logic> ex_m_inst_addrl; |
sc_in<sc_logic> ex_m_syscall_exception; |
sc_in<sc_logic> ex_m_illegal_instruction; |
sc_in<sc_logic> ex_m_ovf_excep; |
sc_in<sc_logic> DBUS; |
sc_in<sc_logic> data_addrl; |
sc_in<sc_logic> data_addrs; |
|
// INTERRUPT SIGNAL |
sc_in<bool> interrupt_signal; |
sc_out<bool> m_wb_interrupt_signal; |
sc_in<sc_logic> enable_interrupt; |
sc_signal<bool> interrupt_signal_out; |
sc_signal<bool> interrupt_out_out; |
sc_signal<bool> ground; |
|
// exception status vector -> to CPO-Cause |
sc_out<sc_logic> m_wb_IBUS; |
sc_out<sc_logic> m_wb_inst_addrl; |
sc_out<sc_logic> m_wb_syscall_exception; |
sc_out<sc_logic> m_wb_illegal_instruction; |
sc_out<sc_logic> m_wb_ovf_excep; |
sc_out<sc_logic> m_wb_DBUS; |
sc_out<sc_logic> m_wb_data_addrl; |
sc_out<sc_logic> m_wb_data_addrs; |
|
|
sc_in<sc_uint<32> > ex_m_instaddr; |
sc_out<sc_uint<32> > m_wb_instaddr; |
|
// sc_in<sc_uint<32> > ex_m_dataaddr; il segnale �dataddr! |
sc_out<sc_uint<32> > m_wb_dataaddr; |
|
select_mem *select_mem1; |
multiplexer_mem *multiplexer_mem1; |
reg_mem *reg_mem1; |
memstage_ctrl *memstage_ctrl1; |
mux_interrupt *mux_interrupt1; |
flag_interr *flag_interr1; |
|
SC_CTOR(mem_stage) |
{ |
select_mem1 = new select_mem("select_mem"); |
select_mem1->id_ex_m_datareq(id_ex_m_datareq); |
select_mem1->id_ex_m_datarw(id_ex_m_datarw); |
select_mem1->id_ex_m_byteselect(id_ex_m_byteselect); |
select_mem1->id_ex_m_datastore(id_ex_m_datastore); |
select_mem1->datawrite(datawrite); |
select_mem1->ex_m_alu(ex_m_alu); |
select_mem1->dataaddr(dataaddr); |
select_mem1->datareq(datareq); |
select_mem1->datarw(datarw); |
select_mem1->databs(databs); |
select_mem1->enable_memstage(enable_memstage); |
|
multiplexer_mem1 = new multiplexer_mem("multiplexer_mem"); |
multiplexer_mem1->id_ex_m_byteselect(id_ex_m_byteselect); |
multiplexer_mem1->id_ex_m_bssign(id_ex_m_bssign); |
multiplexer_mem1->id_ex_m_memtoreg(id_ex_m_memtoreg); |
multiplexer_mem1->ex_m_alu(ex_m_alu); |
multiplexer_mem1->dataread(dataread); |
multiplexer_mem1->id_store(id_store); |
multiplexer_mem1->m_id_forward(m_id_forward); |
|
reg_mem1 = new reg_mem("reg_mem"); |
reg_mem1->in_clk(in_clk); |
reg_mem1->reset(reset); |
reg_mem1->insthold(insthold); |
reg_mem1->datahold(datahold); |
reg_mem1->wb_id_forward(wb_id_forward); |
reg_mem1->id_ex_m_wb_writeregister(id_ex_m_wb_writeregister); |
reg_mem1->id_ex_m_wb_regwrite(id_ex_m_wb_regwrite); |
reg_mem1->id_store(id_store); |
reg_mem1->id_ex_m_writeregister(id_ex_m_writeregister); |
reg_mem1->id_ex_m_regwrite(id_ex_m_regwrite); |
|
reg_mem1->ex_m_IBUS(ex_m_IBUS); |
reg_mem1->ex_m_inst_addrl(ex_m_inst_addrl); |
reg_mem1->ex_m_syscall_exception(ex_m_syscall_exception); |
reg_mem1->ex_m_illegal_instruction(ex_m_illegal_instruction); |
reg_mem1->ex_m_ovf_excep(ex_m_ovf_excep); |
reg_mem1->DBUS(DBUS); |
reg_mem1->data_addrl(data_addrl); |
reg_mem1->data_addrs(data_addrs); |
reg_mem1->ex_m_instaddr(ex_m_instaddr); |
reg_mem1->ex_m_dataaddr(dataaddr); |
reg_mem1->interrupt_signal(interrupt_out_out); |
reg_mem1->m_wb_interrupt_signal(m_wb_interrupt_signal); |
|
reg_mem1->m_wb_IBUS(m_wb_IBUS); |
reg_mem1->m_wb_inst_addrl(m_wb_inst_addrl); |
reg_mem1->m_wb_syscall_exception(m_wb_syscall_exception); |
reg_mem1->m_wb_illegal_instruction(m_wb_illegal_instruction); |
reg_mem1->m_wb_ovf_excep(m_wb_ovf_excep); |
reg_mem1->m_wb_DBUS(m_wb_DBUS); |
reg_mem1->m_wb_data_addrl(m_wb_data_addrl); |
reg_mem1->m_wb_data_addrs(m_wb_data_addrs); |
reg_mem1->m_wb_instaddr(m_wb_instaddr); |
reg_mem1->m_wb_dataaddr(m_wb_dataaddr); |
reg_mem1->enable_memstage(enable_memstage); |
|
memstage_ctrl1 = new memstage_ctrl("memstage_ctrl"); |
memstage_ctrl1->ex_m_IBUS(ex_m_IBUS); |
memstage_ctrl1->ex_m_inst_addrl(ex_m_inst_addrl); |
memstage_ctrl1->ex_m_syscall_exception(ex_m_syscall_exception); |
memstage_ctrl1->ex_m_illegal_instruction(ex_m_illegal_instruction); |
memstage_ctrl1->ex_m_ovf_excep(ex_m_ovf_excep); |
memstage_ctrl1->DBUS(DBUS); |
memstage_ctrl1->data_addrl(data_addrl); |
memstage_ctrl1->data_addrs(data_addrs); |
memstage_ctrl1->mem_exception(mem_exception); |
memstage_ctrl1->interrupt_signal(interrupt_out_out); |
|
flag_interr1 = new flag_interr("flag_interr"); |
flag_interr1->in_clk(in_clk); |
flag_interr1->reset(reset); |
flag_interr1->interrupt_in(interrupt_signal_out); |
flag_interr1->interrupt_out(interrupt_out_out); |
|
ground.write(false); |
|
mux_interrupt1 = new mux_interrupt("mux_interrupt"); |
mux_interrupt1->IN_A(interrupt_signal); |
mux_interrupt1->IN_B(ground); |
mux_interrupt1->SEL(enable_interrupt); |
mux_interrupt1->OUT(interrupt_signal_out); |
} |
}; |
|
|
#endif |
/trunk/cpu/cpu/enable_stage.cpp
0,0 → 1,62
#include "enable_stage.h" |
|
void enable_stage::do_enable_stage() |
{ |
if(wb_exception.read() == SC_LOGIC_1) |
{ |
enable_pc.write(SC_LOGIC_0); |
enable_fetch.write(SC_LOGIC_0); |
enable_decode.write(SC_LOGIC_0); |
enable_execute.write(SC_LOGIC_0); |
enable_memstage.write(SC_LOGIC_0); |
} |
else |
if(mem_exception.read() == SC_LOGIC_1) |
{ |
enable_pc.write(SC_LOGIC_0); |
enable_fetch.write(SC_LOGIC_0); |
enable_decode.write(SC_LOGIC_0); |
enable_execute.write(SC_LOGIC_0); |
enable_memstage.write(SC_LOGIC_0); |
} |
else |
if(ex_exception.read() == SC_LOGIC_1) |
{ |
enable_pc.write(SC_LOGIC_0); |
enable_fetch.write(SC_LOGIC_0); |
enable_decode.write(SC_LOGIC_0); |
enable_execute.write(SC_LOGIC_0); |
enable_memstage.write(SC_LOGIC_1); |
} |
else |
if(id_exception.read() == SC_LOGIC_1) |
{ |
enable_pc.write(SC_LOGIC_0); |
enable_fetch.write(SC_LOGIC_0); |
enable_decode.write(SC_LOGIC_0); |
enable_execute.write(SC_LOGIC_1); |
enable_memstage.write(SC_LOGIC_1); |
} |
else |
if(if_exception.read() == SC_LOGIC_1) |
{ |
enable_pc.write(SC_LOGIC_0); |
enable_fetch.write(SC_LOGIC_0); |
enable_decode.write(SC_LOGIC_1); |
enable_execute.write(SC_LOGIC_1); |
enable_memstage.write(SC_LOGIC_1); |
} |
else |
{ |
enable_pc.write(SC_LOGIC_1); |
enable_fetch.write(SC_LOGIC_1); |
enable_decode.write(SC_LOGIC_1); |
enable_execute.write(SC_LOGIC_1); |
enable_memstage.write(SC_LOGIC_1); |
} |
|
|
|
|
|
} |
/trunk/cpu/cpu/sc_cpu.cpp
0,0 → 1,244
// |
// $Id: sc_cpu.cpp,v 1.1 2006-01-21 03:37:32 igorloi Exp $ |
// |
// #define _ASM_ONLY_ |
// #define _DOBRANCH_ -- should be defined in id_stage only! |
#include "sc_cpu.h" |
|
sc_cpu::sc_cpu(const sc_module_name& name_) |
{ |
SC_METHOD(clocktik); |
sensitive_pos << in_clk; |
|
pc = new pc_stage("pc_stage"); |
pc->in_clk(in_clk); |
pc->reset(reset); |
pc->pc_in(pc_in); |
pc->pc_out(pc_out); |
pc->insthold(insthold); |
pc->datahold(datahold); |
pc->instreq(instreq); |
pc->instaddr(instaddr); |
pc->instdatawrite(instdatawrite); |
pc->instrw(instrw); |
pc->enable_pc(enable_pc); |
|
|
if_s = new if_stage("if_stage"); |
if_s->in_clk(in_clk); |
if_s->reset(reset); |
if_s->pc_out(pc_out); |
if_s->id_new_pc(id_new_pc); |
if_s->id_jmp_tar(id_jmp_tar); |
if_s->id_ctrl(id_ctrl); |
if_s->id_branch(id_branch); |
if_s->pc_in(pc_in); |
if_s->instdataread(instdataread); |
if_s->if_id_inst(if_id_inst); |
if_s->if_id_next_pc(if_id_next_pc); |
if_s->insthold(insthold); |
if_s->datahold(datahold); |
if_s->new_pc(new_pc); |
if_s->load_epc(load_epc); |
|
// only to mananage exceptions |
//****************************************** |
if_s->IBUS(IBUS); |
if_s->inst_addrl(inst_addrl); |
if_s->if_id_IBUS(if_id_IBUS); |
if_s->if_id_inst_addrl(if_id_inst_addrl); |
if_s->enable_fetch(enable_fetch); |
if_s->if_exception(if_exception); |
if_s->pc_if_instaddr(instaddr); |
if_s->if_id_instaddr(if_id_instaddr); |
//****************************************** |
|
|
id = new id_stage("id_stage"); |
id->in_clk(in_clk); |
id->reset(reset); |
id->insthold(insthold); |
id->datahold(datahold); |
id->if_id_next_pc(if_id_next_pc); |
id->if_id_inst(if_id_inst); |
id->id_jmp_tar(id_jmp_tar); |
id->id_new_pc(id_new_pc); |
id->id_branch(id_branch); |
id->id_ctrl(id_ctrl); |
id->id_ex_alu1(id_ex_alu1); |
id->id_ex_alu2(id_ex_alu2); |
id->id_ex_datastore(id_ex_datastore); |
id->id_ex_alu_ctrl(id_ex_alu_ctrl); |
id->id_ex_alu_sa(id_ex_alu_sa); |
|
id->id_ex_byteselect(id_ex_byteselect); |
id->id_ex_bssign(id_ex_bssign); |
|
id->id_ex_equal(id_ex_equal); |
id->id_ex_datareq(id_ex_datareq); |
id->id_ex_datarw(id_ex_datarw); |
id->id_ex_memtoreg(id_ex_memtoreg); |
id->id_ex_writeregister_out(id_ex_writeregister_out); |
id->id_ex_regwrite_out(id_ex_regwrite_out); |
id->id_ex_m_writeregister(id_ex_m_writeregister); |
id->id_ex_m_wb_writeregister(id_ex_m_wb_writeregister); |
id->id_ex_m_regwrite(id_ex_m_regwrite); |
id->id_ex_m_wb_regwrite(id_ex_m_wb_regwrite); |
id->ex_id_forward(ex_id_forward); |
id->m_id_forward(m_id_forward); |
id->wb_id_forward(wb_id_forward); |
id->cp0_inst(cp0_inst); |
id->cp0_reg_no(reg_no); |
id->cp0_reg_rw(reg_rw); |
id->cp0_reg_rs(reg_rs); |
id->cp0_reg_out(reg_out); |
// only to mananage exceptions |
//******************************************************* |
id->if_id_IBUS(if_id_IBUS); |
id->if_id_inst_addrl(if_id_inst_addrl); |
id->id_ex_IBUS(id_ex_IBUS); |
id->id_ex_inst_addrl(id_ex_inst_addrl); |
id->id_ex_syscall_exception(id_ex_syscall_exception); |
id->id_ex_illegal_instruction(id_ex_illegal_instruction); |
id->if_id_instaddr(if_id_instaddr); |
id->id_ex_instaddr(id_ex_instaddr); |
//******************************************************* |
id->enable_decode(enable_decode); |
id->id_exception(id_exception); |
id->enable_kernel_mode(enable_kernel_mode); // when this bit is set to one the cpu are running in Kernel_mode |
|
|
ex = new ex_stage("ex_stage"); |
ex->in_clk(in_clk); |
ex->reset(reset); |
ex->insthold(insthold); |
ex->datahold(datahold); |
ex->id_ex_alu1(id_ex_alu1); |
ex->id_ex_alu2(id_ex_alu2); |
ex->id_ex_datastore(id_ex_datastore); |
ex->id_ex_alu_ctrl(id_ex_alu_ctrl); |
ex->id_ex_alu_sa(id_ex_alu_sa); |
ex->id_ex_byteselect(id_ex_byteselect); |
ex->id_ex_bssign(id_ex_bssign); |
|
ex->id_ex_equal(id_ex_equal); |
ex->id_ex_datareq(id_ex_datareq); |
ex->id_ex_datarw(id_ex_datarw); |
ex->id_ex_memtoreg(id_ex_memtoreg); |
ex->id_ex_writeregister_out(id_ex_writeregister_out); |
ex->id_ex_regwrite_out(id_ex_regwrite_out); |
ex->id_ex_m_writeregister(id_ex_m_writeregister); |
ex->id_ex_m_regwrite(id_ex_m_regwrite); |
ex->id_ex_m_datastore(id_ex_m_datastore); |
ex->ex_m_alu(ex_m_alu); |
ex->id_ex_m_datareq(id_ex_m_datareq); |
ex->id_ex_m_datarw(id_ex_m_datarw); |
ex->id_ex_m_memtoreg(id_ex_m_memtoreg); |
ex->id_ex_m_byteselect(id_ex_m_byteselect); |
ex->id_ex_m_bssign(id_ex_m_bssign); |
ex->ex_id_forward(ex_id_forward); |
// only to mananage exceptions |
//******************************************************* |
ex->id_ex_IBUS(id_ex_IBUS); |
ex->id_ex_inst_addrl(id_ex_inst_addrl); |
ex->id_ex_syscall_exception(id_ex_syscall_exception); |
ex->id_ex_illegal_instruction(id_ex_illegal_instruction); |
ex->ex_m_IBUS(ex_m_IBUS); |
ex->ex_m_inst_addrl(ex_m_inst_addrl); |
ex->ex_m_syscall_exception(ex_m_syscall_exception); |
ex->ex_m_illegal_instruction(ex_m_illegal_instruction); |
ex->ex_m_ovf_excep(ex_m_ovf_excep); |
ex->id_ex_instaddr(id_ex_instaddr); |
ex->ex_m_instaddr(ex_m_instaddr); |
//******************************************************* |
// from cp0 |
ex->addr_err(addr_err); |
ex->enable_execute(enable_execute); |
ex->ex_exception(ex_exception); |
|
|
mem = new mem_stage("mem_stage"); |
mem->in_clk(in_clk); |
mem->reset(reset); |
mem->insthold(insthold); |
mem->datahold(datahold); |
mem->dataread(dataread); |
mem->datawrite(datawrite); |
mem->dataaddr(dataaddr); |
mem->datareq(datareq); |
mem->datarw(datarw); |
mem->databs(databs); |
mem->ex_m_alu(ex_m_alu); |
mem->id_ex_m_datastore(id_ex_m_datastore); |
mem->id_ex_m_datareq(id_ex_m_datareq); |
mem->id_ex_m_datarw(id_ex_m_datarw); |
mem->id_ex_m_memtoreg(id_ex_m_memtoreg); |
|
mem->id_ex_m_byteselect(id_ex_m_byteselect); |
mem->id_ex_m_bssign(id_ex_m_bssign); |
|
mem->id_ex_m_writeregister(id_ex_m_writeregister); |
mem->id_ex_m_regwrite(id_ex_m_regwrite); |
mem->id_ex_m_wb_writeregister(id_ex_m_wb_writeregister); |
mem->id_ex_m_wb_regwrite(id_ex_m_wb_regwrite); |
mem->m_id_forward(m_id_forward); |
mem->wb_id_forward(wb_id_forward); |
|
mem->ex_m_IBUS(ex_m_IBUS); |
mem->ex_m_inst_addrl(ex_m_inst_addrl); |
mem->ex_m_syscall_exception(ex_m_syscall_exception); |
mem->ex_m_illegal_instruction(ex_m_illegal_instruction); |
mem->ex_m_ovf_excep(ex_m_ovf_excep); |
mem->DBUS(DBUS); |
mem->data_addrl(data_addrl); |
mem->data_addrs(data_addrs); |
|
mem->m_wb_IBUS(m_wb_IBUS); |
mem->m_wb_inst_addrl(m_wb_inst_addrl); |
mem->m_wb_syscall_exception(m_wb_syscall_exception); |
mem->m_wb_illegal_instruction(m_wb_illegal_instruction); |
mem->m_wb_ovf_excep(m_wb_ovf_excep); |
mem->m_wb_DBUS(m_wb_DBUS); |
mem->m_wb_data_addrl(m_wb_data_addrl); |
mem->m_wb_data_addrs(m_wb_data_addrs); |
|
mem->ex_m_instaddr(ex_m_instaddr); |
mem->m_wb_instaddr(m_wb_instaddr); |
mem->m_wb_dataaddr(m_wb_dataaddr); //aggiunta l'uscita dell indirizzo DATAMEM in caso di page fault |
mem->mem_exception(mem_exception); |
mem->enable_memstage(enable_memstage); |
mem->interrupt_signal(interrupt_signal); |
mem->m_wb_interrupt_signal(m_wb_interrupt_signal); |
mem->enable_interrupt(enable_interrupt); |
|
enable_stage1 = new enable_stage("enable_stage"); |
enable_stage1->enable_pc(enable_pc); |
enable_stage1->enable_fetch(enable_fetch); |
enable_stage1->enable_decode(enable_decode); |
enable_stage1->enable_execute(enable_execute); |
enable_stage1->enable_memstage(enable_memstage); |
enable_stage1->if_exception(if_exception); |
enable_stage1->id_exception(id_exception); |
enable_stage1->ex_exception(ex_exception); |
enable_stage1->mem_exception(mem_exception); |
enable_stage1->wb_exception(wb_exception); |
|
|
writeback_ctrl1 = new writeback_ctrl("writeback_ctrl"); |
writeback_ctrl1->m_wb_IBUS(m_wb_IBUS); |
writeback_ctrl1->m_wb_inst_addrl(m_wb_inst_addrl); |
writeback_ctrl1->m_wb_syscall_exception(m_wb_syscall_exception); |
writeback_ctrl1->m_wb_illegal_instruction(m_wb_illegal_instruction); |
writeback_ctrl1->m_wb_ovf_excep(m_wb_ovf_excep); |
writeback_ctrl1->m_wb_DBUS(m_wb_DBUS); |
writeback_ctrl1->m_wb_data_addrl(m_wb_data_addrl); |
writeback_ctrl1->m_wb_data_addrs(m_wb_data_addrs); |
writeback_ctrl1->wb_exception(wb_exception); |
writeback_ctrl1->m_wb_interrupt_signal(m_wb_interrupt_signal); |
|
mux_instaddr1 = new mux_instaddr("mux_instaddr"); |
mux_instaddr1->m_wb_instaddr(m_wb_instaddr); |
mux_instaddr1->ex_m_instaddr(ex_m_instaddr); |
mux_instaddr1->m_wb_instaddr_s(m_wb_instaddr_s); |
mux_instaddr1->m_wb_interrupt_signal(m_wb_interrupt_signal); |
} |
/trunk/cpu/cpu/enable_stage.h
0,0 → 1,27
#include "systemc.h" |
#include "../constants/constants.h" |
|
SC_MODULE(enable_stage) |
{ |
sc_in<sc_logic> if_exception; |
sc_in<sc_logic> id_exception; |
sc_in<sc_logic> ex_exception; |
sc_in<sc_logic> mem_exception; |
sc_in<sc_logic> wb_exception; |
|
sc_out<sc_logic> enable_pc; |
sc_out<sc_logic> enable_fetch; |
sc_out<sc_logic> enable_decode; |
sc_out<sc_logic> enable_execute; |
sc_out<sc_logic> enable_memstage; |
|
void do_enable_stage(); |
|
SC_CTOR(enable_stage) |
{ |
SC_METHOD(do_enable_stage); |
sensitive << if_exception << id_exception; |
sensitive << ex_exception << mem_exception; |
sensitive << wb_exception ; |
} |
}; |
/trunk/cpu/cpu/ex_stage/mux_hi.h
0,0 → 1,18
#include "systemc.h" |
#include "../../constants/constants.h" |
|
SC_MODULE(mux_hi) |
{ |
sc_in<sc_lv<32> > hi; |
sc_in<sc_lv<32> > rs; |
sc_in<sc_lv<6> > id_ex_alu_ctrl; |
sc_out<sc_lv<32> > out; |
|
void do_mux_hi(); |
|
SC_CTOR(mux_hi) |
{ |
SC_METHOD(do_mux_hi); |
sensitive << hi << rs << id_ex_alu_ctrl; |
} |
}; |
/trunk/cpu/cpu/ex_stage/mux_rd.cpp
0,0 → 1,21
#include "mux_rd.h" |
|
void mux_rd::do_mux_rd() |
{ |
if (id_ex_alu_ctrl.read() == FUNC_MFLO) |
{ |
out_ex_alu_s.write(out_lo.read()); |
out_ex_id_forward_s.write(out_lo.read()); |
} |
else |
if (id_ex_alu_ctrl.read() == FUNC_MFHI) |
{ |
out_ex_alu_s.write(out_hi.read()); |
out_ex_id_forward_s.write(out_hi.read()); |
} |
else |
{ |
out_ex_alu_s.write(in_ex_alu_s.read()); |
out_ex_id_forward_s.write(in_ex_id_forward_s.read()); |
} |
} |
/trunk/cpu/cpu/ex_stage/ex_stage.cpp
0,0 → 1,5
//! EX Stage module |
// |
// $Id: ex_stage.cpp,v 1.00 2004/12/23 22:253:00 DIEE Cagliari |
// |
#include "ex_stage.h" |
/trunk/cpu/cpu/ex_stage/mux_lo.cpp
0,0 → 1,9
#include "mux_lo.h" |
|
void mux_lo::do_mux_lo() |
{ |
if (id_ex_alu_ctrl.read() == FUNC_MTLN) |
out.write(rs.read()); |
else |
out.write(lo.read()); |
} |
/trunk/cpu/cpu/ex_stage/mux_rd.h
0,0 → 1,21
#include "systemc.h" |
#include "../../constants/constants.h" |
|
SC_MODULE(mux_rd) |
{ |
sc_in<sc_lv<32> > out_lo; |
sc_in<sc_lv<32> > out_hi; |
sc_in<sc_lv<32> > in_ex_id_forward_s; |
sc_in<sc_lv<32> > in_ex_alu_s; |
sc_in<sc_lv<6> > id_ex_alu_ctrl; |
sc_out<sc_lv<32> > out_ex_id_forward_s; |
sc_out<sc_lv<32> > out_ex_alu_s; |
|
void do_mux_rd(); |
|
SC_CTOR(mux_rd) |
{ |
SC_METHOD(do_mux_rd); |
sensitive << out_lo << out_hi << id_ex_alu_ctrl << in_ex_id_forward_s << in_ex_alu_s; |
} |
} ; |
/trunk/cpu/cpu/ex_stage/ex_stage.h
0,0 → 1,180
// |
// $Id: ex_stage.h,v 1.1 2006-01-21 03:37:34 igorloi Exp $ |
// |
#ifndef _EX_STAGE_H |
#define _EX_STAGE_H |
|
#include <systemc.h> |
#include "reg_ex.h" |
#include "alu.h" |
#include "backwrite.h" |
#include "multiply.h" |
#include "mux_lo.h" |
#include "mux_hi.h" |
#include "mux_rd.h" |
|
|
/*#include "./ex_stage/reg_ex.h" |
#include "./ex_stage/alu.h" |
#include "./ex_stage/backwrite.h" |
#include "./ex_stage/multiply.h" |
#include "./ex_stage/mux_lo.h" |
#include "./ex_stage/mux_hi.h" |
#include "./ex_stage/mux_rd.h" |
*/ |
SC_MODULE(ex_stage) |
{ |
sc_in<bool> in_clk; |
sc_in<bool> reset; |
|
sc_in<bool> insthold; |
sc_in<bool> datahold; |
|
// signals from id_stage |
sc_in<sc_lv<32> > id_ex_alu1; |
sc_in<sc_lv<32> > id_ex_alu2; |
sc_in<sc_lv<32> > id_ex_datastore; |
sc_in<sc_lv<6> > id_ex_alu_ctrl; |
sc_in<sc_logic> id_ex_equal; |
sc_in<sc_lv<2> > id_ex_byteselect; |
sc_in<sc_logic> id_ex_bssign; |
sc_in<sc_lv<5> > id_ex_alu_sa; |
|
// signals to be sent on to mem_stage |
sc_in<sc_logic> id_ex_datareq; |
sc_in<sc_logic> id_ex_datarw; |
sc_in<sc_logic> id_ex_memtoreg; |
|
// signal to control save in register |
sc_in<sc_lv<5> > id_ex_writeregister_out; |
sc_in<sc_logic> id_ex_regwrite_out; |
|
sc_out<sc_lv<5> > id_ex_m_writeregister; |
sc_out<sc_logic> id_ex_m_regwrite; |
|
sc_out<sc_logic> id_ex_m_datareq; |
sc_out<sc_logic> id_ex_m_datarw; |
sc_out<sc_lv<32> > id_ex_m_datastore; |
sc_out<sc_lv<32> > ex_m_alu; |
|
sc_out<sc_logic> id_ex_m_memtoreg; |
|
sc_out<sc_lv<32> > ex_id_forward; |
|
// Signals directly to mem stage |
sc_out<sc_lv<2> > id_ex_m_byteselect; |
sc_out<sc_logic> id_ex_m_bssign; |
|
// Signals to cp0 |
sc_out<sc_logic> ovf_excep; |
|
// Signals from cp0 |
// To prevent memory access in case of Address Error Exception or OCP action |
sc_in<sc_logic> addr_err; |
|
// sc_in<sc_lv<32> > cp0_data_from; |
|
sc_signal<sc_lv<32> > ex_alu_s; |
sc_signal<sc_lv<32> > ex_id_forward_s; |
sc_signal<sc_lv<32> > in_ex_alu_s; |
sc_signal<sc_lv<32> > in_ex_id_forward_s; |
|
// special registers |
sc_signal<sc_lv<32> > hi; |
sc_signal<sc_lv<32> > lo; |
sc_signal<sc_lv<32> > in_lo; |
sc_signal<sc_lv<32> > in_hi; |
sc_signal<sc_lv<32> > out_lo; |
sc_signal<sc_lv<32> > out_hi; |
|
|
|
sc_signal<sc_logic> carry; |
|
reg_ex *reg_ex1; |
alu *alu1; |
backwrite *backwrite1; |
multiply *multiply1; |
mux_lo *mux_lo1; |
mux_hi *mux_hi1; |
mux_rd *mux_rd1; |
|
SC_CTOR(ex_stage) |
{ |
reg_ex1 = new reg_ex("reg_ex"); |
reg_ex1->in_clk(in_clk); |
reg_ex1->reset(reset); |
reg_ex1->insthold(insthold); |
reg_ex1->datahold(datahold); |
reg_ex1->addr_err(addr_err); |
reg_ex1->ex_alu_s(ex_alu_s); |
reg_ex1->ex_m_alu(ex_m_alu); |
reg_ex1->id_ex_datastore(id_ex_datastore); |
reg_ex1->id_ex_m_datastore(id_ex_m_datastore); |
reg_ex1->id_ex_datareq(id_ex_datareq); |
reg_ex1->id_ex_m_datareq(id_ex_m_datareq); |
reg_ex1->id_ex_datarw(id_ex_datarw); |
reg_ex1->id_ex_m_datarw(id_ex_m_datarw); |
reg_ex1->id_ex_memtoreg(id_ex_memtoreg); |
reg_ex1->id_ex_m_memtoreg(id_ex_m_memtoreg); |
reg_ex1->id_ex_writeregister_out(id_ex_writeregister_out); |
reg_ex1->id_ex_m_writeregister(id_ex_m_writeregister); |
reg_ex1->id_ex_regwrite_out(id_ex_regwrite_out); |
reg_ex1->id_ex_m_regwrite(id_ex_m_regwrite); |
reg_ex1->id_ex_byteselect(id_ex_byteselect); |
reg_ex1->id_ex_m_byteselect(id_ex_m_byteselect); |
reg_ex1->id_ex_bssign(id_ex_bssign); |
reg_ex1->id_ex_m_bssign(id_ex_m_bssign); |
reg_ex1->in_lo(in_lo); |
reg_ex1->out_lo(out_lo); |
reg_ex1->in_hi(in_hi); |
reg_ex1->out_hi(out_hi); |
|
|
alu1 = new alu("alu"); |
alu1->id_ex_alu1(id_ex_alu1); |
alu1->id_ex_alu2(id_ex_alu2); |
alu1->id_ex_alu_ctrl(id_ex_alu_ctrl); |
alu1->id_ex_equal(id_ex_equal); |
alu1->id_ex_alu_sa(id_ex_alu_sa); |
alu1->ovf_excep(ovf_excep); |
alu1->carry(carry); |
alu1->ex_alu_s(in_ex_alu_s); |
alu1->ex_id_forward_s(in_ex_id_forward_s); |
|
backwrite1 = new backwrite("backwrite"); |
backwrite1->ex_id_forward_s(ex_id_forward_s); |
backwrite1->ex_id_forward(ex_id_forward); |
|
multiply1 = new multiply("multiply"); |
multiply1->id_ex_alu1(id_ex_alu1); |
multiply1->id_ex_alu2(id_ex_alu2); |
multiply1->id_ex_alu_ctrl(id_ex_alu_ctrl); |
multiply1->hi(hi); |
multiply1->lo(lo); |
|
mux_lo1 = new mux_lo("mux_lo"); |
mux_lo1->lo(lo); |
mux_lo1->rs(id_ex_alu1); |
mux_lo1->id_ex_alu_ctrl(id_ex_alu_ctrl); |
mux_lo1->out(in_lo); |
|
mux_hi1 = new mux_hi("mux_hi"); |
mux_hi1->hi(hi); |
mux_hi1->rs(id_ex_alu1); |
mux_hi1->id_ex_alu_ctrl(id_ex_alu_ctrl); |
mux_hi1->out(in_hi); |
|
mux_rd1 = new mux_rd("mux_rd"); |
mux_rd1->in_ex_id_forward_s(in_ex_id_forward_s); //dalla ALU |
mux_rd1->in_ex_alu_s(in_ex_alu_s); // dalla ALU |
mux_rd1->out_lo(out_lo); // dai registri LO |
mux_rd1->out_hi(out_hi); // dai registri HI |
mux_rd1->id_ex_alu_ctrl(id_ex_alu_ctrl); // selettore del MUX |
mux_rd1->out_ex_id_forward_s(ex_id_forward_s); // USCITE verso i registri di pipeline |
mux_rd1->out_ex_alu_s(ex_alu_s); |
} |
}; |
|
#endif |
|
/trunk/cpu/cpu/ex_stage/mux_lo.h
0,0 → 1,18
#include "systemc.h" |
#include "../../constants/constants.h" |
|
SC_MODULE(mux_lo) |
{ |
sc_in<sc_lv<32> > lo; |
sc_in<sc_lv<32> > rs; |
sc_in<sc_lv<6> > id_ex_alu_ctrl; |
sc_out<sc_lv<32> > out; |
|
void do_mux_lo(); |
|
SC_CTOR(mux_lo) |
{ |
SC_METHOD(do_mux_lo); |
sensitive << lo << rs << id_ex_alu_ctrl; |
} |
} ; |
/trunk/cpu/cpu/ex_stage/reg_ex.cpp
0,0 → 1,93
#include "reg_ex.h" |
|
void reg_ex::do_reg_ex() |
{ |
if(reset.read() == true) |
{ |
ex_m_alu.write(WORD_ZERO); |
id_ex_m_datastore.write(WORD_ZERO); |
|
id_ex_m_datareq.write(SC_LOGIC_0); |
id_ex_m_datarw.write(SC_LOGIC_0); |
|
id_ex_m_memtoreg.write(SC_LOGIC_0); |
id_ex_m_writeregister.write("00000"); |
id_ex_m_regwrite.write(SC_LOGIC_0); |
|
id_ex_m_byteselect.write("00"); |
id_ex_m_bssign.write(SC_LOGIC_0); |
|
out_lo.write(WORD_ZERO); |
out_hi.write(WORD_ZERO); |
|
// PIPELINED EXCEPTION SIGNALS |
ex_m_IBUS.write(SC_LOGIC_0); |
ex_m_inst_addrl.write(SC_LOGIC_0); |
ex_m_syscall_exception.write(SC_LOGIC_0); |
ex_m_illegal_instruction.write(SC_LOGIC_0); |
ex_m_ovf_excep.write(SC_LOGIC_0); |
ex_m_instaddr.write(0); |
|
} |
else |
if((datahold.read() == false) && (insthold.read() == false) && (enable_execute.read() == SC_LOGIC_1)) |
{ |
ex_m_alu.write(ex_alu_s.read()); |
id_ex_m_datastore.write(id_ex_datastore.read()); |
id_ex_m_datarw.write(id_ex_datarw.read()); |
id_ex_m_memtoreg.write(id_ex_memtoreg.read()); |
id_ex_m_writeregister.write(id_ex_writeregister_out.read()); |
|
id_ex_m_byteselect.write(id_ex_byteselect.read()); |
id_ex_m_bssign.write(id_ex_bssign.read()); |
|
out_lo.write(in_lo.read()); |
out_hi.write(in_hi.read()); |
|
ex_m_IBUS.write(id_ex_IBUS); |
ex_m_inst_addrl.write(id_ex_inst_addrl); |
ex_m_syscall_exception.write(id_ex_syscall_exception); |
ex_m_illegal_instruction.write(id_ex_illegal_instruction); |
ex_m_ovf_excep.write(ovf_excep); |
ex_m_instaddr.write(id_ex_instaddr); |
// Address Error Exception |
if (addr_err.read() == 1) |
{ |
#ifdef _DEBUG_ |
cout << " ***************** Address Error Exception ****************** " << endl; |
#endif |
id_ex_m_datareq.write(SC_LOGIC_0); // NB! No read/write |
id_ex_m_regwrite.write(SC_LOGIC_0); // NB! No register write |
} |
else |
{ |
id_ex_m_datareq.write(id_ex_datareq.read()); |
id_ex_m_regwrite.write(id_ex_regwrite_out.read()); |
} |
|
} |
else |
if((datahold.read() == false) && (insthold.read() == false) && (enable_execute.read() == SC_LOGIC_0)) |
{ |
ex_m_alu.write(WORD_ZERO); |
id_ex_m_datastore.write(WORD_ZERO); |
id_ex_m_datareq.write(SC_LOGIC_0); |
id_ex_m_datarw.write(SC_LOGIC_0); |
id_ex_m_memtoreg.write(SC_LOGIC_0); |
id_ex_m_writeregister.write("00000"); |
id_ex_m_regwrite.write(SC_LOGIC_0); |
id_ex_m_byteselect.write("00"); |
id_ex_m_bssign.write(SC_LOGIC_0); |
out_lo.write(WORD_ZERO); |
out_hi.write(WORD_ZERO); |
|
ex_m_IBUS.write(id_ex_IBUS); |
ex_m_inst_addrl.write(id_ex_inst_addrl); |
ex_m_syscall_exception.write(id_ex_syscall_exception); |
ex_m_illegal_instruction.write(id_ex_illegal_instruction); |
ex_m_ovf_excep.write(ovf_excep); |
ex_m_instaddr.write(id_ex_instaddr); |
} |
else; |
|
} |
/trunk/cpu/cpu/ex_stage/backwrite.cpp
0,0 → 1,6
#include "backwrite.h" |
|
void backwrite::do_backwrite() |
{ |
ex_id_forward.write(ex_id_forward_s.read()); |
} |
/trunk/cpu/cpu/ex_stage/reg_ex.h
0,0 → 1,70
#include "systemc.h" |
#include "../../constants/config.h" |
#include "../../constants/constants.h" |
|
SC_MODULE(reg_ex) |
{ |
sc_in<bool> in_clk; |
sc_in<bool> reset; |
sc_in<bool> insthold; |
sc_in<bool> datahold; |
|
sc_in<sc_logic> addr_err; |
|
sc_in<sc_lv<32> > ex_alu_s; |
sc_out<sc_lv<32> > ex_m_alu; |
|
sc_in<sc_lv<32> > id_ex_datastore; |
sc_out<sc_lv<32> > id_ex_m_datastore; |
|
sc_in<sc_logic> id_ex_datareq; |
sc_out<sc_logic> id_ex_m_datareq; |
|
sc_in<sc_logic> id_ex_datarw; |
sc_out<sc_logic> id_ex_m_datarw; |
|
sc_in<sc_logic> id_ex_memtoreg; |
sc_out<sc_logic> id_ex_m_memtoreg; |
|
sc_in<sc_lv<5> > id_ex_writeregister_out; |
sc_out<sc_lv<5> > id_ex_m_writeregister; |
|
sc_in<sc_logic> id_ex_regwrite_out; |
sc_out<sc_logic> id_ex_m_regwrite; |
|
sc_in<sc_lv<2> > id_ex_byteselect; |
sc_out<sc_lv<2> > id_ex_m_byteselect; |
|
sc_in<sc_logic> id_ex_bssign; |
sc_out<sc_logic> id_ex_m_bssign; |
|
sc_in<sc_lv<32> > in_lo; |
sc_out<sc_lv<32> > out_lo; |
|
sc_in<sc_lv<32> > in_hi; |
sc_out<sc_lv<32> > out_hi; |
|
sc_in<sc_logic> id_ex_IBUS; |
sc_in<sc_logic> id_ex_inst_addrl; |
sc_in<sc_logic> id_ex_syscall_exception; |
sc_in<sc_logic> id_ex_illegal_instruction; |
sc_in<sc_logic> ovf_excep; |
sc_out<sc_logic> ex_m_IBUS; |
sc_out<sc_logic> ex_m_inst_addrl; |
sc_out<sc_logic> ex_m_syscall_exception; |
sc_out<sc_logic> ex_m_illegal_instruction; |
sc_out<sc_logic> ex_m_ovf_excep; |
|
sc_in<sc_uint<32> > id_ex_instaddr; |
sc_out<sc_uint<32> > ex_m_instaddr; |
|
sc_in<sc_logic> enable_execute; |
|
void do_reg_ex(); |
|
SC_CTOR(reg_ex) |
{ |
SC_METHOD(do_reg_ex); |
sensitive_pos << in_clk; |
} |
}; |
/trunk/cpu/cpu/ex_stage/multiply.cpp
0,0 → 1,32
#include "multiply.h" |
|
void multiply::do_multiply() |
{ |
|
sc_lv<32> rs = id_ex_alu1.read(); |
sc_lv<32> rt = id_ex_alu2.read(); |
sc_lv<6> func = id_ex_alu_ctrl.read(); |
|
if(func == FUNC_MULT) |
{ |
sc_lv<64> l64s, l64t, l64r; |
sc_int<64> i64s, i64t, i64r; |
i64s = l64s = (WORD_ZERO,rs); |
i64t = l64t = (WORD_ZERO,rt); |
l64r = i64r = i64s * i64t; |
hi.write(l64r.range(63,32)); |
lo.write(l64r.range(31,0)); |
} |
else |
if(func == FUNC_MULTU) |
{ |
sc_lv<64> l64s, l64t, l64r; |
sc_uint<64> i64s, i64t, i64r; |
i64s = l64s = (WORD_ZERO,rs); |
i64t = l64t = (WORD_ZERO,rt); |
l64r = i64r = i64s * i64t; |
hi.write(l64r.range(63,32)); |
lo.write(l64r.range(31,0)); |
} |
else; |
} |
/trunk/cpu/cpu/ex_stage/backwrite.h
0,0 → 1,16
#include "systemc.h" |
// modulo completamente inutile!!! |
|
SC_MODULE(backwrite) |
{ |
sc_in<sc_lv<32> > ex_id_forward_s; |
sc_out<sc_lv<32> > ex_id_forward; |
|
void do_backwrite(); |
|
SC_CTOR(backwrite) |
{ |
SC_METHOD(do_backwrite); |
sensitive << ex_id_forward_s; |
} |
}; |
/trunk/cpu/cpu/ex_stage/alu.cpp
0,0 → 1,176
// |
// HO MODIFICATO la funzione SLLV e SRLV |
// ed ho aggiunto i segnali temp_rs e shift_rs |
// |
|
|
#include "alu.h" |
|
void alu::do_alu() |
{ |
sc_lv<6> func = id_ex_alu_ctrl.read(); |
sc_lv<32> rs = id_ex_alu1.read(); |
sc_lv<32> rt = id_ex_alu2.read(); |
sc_lv<32> rd = WORD_ZERO; |
sc_int<32> irs = rs; |
sc_int<32> irt = rt; |
sc_uint<32> uirs = rs; |
sc_uint<32> uirt = rt; |
sc_logic equal = id_ex_equal.read(); |
sc_logic ovf_excep_l; |
|
sc_logic sign_bit_for_sra; |
|
// shift amount |
sc_lv<5> sa = id_ex_alu_sa.read(); |
sc_uint<5> uisa = sa; |
|
// shift from the register rs |
sc_lv<5> temp_rs = rs.range(4,0); |
sc_uint<5> shift_rs = temp_rs; |
|
sc_logic n0, n1; |
n0 = 0; |
n1 = 1; |
|
// Defaults... |
ovf_excep.write(n0); // ovf_excep_l = 0; |
carry.write(n0); |
|
if(func == FUNC_SLL) |
{ |
rd = rt << uisa; |
} |
else if(func == FUNC_SRL) |
{ |
rd = rt >> uisa; |
} |
else if(func == FUNC_SRA) |
{ |
sign_bit_for_sra = rt[31]; |
rd = rt >> uisa; |
} |
else if(func == FUNC_SLLV) |
{ |
rd = rt << shift_rs; |
} |
else if(func == FUNC_SRLV) |
{ |
rd = rt >> shift_rs; |
} |
else if(func == FUNC_SRAV) |
{ |
} |
/*else if(func == FUNC_MFHI) |
{ |
rd = hi; |
} |
|
else if(func == FUNC_MFLO) |
{ |
rd = lo; |
}*/ |
|
else if(func == FUNC_ADD) |
{ |
sc_lv<33> temp; |
sc_lv<32> t = rt, s = rs; |
sc_lv<33> tt, ss; |
sc_int<33> ttt, sss; |
// Sign extend t |
if(t[31] == '1') |
ttt = tt = ("1",t); |
else |
ttt = tt = ("0",t); |
// Sign extend s |
if(s[31] == '1') |
sss = ss = ("1",s); |
else |
sss = ss = ("0",s); |
temp = ttt + sss; |
|
// Set exception bit |
if (temp[32] != temp[31]) |
ovf_excep.write(SC_LOGIC_1); |
else |
ovf_excep.write(SC_LOGIC_0); |
rd = temp.range(31,0); |
} |
else if(func == FUNC_ADDU) |
{ |
rd = uirs + uirt; |
} |
else if(func == FUNC_SUB) |
{ |
sc_lv<33> temp; |
sc_lv<32> t = rt, s = rs; |
sc_lv<33> tt, ss; |
sc_int<33> ttt, sss; |
// Sign extend t |
if(t[31] == '1') |
ttt = tt = ("1",t); |
else |
ttt = tt = ("0",t); |
// Sign extend s |
if(s[31] == '1') |
sss = ss = ("1",s); |
else |
sss = ss = ("0",s); |
temp = ttt + sss; |
|
// Set exception bit |
if (temp[32] != temp[31]) |
ovf_excep.write(SC_LOGIC_1); |
else |
ovf_excep.write(SC_LOGIC_0); |
rd = temp.range(31,0); |
} |
else if(func == FUNC_SUBU) |
{ |
rd = irs - irt; |
} |
else if(func == FUNC_AND) |
{ |
rd = rs & rt; |
} |
else if(func == FUNC_OR) |
{ |
rd = rs | rt; |
} |
else if(func == FUNC_XOR) |
{ |
rd = rs ^ rt; |
} |
else if(func == FUNC_NOR) |
{ |
rd = ~(rs|rt); |
} |
else if(func == FUNC_SLT) |
if(irs < irt) |
{ |
rd = WORD_CON_ONE; |
} |
else |
{ |
rd = WORD_ZERO; |
} |
else if(func == FUNC_SLTU) |
if(uirs < uirt) |
{ |
rd = WORD_CON_ONE; |
} |
else |
{ |
rd = WORD_ZERO; |
} |
else |
{ |
rd = WORD_ZERO; |
} |
|
ex_alu_s.write(rd); |
ex_id_forward_s.write(rd); |
|
|
|
} |
/trunk/cpu/cpu/ex_stage/multiply.h
0,0 → 1,23
#include "systemc.h" |
#include "../../constants/constants.h" |
|
SC_MODULE(multiply) |
{ |
sc_in<sc_lv<32> > id_ex_alu1; |
sc_in<sc_lv<32> > id_ex_alu2; |
|
sc_in<sc_lv<6> > id_ex_alu_ctrl; |
|
sc_out<sc_lv<32> > hi; |
sc_out<sc_lv<32> > lo; |
|
|
void do_multiply(); |
|
SC_CTOR(multiply) |
{ |
SC_METHOD(do_multiply); |
sensitive << id_ex_alu1 << id_ex_alu2; |
sensitive << id_ex_alu_ctrl; |
}; |
}; |
/trunk/cpu/cpu/ex_stage/alu.h
0,0 → 1,26
#include "systemc.h" |
#include "../../constants/config.h" |
#include "../../constants/constants.h" |
|
SC_MODULE(alu) |
{ |
sc_in<sc_lv<32> > id_ex_alu1; |
sc_in<sc_lv<32> > id_ex_alu2; |
sc_in<sc_lv<6> > id_ex_alu_ctrl; |
sc_in<sc_logic> id_ex_equal; |
sc_in<sc_lv<5> > id_ex_alu_sa; |
sc_out<sc_logic> ovf_excep; |
sc_out<sc_logic> carry; |
sc_out<sc_lv<32> > ex_alu_s; |
sc_out<sc_lv<32> > ex_id_forward_s; |
|
void do_alu(); |
|
SC_CTOR(alu) |
{ |
SC_METHOD(do_alu); |
sensitive << id_ex_equal << id_ex_alu_ctrl; |
sensitive << id_ex_alu1 << id_ex_alu2; |
sensitive << id_ex_alu_sa; |
} |
}; |
/trunk/cpu/cpu/ex_stage/execute_ctrl.cpp
0,0 → 1,14
#include "execute_ctrl.h" |
|
void execute_ctrl::do_execute_ctrl() |
{ |
if((id_ex_IBUS.read() == SC_LOGIC_1) || |
(id_ex_inst_addrl.read() == SC_LOGIC_1) || |
(id_ex_syscall_exception.read() == SC_LOGIC_1) || |
(id_ex_illegal_instruction.read() == SC_LOGIC_1) || |
(ovf_excep.read() == SC_LOGIC_1)) |
ex_exception.write(SC_LOGIC_1); |
else |
ex_exception.write(SC_LOGIC_0); |
|
}; |
/trunk/cpu/cpu/ex_stage/mux_hi.cpp
0,0 → 1,9
#include "mux_hi.h" |
|
void mux_hi::do_mux_hi() |
{ |
if (id_ex_alu_ctrl.read() == FUNC_MTHI) |
out.write(rs.read()); |
else |
out.write(hi.read()); |
} |
/trunk/cpu/cpu/ex_stage/execute_ctrl.h
0,0 → 1,22
#include "systemc.h" |
#include "../../constants/constants.h" |
|
SC_MODULE(execute_ctrl) |
{ |
sc_in<sc_logic> id_ex_IBUS; |
sc_in<sc_logic> id_ex_inst_addrl; |
sc_in<sc_logic> id_ex_illegal_instruction; |
sc_in<sc_logic> id_ex_syscall_exception; |
sc_in<sc_logic> ovf_excep; |
sc_out<sc_logic> ex_exception; |
|
void do_execute_ctrl(); |
|
SC_CTOR(execute_ctrl) |
{ |
SC_METHOD(do_execute_ctrl); |
sensitive << id_ex_IBUS << id_ex_inst_addrl; |
sensitive << id_ex_illegal_instruction << id_ex_syscall_exception; |
sensitive << ovf_excep; |
} |
}; |
/trunk/cpu/cpu/id_stage.cpp
0,0 → 1,22
#include "id_stage.h" |
/trunk/cpu/cpu/mem_stage/reg_mem.h
0,0 → 1,56
#include "systemc.h" |
#include "../../constants/constants.h" |
|
SC_MODULE(reg_mem) |
{ |
sc_in<bool> in_clk; |
sc_in<bool> reset; |
|
sc_in<bool> insthold; |
sc_in<bool> datahold; |
|
sc_out<sc_lv<32> > wb_id_forward; |
sc_out<sc_lv<5> > id_ex_m_wb_writeregister; |
sc_out<sc_logic> id_ex_m_wb_regwrite; |
sc_in<sc_lv<32> > id_store; |
sc_in<sc_lv<5> > id_ex_m_writeregister; |
sc_in<sc_logic> id_ex_m_regwrite; |
|
// EXCEPTION SIGNALS |
sc_in<sc_logic> ex_m_IBUS; |
sc_in<sc_logic> ex_m_inst_addrl; |
sc_in<sc_logic> ex_m_syscall_exception; |
sc_in<sc_logic> ex_m_illegal_instruction; |
sc_in<sc_logic> ex_m_ovf_excep; |
sc_in<sc_logic> DBUS; |
sc_in<sc_logic> data_addrl; |
sc_in<sc_logic> data_addrs; |
|
// exception status vector -> to CPO-Cause |
sc_out<sc_logic> m_wb_IBUS; |
sc_out<sc_logic> m_wb_inst_addrl; |
sc_out<sc_logic> m_wb_syscall_exception; |
sc_out<sc_logic> m_wb_illegal_instruction; |
sc_out<sc_logic> m_wb_ovf_excep; |
sc_out<sc_logic> m_wb_DBUS; |
sc_out<sc_logic> m_wb_data_addrl; |
sc_out<sc_logic> m_wb_data_addrs; |
|
sc_out<sc_uint<32> > m_wb_instaddr; //se un bit dell ESV �pari ad 1 allora questo �l'indirizzo della vittima |
sc_in<sc_uint<32> > ex_m_instaddr; |
sc_in<sc_uint<32> > ex_m_dataaddr; |
sc_out<sc_uint<32> > m_wb_dataaddr; |
|
sc_in<bool> interrupt_signal; |
sc_out<bool> m_wb_interrupt_signal; |
|
sc_in<sc_logic> enable_memstage; |
|
void do_reg_mem(); |
|
SC_CTOR(reg_mem) |
{ |
SC_METHOD(do_reg_mem); |
sensitive_pos << in_clk; |
} |
}; |
/trunk/cpu/cpu/mem_stage/flag_interr.h
0,0 → 1,16
#include "systemc.h" |
|
SC_MODULE(flag_interr) |
{ |
sc_in<bool> in_clk, reset; |
sc_in<bool> interrupt_in; |
sc_out<bool> interrupt_out; |
|
void do_flag_interr(); |
|
SC_CTOR(flag_interr) |
{ |
SC_METHOD(do_flag_interr); |
sensitive << in_clk << interrupt_in; |
} |
}; |
/trunk/cpu/cpu/mem_stage/select_mem.h
0,0 → 1,29
//! Selects inputs to the data memory |
|
#include "systemc.h" |
#include "../../constants/constants.h" |
|
SC_MODULE(select_mem) |
{ |
sc_in<sc_logic> id_ex_m_datareq; |
sc_in<sc_logic> id_ex_m_datarw; |
sc_in<sc_lv<2> > id_ex_m_byteselect; |
sc_in<sc_lv<32> > id_ex_m_datastore; |
sc_out<sc_lv<32> > datawrite; |
sc_in<sc_lv<32> > ex_m_alu; |
sc_out<sc_uint<32> > dataaddr; |
sc_out<sc_logic> datareq; |
sc_out<sc_logic> datarw; |
sc_out<sc_lv<2> > databs; |
sc_in<sc_logic> enable_memstage; |
|
void do_select_mem(); |
|
SC_CTOR(select_mem) |
{ |
SC_METHOD(do_select_mem); |
sensitive << id_ex_m_datareq << id_ex_m_datarw << id_ex_m_datastore; |
sensitive << ex_m_alu << id_ex_m_byteselect << enable_memstage; |
//sensitive << datawrite; |
} |
}; |
/trunk/cpu/cpu/mem_stage/mux_interrupt.cpp
0,0 → 1,12
#include "mux_interrupt.h" |
|
void mux_interrupt::do_mux_interrupt() |
{ |
if(SEL.read() == SC_LOGIC_1) |
OUT.write(IN_A.read()); |
else |
if(SEL.read() == SC_LOGIC_0) |
OUT.write(IN_B.read()); |
else |
OUT.write(IN_A.read()); |
} |
/trunk/cpu/cpu/mem_stage/memstage_ctrl.cpp
0,0 → 1,18
#include "memstage_ctrl.h" |
|
void memstage_ctrl::do_memstage_ctrl() |
{ |
if((ex_m_IBUS.read() == SC_LOGIC_1) || |
(ex_m_inst_addrl.read() == SC_LOGIC_1) || |
(ex_m_syscall_exception.read() == SC_LOGIC_1) || |
(ex_m_illegal_instruction.read() == SC_LOGIC_1) || |
(ex_m_ovf_excep.read() == SC_LOGIC_1) || |
(DBUS.read() == SC_LOGIC_1) || |
(data_addrl.read() == SC_LOGIC_1) || |
(data_addrs.read() == SC_LOGIC_1) || |
(interrupt_signal.read() == SC_LOGIC_1)) |
mem_exception.write(SC_LOGIC_1); |
else |
mem_exception.write(SC_LOGIC_0); |
|
}; |
/trunk/cpu/cpu/mem_stage/multiplexer_mem.cpp
0,0 → 1,38
//! Selects whether to bypass data memory or not |
/*! |
When reading from memory, the data signal from data memory is chosen |
sensitive << id_ex_m_memtoreg << ex_m_alu << dataread; |
*/ |
|
#include "multiplexer_mem.h" |
|
void multiplexer_mem::do_multiplexer_mem() |
{ |
sc_lv<32> store; |
sc_lv<2> byteselect = id_ex_m_byteselect.read(); |
sc_logic bssign = id_ex_m_bssign.read(); |
if (id_ex_m_memtoreg.read() == SC_LOGIC_0) |
{ |
store = ex_m_alu.read(); |
} |
else |
{ |
store = dataread.read(); |
if (byteselect == "01") |
{ |
store = store & "00000000000000000000000011111111"; |
if ((store.range(7,7) == "1") && (bssign == SC_LOGIC_1)) |
store = store | "11111111111111111111111100000000"; |
} |
else if (byteselect == "10") |
{ |
store = store & "00000000000000001111111111111111"; |
if ((store.range(15,15) == "1") && (bssign == SC_LOGIC_1)) |
store = store | "11111111111111110000000000000000"; |
} |
|
} |
|
id_store.write(store); |
m_id_forward.write(store); |
} |
/trunk/cpu/cpu/mem_stage/mux_interrupt.h
0,0 → 1,21
#include "systemc.h" |
#include "../../constants/constants.h" |
|
SC_MODULE(mux_interrupt) |
{ |
sc_in<bool> IN_A; |
sc_in<bool> IN_B; |
|
sc_in<sc_logic> SEL; |
|
sc_out<bool> OUT; |
|
|
void do_mux_interrupt(); |
|
SC_CTOR(mux_interrupt) |
{ |
SC_METHOD(do_mux_interrupt); |
sensitive << IN_A << IN_B << SEL; |
} |
}; |
/trunk/cpu/cpu/mem_stage/memstage_ctrl.h
0,0 → 1,27
#include "systemc.h" |
#include "../../constants/constants.h" |
|
SC_MODULE(memstage_ctrl) |
{ |
sc_in<sc_logic> ex_m_IBUS; |
sc_in<sc_logic> ex_m_inst_addrl; |
sc_in<sc_logic> ex_m_illegal_instruction; |
sc_in<sc_logic> ex_m_syscall_exception; |
sc_in<sc_logic> ex_m_ovf_excep; |
sc_in<sc_logic> DBUS; |
sc_in<sc_logic> data_addrl; |
sc_in<sc_logic> data_addrs; |
sc_in<bool> interrupt_signal; |
sc_out<sc_logic> mem_exception; |
|
|
void do_memstage_ctrl(); |
|
SC_CTOR(memstage_ctrl) |
{ |
SC_METHOD(do_memstage_ctrl); |
sensitive << ex_m_IBUS << ex_m_inst_addrl; |
sensitive << ex_m_illegal_instruction << ex_m_syscall_exception; |
sensitive << ex_m_ovf_excep << DBUS << data_addrl << data_addrs << interrupt_signal; |
} |
}; |
/trunk/cpu/cpu/mem_stage/reg_mem.cpp
0,0 → 1,63
#include "reg_mem.h" |
|
void reg_mem::do_reg_mem() |
{ |
if(reset.read() == true) |
{ |
wb_id_forward.write(WORD_ZERO); |
id_ex_m_wb_regwrite.write(SC_LOGIC_0); |
id_ex_m_wb_writeregister.write("00000"); |
|
m_wb_IBUS.write(SC_LOGIC_0); |
m_wb_inst_addrl.write(SC_LOGIC_0); |
m_wb_syscall_exception.write(SC_LOGIC_0); |
m_wb_illegal_instruction.write(SC_LOGIC_0); |
m_wb_ovf_excep.write(SC_LOGIC_0); |
m_wb_DBUS.write(SC_LOGIC_0); |
m_wb_data_addrl.write(SC_LOGIC_0); |
m_wb_data_addrs.write(SC_LOGIC_0); |
m_wb_instaddr.write(0); |
m_wb_dataaddr.write(0); |
m_wb_interrupt_signal.write(false); |
} |
else |
{ |
if((datahold.read() == false) && (insthold.read() == false) && (enable_memstage.read() == SC_LOGIC_1)) |
{ |
wb_id_forward.write(id_store.read()); |
id_ex_m_wb_regwrite.write(id_ex_m_regwrite.read()); |
id_ex_m_wb_writeregister.write(id_ex_m_writeregister.read()); |
|
m_wb_IBUS.write(ex_m_IBUS.read()); |
m_wb_inst_addrl.write(ex_m_inst_addrl.read()); |
m_wb_syscall_exception.write(ex_m_syscall_exception.read()); |
m_wb_illegal_instruction.write(ex_m_illegal_instruction.read()); |
m_wb_ovf_excep.write(ex_m_ovf_excep.read()); |
m_wb_DBUS.write(DBUS.read()); |
m_wb_data_addrl.write(data_addrl.read()); |
m_wb_data_addrs.write(data_addrs.read()); |
m_wb_instaddr.write(ex_m_instaddr.read()); |
m_wb_dataaddr.write(ex_m_dataaddr.read()); |
m_wb_interrupt_signal.write(interrupt_signal.read()); |
} |
else |
if((datahold.read() == false) && (insthold.read() == false) && (enable_memstage.read() == SC_LOGIC_0)) |
{ |
wb_id_forward.write(WORD_ZERO); |
id_ex_m_wb_regwrite.write(SC_LOGIC_0); |
id_ex_m_wb_writeregister.write("00000"); |
|
m_wb_IBUS.write(ex_m_IBUS); |
m_wb_inst_addrl.write(ex_m_inst_addrl.read()); |
m_wb_syscall_exception.write(ex_m_syscall_exception.read()); |
m_wb_illegal_instruction.write(ex_m_illegal_instruction.read()); |
m_wb_ovf_excep.write(ex_m_ovf_excep.read()); |
m_wb_DBUS.write(DBUS.read()); |
m_wb_data_addrl.write(data_addrl.read()); |
m_wb_data_addrs.write(data_addrs.read()); |
m_wb_instaddr.write(ex_m_instaddr.read()); |
m_wb_dataaddr.write(ex_m_dataaddr.read()); |
m_wb_interrupt_signal.write(interrupt_signal.read()); |
} |
} |
} |
/trunk/cpu/cpu/mem_stage/flag_interr.cpp
0,0 → 1,15
#include "flag_interr.h" |
|
void flag_interr::do_flag_interr() |
{ |
if(reset.read() == true) |
interrupt_out.write(false); |
else |
if(interrupt_in.read() == true) |
interrupt_out.write(true); |
else |
if((in_clk.read() == true) && (interrupt_in.read() == false)) |
interrupt_out.write(false); |
else; |
|
} |
/trunk/cpu/cpu/mem_stage/multiplexer_mem.h
0,0 → 1,28
//! Selects whether to bypass data memory or not |
/*! |
When reading from memory, the data signal from data memory is chosen |
sensitive << id_ex_m_memtoreg << ex_m_alu << dataread; |
*/ |
|
#include "systemc.h" |
#include "../../constants/constants.h" |
|
SC_MODULE(multiplexer_mem) |
{ |
sc_in<sc_lv<2> > id_ex_m_byteselect; |
sc_in<sc_logic> id_ex_m_bssign; |
sc_in<sc_logic> id_ex_m_memtoreg; |
sc_in<sc_lv<32> > ex_m_alu; |
sc_in<sc_lv<32> > dataread; |
sc_out<sc_lv<32> > id_store; |
sc_out<sc_lv<32> > m_id_forward; |
|
void do_multiplexer_mem(); |
|
SC_CTOR(multiplexer_mem) |
{ |
SC_METHOD(do_multiplexer_mem); |
sensitive << id_ex_m_memtoreg << ex_m_alu << dataread; |
sensitive << id_ex_m_byteselect << id_ex_m_bssign; |
} |
}; |
/trunk/cpu/cpu/mem_stage/select_mem.cpp
0,0 → 1,45
/*! |
Sets the address and request signals to the data memory. |
For load instructions, data is set to ZZZ... |
sensitive << id_ex_m_datareq << id_ex_m_datarw << id_ex_m_datastore << ex_m_alu << datawrite; |
*/ |
|
#include "select_mem.h" |
#include "../../constants/constants.h" |
void select_mem::do_select_mem() |
{ |
sc_logic dreq = id_ex_m_datareq.read(); |
sc_logic drw = id_ex_m_datarw.read(); |
sc_lv<32> d; |
sc_uint<32> daddr; |
sc_lv<2> byteselect = id_ex_m_byteselect.read(); |
|
|
if(enable_memstage.read() == SC_LOGIC_1) |
{ |
if ((dreq == 1) && (drw == 1)) |
{ |
d = id_ex_m_datastore.read(); |
datawrite.write(d); |
} |
else |
{ |
d = WORD_ZERO; |
datawrite.write(d); |
} |
daddr = ex_m_alu.read(); |
dataaddr.write(daddr); |
datareq.write(dreq); |
datarw.write(drw); |
databs.write(byteselect); |
} |
else |
{ |
datawrite.write(WORD_ZERO); |
dataaddr.write(0); |
datareq.write(SC_LOGIC_0); |
datarw.write(SC_LOGIC_0); |
databs.write(byteselect); |
|
} |
} |
/trunk/cpu/cpu/if_stage.cpp
0,0 → 1,45
#include "if_stage.h" |
/trunk/cpu/cpu/sc_cpu.h
0,0 → 1,218
// |
// $Id: sc_cpu.h,v 1.1 2006-01-21 03:37:32 igorloi Exp $ |
// |
|
#ifndef _SC_CPU_H |
#define _SC_CPU_H |
|
#include <systemc.h> |
#include "../constants/config.h" |
#include "../constants/constants.h" |
#include "pc_stage.h" |
#include "if_stage.h" |
#include "id_stage.h" |
#include "ex_stage.h" |
#include "mem_stage.h" |
#include "enable_stage.h" |
#include "writeback_ctrl.h" |
#include "mux_instaddr.h" |
|
SC_MODULE(sc_cpu) |
{ |
// to CP0_STAGE |
sc_in<sc_lv<32> > new_pc; |
sc_in<sc_logic> load_epc; |
sc_out<sc_lv<32> > pc_in; |
sc_out<sc_lv<32> > pc_out; |
sc_out<sc_logic> id_branch; |
sc_out<sc_logic> id_ctrl; |
sc_out<sc_logic> id_ex_datarw; |
sc_out<sc_logic> id_ex_datareq; |
sc_in<sc_logic> addr_err; |
sc_in<bool> insthold; |
sc_out<sc_lv<4> > cp0_inst; |
sc_out<sc_lv<32> > reg_rs; |
sc_in<sc_lv<32> > reg_out; |
sc_out<sc_uint<5> > reg_no; |
sc_out<sc_logic> reg_rw; |
sc_out<sc_lv<32> > ex_id_forward; |
|
|
// EXCEPTION SIGNAL FROM DATAMEM AND INSTMEM |
//***************************************************************************************************** |
sc_in<sc_logic> inst_addrl; // disaligned address in instmem during fetch stage |
sc_in<sc_logic> IBUS; //page fault in instmem |
sc_in<sc_logic> data_addrl; //disaligned address in datamem during load instruction |
sc_in<sc_logic> data_addrs; //disaligned address in datamem during store instruction |
sc_in<sc_logic> DBUS; //page fault in instmem |
//***************************************************************************************************** |
|
// EXCEPTION SIGNALS TO ENABLE/DISABLE PIPELINED STAGE |
//***************************************************************************************************** |
sc_signal<sc_logic> enable_pc; |
sc_signal<sc_logic> enable_fetch; |
sc_signal<sc_logic> enable_decode; |
sc_signal<sc_logic> enable_execute; |
sc_signal<sc_logic> enable_memstage; |
sc_signal<sc_logic> if_exception; |
sc_signal<sc_logic> id_exception; |
sc_signal<sc_logic> ex_exception; |
sc_signal<sc_logic> mem_exception; |
sc_signal<sc_logic> wb_exception; |
sc_signal<sc_logic> interrupt_exception; |
//***************************************************************************************************** |
|
// INTERRUPT SIGNALS |
//********************************************** |
sc_in<bool> interrupt_signal; |
sc_out<bool> m_wb_interrupt_signal; |
sc_in<sc_logic> enable_interrupt; |
sc_in<sc_logic> enable_kernel_mode; |
//********************************************** |
|
|
// PIPELINED EXCEPTION SIGNALS |
//***************************************************************************************************** |
sc_signal<sc_logic> if_id_inst_addrl; // from if_stage to id_stage |
sc_signal<sc_logic> if_id_IBUS; // from if_stage to id_stage |
sc_signal<sc_logic> id_ex_inst_addrl; // from id_stage to ex_stage |
sc_signal<sc_logic> id_ex_IBUS; // from id_stage to ex_stage |
sc_signal<sc_logic> id_ex_syscall_exception; // from id_stage to ex_stage |
sc_signal<sc_logic> id_ex_illegal_instruction; // from id_stage to ex_stage |
sc_signal<sc_logic> ex_m_ovf_excep; // from ex_stage to mem_stage |
sc_signal<sc_logic> ex_m_inst_addrl; // from ex_stage to mem_stage |
sc_signal<sc_logic> ex_m_IBUS; // from ex_stage to mem_stage |
sc_signal<sc_logic> ex_m_syscall_exception; // from ex_stage to mem_stage |
sc_signal<sc_logic> ex_m_illegal_instruction; // from ex_stage to mem_stage |
sc_out<sc_logic> m_wb_DBUS; // from mem_stage to cp0_cause |
sc_out<sc_logic> m_wb_data_addrl; // from mem_stage to cp0_cause |
sc_out<sc_logic> m_wb_data_addrs; // from mem_stage to cp0_cause |
sc_out<sc_logic> m_wb_ovf_excep; // from mem_stage to cp0_cause |
sc_out<sc_logic> m_wb_syscall_exception; // from mem_stage to cp0_cause |
sc_out<sc_logic> m_wb_illegal_instruction; // from mem_stage to cp0_cause |
sc_out<sc_logic> m_wb_IBUS; // from mem_stage to cp0_cause |
sc_out<sc_logic> m_wb_inst_addrl; // from mem_stage to cp0_cause |
|
sc_signal<sc_uint<32> > if_id_instaddr; // from if_stage to id_stage (victim address instruction) |
sc_signal<sc_uint<32> > id_ex_instaddr; // from id_stage to ex_stage (victim address instruction) |
sc_signal<sc_uint<32> > ex_m_instaddr; // from ex_stage to mem_stage address for INTERRUPT EPC |
sc_signal<sc_uint<32> > m_wb_instaddr; // from mem_stage to mux_instaddr (victim address instruction) |
sc_out<sc_uint<32> > m_wb_instaddr_s; // from mux_instaddr to EPC |
sc_out<sc_uint<32> > m_wb_dataaddr; // from mem_stage to cpo_cause (victim address instruction) |
//***************************************************************************************************** |
|
|
|
// |
// Very basic signals for the CPU! |
// |
//! Main clock signal |
sc_in<bool> in_clk; |
//! Main reset signal |
sc_in<bool> reset; |
|
// |
// Instruction memory interface |
// |
//! Instruction memory input data |
// sc_inout_rv<32> instdata; |
sc_in<sc_lv<32> > instdataread; |
sc_out<sc_lv<32> > instdatawrite; |
//! Instruction memory address |
sc_out<sc_uint<32> > instaddr; |
//! Instruction memory request |
sc_out<sc_logic> instreq; |
//! Instruction memory read/write signal. 1 for write. 0 for read. |
sc_out<sc_logic> instrw; |
//! Hold signal from cp0 (Was: instruction memory) |
|
|
//sc_in<bool> x_insthold; //in sc_risc! |
|
// |
// Data memory interface |
// |
//! Data memory in/out data |
// sc_inout_rv<32> data; |
sc_in<sc_lv<32> > dataread; |
sc_out<sc_lv<32> > datawrite; |
//! Data memory address |
sc_out<sc_uint<32> > dataaddr; |
//! Data memory request |
sc_out<sc_logic> datareq; |
//! Data memory read/write signal. 1 for write. 0 for read. |
sc_out<sc_logic> datarw; |
//! Byte select signal. Select bytes to be written. 01 for byte, 10 for halfword |
sc_out<sc_lv<2> > databs; |
//! Hold signal from data memory |
sc_in<bool> datahold; |
|
|
// Misc. signals |
sc_signal<sc_lv<32> > id_new_pc; |
sc_signal<sc_lv<32> > id_jmp_tar; |
sc_signal<sc_lv<32> > if_id_inst; |
sc_signal<sc_lv<32> > if_id_next_pc; |
|
// signal from id_stage to ex_stage |
sc_signal<sc_lv<32> > id_ex_alu1; |
sc_signal<sc_lv<32> > id_ex_alu2; |
sc_signal<sc_lv<32> > id_ex_datastore; |
sc_signal<sc_lv<6> > id_ex_alu_ctrl; |
sc_signal<sc_logic> id_ex_equal; |
sc_signal<sc_lv<2> > id_ex_byteselect; |
sc_signal<sc_logic> id_ex_bssign; |
sc_signal<sc_lv<5> > id_ex_alu_sa; |
|
// signal to mem_stage through ex_stage |
sc_signal<sc_logic> id_ex_memtoreg; |
sc_signal<sc_lv<2> > id_ex_m_byteselect; |
sc_signal<sc_logic> id_ex_m_bssign; |
|
// signal to mem_stage |
sc_signal<sc_logic> id_ex_m_datareq; |
sc_signal<sc_logic> id_ex_m_datarw; |
sc_signal<sc_lv<32> > id_ex_m_datastore; |
sc_signal<sc_lv<32> > ex_m_alu; |
sc_signal<sc_logic> id_ex_m_memtoreg; |
sc_signal<sc_logic> m_ocp_cmd; |
|
// signal to control save in register |
sc_signal<sc_lv<5> > id_ex_writeregister_out; |
sc_signal<sc_logic> id_ex_regwrite_out; |
|
// forwarding control signal |
sc_signal<sc_lv<5> > id_ex_m_writeregister; |
sc_signal<sc_lv<5> > id_ex_m_wb_writeregister; |
sc_signal<sc_logic> id_ex_m_regwrite; |
sc_signal<sc_logic> id_ex_m_wb_regwrite; |
//sc_signal<sc_lv<32> > ex_id_forward; |
sc_signal<sc_lv<32> > m_id_forward; |
sc_signal<sc_lv<32> > wb_id_forward; |
|
|
// signals between ID stage and cp0 |
|
sc_signal<sc_logic> inst_break; |
sc_signal<sc_logic> inst_syscall; |
|
|
pc_stage *pc; |
if_stage *if_s; |
id_stage *id; |
ex_stage *ex; |
mem_stage *mem; |
enable_stage *enable_stage1; |
writeback_ctrl *writeback_ctrl1; |
mux_instaddr *mux_instaddr1; |
|
void clocktik() |
{ |
}; |
|
SC_HAS_PROCESS(sc_cpu); |
sc_cpu(const sc_module_name& name_); |
|
}; |
|
#endif |
/trunk/cpu/cpu/cp0.cpp
0,0 → 1,4
// |
// $Id: cp0.cpp,v 1.1 2006-01-21 03:37:32 igorloi Exp $ |
// |
#include "cp0.h" |
/trunk/cpu/cpu/id_stage.h
0,0 → 1,351
#include "systemc.h" |
#include "./id_stage/control.h" |
#include "./id_stage/mux_writeregister.h" |
#include "./id_stage/sign_extend.h" |
#include "./id_stage/add_new_pc.h" |
#include "./id_stage/mux_jump.h" |
#include "./id_stage/mux_forward_select.h" |
#include "./id_stage/mux_alu1.h" |
#include "./id_stage/mux_alu2.h" |
#include "./id_stage/comparator.h" |
#include "./id_stage/forwarding_control.h" |
#include "./id_stage/reg_id.h" |
#include "./id_stage/decode_ctrl.h" |
|
#include "./id_stage/regfile_high.h" |
|
#include "../constants/config.h" |
#include "../constants/constants.h" |
|
SC_MODULE(id_stage) |
{ |
sc_in<bool> in_clk; |
sc_in<bool> reset; |
|
sc_in<bool> insthold; |
sc_in<bool> datahold; |
|
sc_in<sc_lv<32> > if_id_next_pc; |
sc_in<sc_lv<32> > if_id_inst; |
|
// signal to if_stage NOT clk |
sc_out<sc_lv<32> > id_jmp_tar; |
sc_out<sc_lv<32> > id_new_pc; |
sc_out<sc_logic> id_branch; |
sc_out<sc_logic> id_ctrl; |
|
// signal to ex_stage |
sc_out<sc_lv<32> > id_ex_alu1; |
sc_out<sc_lv<32> > id_ex_alu2; |
sc_out<sc_lv<32> > id_ex_datastore; |
sc_out<sc_lv<6> > id_ex_alu_ctrl; |
sc_out<sc_logic> id_ex_equal; |
sc_out<sc_lv<2> > id_ex_byteselect; |
sc_out<sc_logic> id_ex_bssign; |
sc_out<sc_lv<5> > id_ex_alu_sa; |
|
// signal to mem_stage throught ex_stage |
sc_out<sc_logic> id_ex_datareq; |
sc_out<sc_logic> id_ex_datarw; |
sc_out<sc_logic> id_ex_memtoreg; |
|
sc_signal<sc_lv<2> > id_byteselect; |
sc_signal<sc_logic> id_bssign; |
sc_signal<sc_lv<5> > id_alu_sa; |
|
// signal to control save in register |
sc_out<sc_lv<5> > id_ex_writeregister_out; |
sc_out<sc_logic> id_ex_regwrite_out; |
|
// forwarding control signal |
sc_signal<sc_lv<5> > id_ex_writeregister; |
sc_in<sc_lv<5> > id_ex_m_writeregister; |
sc_in<sc_lv<5> > id_ex_m_wb_writeregister; |
sc_signal<sc_logic> id_ex_regwrite; |
sc_in<sc_logic> id_ex_m_regwrite; |
sc_in<sc_logic> id_ex_m_wb_regwrite; |
sc_in<sc_lv<32> > ex_id_forward; |
sc_in<sc_lv<32> > m_id_forward; |
sc_in<sc_lv<32> > wb_id_forward; |
|
// signals to cp0 |
sc_out<sc_lv<4> > cp0_inst; // Current instruction |
sc_out<sc_uint<5> > cp0_reg_no; // Register to read/write in cp0 |
sc_out<sc_logic> cp0_reg_rw; // Read/Write signal, 1 for write |
sc_out<sc_lv<32> > cp0_reg_rs; // Contents of register rd in instruction for mtc0 |
sc_in<sc_lv<32> > cp0_reg_out; // For reading out from cp0 - for mfc0 |
|
// EXCEPTIONS SIGNALS |
sc_signal<sc_logic> illegal_instruction; |
sc_signal<sc_logic> syscall_exception; |
sc_in<sc_logic> if_id_IBUS; |
sc_in<sc_logic> if_id_inst_addrl; |
sc_out<sc_logic> id_ex_IBUS; |
sc_out<sc_logic> id_ex_inst_addrl; |
sc_out<sc_logic> id_ex_syscall_exception; |
sc_out<sc_logic> id_ex_illegal_instruction; |
sc_out<sc_logic> id_exception; |
sc_in<sc_logic> enable_decode; |
sc_in<sc_uint<32> > if_id_instaddr; |
sc_out<sc_uint<32> > id_ex_instaddr; |
|
sc_in<sc_logic> enable_kernel_mode; |
|
// signals used in control |
sc_signal<sc_lv<5> > rt, rs, rd, sa; |
|
/* sc_lv<5> lrs, lrt, lrd, lsa; // lv version of reg # */ |
/* sc_uint<5> uirs, uirt, uird, uisa; // unsigned integer version of reg # */ |
/* sc_int<32> is, it, id; // integer version of register contents... */ |
|
// sign/zero extend and lui control |
sc_signal<sc_lv<32> > id_sign_extend; |
sc_signal<sc_lv<2> > id_extend_ctrl; |
|
sc_signal<sc_lv<32> > id_mux_fw1; |
sc_signal<sc_lv<32> > id_mux_fw2; |
|
sc_signal<sc_lv<32> > id_reg1; |
sc_signal<sc_lv<32> > id_reg2; |
|
sc_signal<sc_lv<32> > id_alu1; |
sc_signal<sc_lv<32> > id_alu2; |
|
sc_signal<sc_logic> id_equal; |
|
// signal from control unit |
sc_signal<sc_lv<5> > id_writeregister; |
sc_signal<sc_logic> id_regwrite; |
sc_signal<sc_lv<2> > regdest; |
sc_signal<sc_logic> id_select_jump; |
sc_signal<sc_logic> id_pc_store; |
sc_signal<sc_lv<2> > id_sign_ctrl; |
sc_signal<sc_lv<3> > id_branch_select; |
sc_signal<sc_lv<6> > id_alu_ctrl; |
sc_signal<sc_logic> id_datareq; |
sc_signal<sc_logic> id_datarw; |
sc_signal<sc_logic> id_memtoreg; |
sc_signal<sc_logic> id_shamt_ctrl; |
sc_signal<sc_logic> id_mfc0; |
|
// forwarding ctrl unit |
sc_signal<sc_lv<2> > id_fw_ctrl1; |
sc_signal<sc_lv<2> > id_fw_ctrl2; |
|
#ifdef ONEHOT_DEBUG |
sc_signal<sc_logic> inst_addiu; |
sc_signal<sc_logic> inst_jalr; |
sc_signal<sc_logic> inst_lw; |
sc_signal<sc_logic> inst_mfc0; |
sc_signal<sc_logic> inst_mtc0; |
sc_signal<sc_logic> inst_nop; |
sc_signal<sc_logic> inst_sw; |
sc_signal<sc_logic> inst_wait; |
#endif |
|
|
control *control1; |
mux_writeregister *mux_writeregister1; |
sign_extend *sign_extend1; |
add_new_pc *add_new_pc1; |
mux_jump *mux_jump1; |
mux_forward_select *mux_forward_select1; |
mux_forward_select *mux_forward_select2; |
mux_alu1 *mux_alu_1; |
mux_alu2 *mux_alu_2; |
comparator *comparator1; |
forwarding_control *forwarding_control1; |
forwarding_control *forwarding_control2; |
reg_id *reg_id1; |
regfile *localreg; |
decode_ctrl *decode_ctrl1; |
|
|
SC_CTOR(id_stage) |
{ |
control1 = new control("control"); |
control1->if_id_inst(if_id_inst); |
control1->rs(rs); |
control1->rt(rt); |
control1->rd(rd); |
control1->id_alu_ctrl(id_alu_ctrl); |
control1->id_alu_sa(id_alu_sa); |
control1->id_ctrl(id_ctrl); |
control1->id_extend_ctrl(id_extend_ctrl); |
control1->id_sign_ctrl(id_sign_ctrl); |
control1->regdest(regdest); |
control1->id_select_jump(id_select_jump); |
control1->id_pc_store(id_pc_store); |
control1->id_branch_select(id_branch_select); |
control1->id_regwrite(id_regwrite); |
control1->id_shamt_ctrl(id_shamt_ctrl); |
control1->id_datarw(id_datarw); |
control1->id_datareq(id_datareq); |
control1->id_memtoreg(id_memtoreg); |
control1->id_byteselect(id_byteselect); |
control1->cp0_inst(cp0_inst); |
control1->cp0_reg_no(cp0_reg_no); |
control1->cp0_reg_rw(cp0_reg_rw); |
control1->id_mfc0(id_mfc0); |
control1->illegal_instruction(illegal_instruction); //instruzione non definita!! |
control1->syscall_exception(syscall_exception); //instruzione non definita!! |
|
#ifdef ONEHOT_DEBUG |
control1->inst_addiu(inst_addiu); |
control1->inst_jalr(inst_jalr); |
control1->inst_lw(inst_lw); |
control1->inst_mfc0(inst_mfc0); |
control1->inst_mtc0(inst_mtc0); |
control1->inst_nop(inst_nop); |
control1->inst_sw(inst_sw); |
control1->inst_wait(inst_wait); |
#endif |
|
mux_writeregister1 = new mux_writeregister("mux_writeregister"); |
mux_writeregister1->regdest(regdest); |
mux_writeregister1->rt(rt); |
mux_writeregister1->rd(rd); |
mux_writeregister1->id_writeregister(id_writeregister); |
|
sign_extend1 = new sign_extend("sign_extend"); |
sign_extend1->if_id_inst(if_id_inst); |
sign_extend1->id_extend_ctrl(id_extend_ctrl); |
sign_extend1->id_sign_extend(id_sign_extend); |
|
add_new_pc1 = new add_new_pc("add_new_pc"); |
add_new_pc1->if_id_next_pc(if_id_next_pc); |
add_new_pc1->id_sign_extend(id_sign_extend); |
add_new_pc1->id_new_pc(id_new_pc); |
|
mux_jump1 = new mux_jump("mux_jump"); |
mux_jump1->if_id_next_pc(if_id_next_pc); |
mux_jump1->if_id_inst(if_id_inst); |
mux_jump1->id_select_jump(id_select_jump); |
mux_jump1->id_mux_fw1(id_mux_fw1); |
mux_jump1->id_jmp_tar(id_jmp_tar); |
|
mux_forward_select1 = new mux_forward_select("mux_forward_select1"); |
mux_forward_select1->id_reg(id_reg1); |
mux_forward_select1->ex_id_forward(ex_id_forward); |
mux_forward_select1->m_id_forward(m_id_forward); |
mux_forward_select1->wb_id_forward(wb_id_forward); |
mux_forward_select1->id_fw_ctrl(id_fw_ctrl1); |
mux_forward_select1->id_mux_fw(id_mux_fw1); |
|
mux_forward_select2 = new mux_forward_select("mux_forward_select2"); |
mux_forward_select2->id_reg(id_reg2); |
mux_forward_select2->ex_id_forward(ex_id_forward); |
mux_forward_select2->m_id_forward(m_id_forward); |
mux_forward_select2->wb_id_forward(wb_id_forward); |
mux_forward_select2->id_fw_ctrl(id_fw_ctrl2); |
mux_forward_select2->id_mux_fw(id_mux_fw2); |
|
mux_alu_1 = new mux_alu1("mux_alu1"); |
mux_alu_1->if_id_inst(if_id_inst); |
mux_alu_1->id_shamt_ctrl(id_shamt_ctrl); |
mux_alu_1->id_pc_store(id_pc_store); |
mux_alu_1->id_alu1(id_alu1); |
mux_alu_1->if_id_next_pc(if_id_next_pc); |
mux_alu_1->cp0_reg_out(cp0_reg_out); |
mux_alu_1->id_mux_fw1(id_mux_fw1); |
mux_alu_1->id_mfc0(id_mfc0); |
|
mux_alu_2 = new mux_alu2("mux_alu2"); |
mux_alu_2->id_sign_extend(id_sign_extend); |
mux_alu_2->id_sign_ctrl(id_sign_ctrl); |
mux_alu_2->id_alu2(id_alu2); |
mux_alu_2->cp0_reg_rs(cp0_reg_rs); |
mux_alu_2->id_mux_fw2(id_mux_fw2); |
|
comparator1 = new comparator("comparator"); |
comparator1->id_mux_fw1(id_mux_fw1); |
comparator1->id_mux_fw2(id_mux_fw2); |
comparator1->id_branch_select(id_branch_select); |
comparator1->id_equal(id_equal); |
comparator1->id_branch(id_branch); |
|
forwarding_control1 = new forwarding_control("forwarding_control1"); |
forwarding_control1->id_ex_writeregister(id_ex_writeregister); |
forwarding_control1->id_ex_m_writeregister(id_ex_m_writeregister); |
forwarding_control1->id_ex_m_wb_writeregister(id_ex_m_wb_writeregister); |
forwarding_control1->id_ex_regwrite(id_ex_regwrite); |
forwarding_control1->id_ex_m_regwrite(id_ex_m_regwrite); |
forwarding_control1->id_ex_m_wb_regwrite(id_ex_m_wb_regwrite); |
forwarding_control1->rs(rs); |
forwarding_control1->id_fw_ctrl(id_fw_ctrl1); |
|
forwarding_control2 = new forwarding_control("forwarding_control2"); |
forwarding_control2->id_ex_writeregister(id_ex_writeregister); |
forwarding_control2->id_ex_m_writeregister(id_ex_m_writeregister); |
forwarding_control2->id_ex_m_wb_writeregister(id_ex_m_wb_writeregister); |
forwarding_control2->id_ex_regwrite(id_ex_regwrite); |
forwarding_control2->id_ex_m_regwrite(id_ex_m_regwrite); |
forwarding_control2->id_ex_m_wb_regwrite(id_ex_m_wb_regwrite); |
forwarding_control2->rs(rt); |
forwarding_control2->id_fw_ctrl(id_fw_ctrl2); |
|
reg_id1 = new reg_id("reg_id"); |
reg_id1->in_clk(in_clk); |
reg_id1->reset(reset); |
reg_id1->datahold(datahold); |
reg_id1->insthold(insthold); |
reg_id1->id_ex_alu1(id_ex_alu1); |
reg_id1->id_alu1(id_alu1); |
reg_id1->id_ex_alu2(id_ex_alu2); |
reg_id1->id_alu2(id_alu2); |
reg_id1->id_ex_datastore(id_ex_datastore); |
reg_id1->id_mux_fw2(id_mux_fw2); |
reg_id1->id_ex_alu_ctrl(id_ex_alu_ctrl); |
reg_id1->id_alu_ctrl(id_alu_ctrl); |
reg_id1->id_ex_alu_sa(id_ex_alu_sa); |
reg_id1->id_alu_sa(id_alu_sa); |
reg_id1->id_ex_equal(id_ex_equal); |
reg_id1->id_equal(id_equal); |
reg_id1->id_ex_datareq(id_ex_datareq); |
reg_id1->id_datareq(id_datareq); |
reg_id1->id_ex_datarw(id_ex_datarw); |
reg_id1->id_datarw(id_datarw); |
reg_id1->id_ex_memtoreg(id_ex_memtoreg); |
reg_id1->id_memtoreg(id_memtoreg); |
reg_id1->id_ex_writeregister_out(id_ex_writeregister_out); |
reg_id1->id_writeregister(id_writeregister); |
reg_id1->id_ex_writeregister(id_ex_writeregister); |
reg_id1->id_ex_regwrite_out(id_ex_regwrite_out); |
reg_id1->id_regwrite(id_regwrite); |
reg_id1->id_ex_regwrite(id_ex_regwrite); |
reg_id1->id_ex_byteselect(id_ex_byteselect); |
reg_id1->id_byteselect(id_byteselect); |
reg_id1->id_ex_bssign(id_ex_bssign); |
reg_id1->id_bssign(id_bssign); |
// pipelined exception signals |
reg_id1->if_id_IBUS(if_id_IBUS); |
reg_id1->if_id_inst_addrl(if_id_inst_addrl); |
reg_id1->syscall_exception(syscall_exception); |
reg_id1->illegal_instruction(illegal_instruction); |
reg_id1->id_ex_IBUS(id_ex_IBUS); |
reg_id1->id_ex_inst_addrl(id_ex_inst_addrl); |
reg_id1->id_ex_syscall_exception(id_ex_syscall_exception); |
reg_id1->id_ex_illegal_instruction(id_ex_illegal_instruction); |
reg_id1->enable_decode(enable_decode); |
reg_id1->if_id_instaddr(if_id_instaddr); |
reg_id1->id_ex_instaddr(id_ex_instaddr); |
|
decode_ctrl1 = new decode_ctrl("decode_ctrl"); |
decode_ctrl1->if_id_IBUS(if_id_IBUS); |
decode_ctrl1->if_id_inst_addrl(if_id_inst_addrl); |
decode_ctrl1->syscall_exception(syscall_exception); |
decode_ctrl1->illegal_instruction(illegal_instruction); |
decode_ctrl1->id_exception(id_exception); |
|
localreg = new regfile("regfiles"); |
localreg->in_clk(in_clk); |
localreg->reset(reset); |
localreg->rs(rs); |
localreg->rt(rt); |
localreg->wr(id_ex_m_wb_regwrite); |
localreg->rd_in(wb_id_forward); |
localreg->rd(id_ex_m_wb_writeregister); |
localreg->rs_out(id_reg1); |
localreg->rt_out(id_reg2); |
} |
}; |
/trunk/cpu/cpu/pc_stage.cpp
0,0 → 1,351
#include "pc_stage.h" |
/trunk/cpu/cpu/sc_risc.cpp
0,0 → 1,112
// |
// $Id: sc_risc.cpp,v 1.1 2006-01-21 03:37:32 igorloi Exp $ |
// |
#include "sc_risc.h" |
|
sc_risc::sc_risc(const sc_module_name& name_) |
{ |
cpu = new sc_cpu("cpu-processor"); |
|
cpu->in_clk(in_clk); |
cpu->reset(reset); |
cpu->instdataread(instdataread); |
cpu->instdatawrite(instdatawrite); |
cpu->instaddr(instaddr); |
cpu->instreq(instreq); |
cpu->instrw(instrw); |
cpu->insthold(x_insthold); |
cpu->dataread(dataread); |
cpu->datawrite(datawrite); |
cpu->dataaddr(dataaddr); |
cpu->datareq(datareq); |
cpu->datarw(datarw); |
cpu->databs(databs); |
cpu->datahold(datahold); |
cpu->new_pc(new_pc); |
cpu->load_epc(load_epc); |
cpu->pc_in(pc_in); |
cpu->pc_out(pc_out); |
cpu->id_branch(id_branch); |
cpu->id_ctrl(id_ctrl); |
cpu->id_ex_datarw(id_ex_datarw); |
cpu->id_ex_datareq(id_ex_datareq); |
cpu->addr_err(addr_err); |
cpu->cp0_inst(cp0_inst); |
cpu->reg_rs(reg_rs); |
cpu->reg_out(reg_out); |
cpu->reg_no(reg_no); |
cpu->reg_rw(reg_rw); |
cpu->ex_id_forward(ex_id_forward); |
|
// EXCEPTION SIGNALS FROM DATAMEM AND INSTMEM |
cpu->IBUS(IBUS); |
cpu->inst_addrl(inst_addrl); |
cpu->DBUS(DBUS); |
cpu->data_addrl(data_addrl); |
cpu->data_addrs(data_addrs); |
|
// EXCEPTION STATUS VECTOR FROM CPU TO CP0 |
cpu->m_wb_ovf_excep(m_wb_ovf_excep); |
cpu->m_wb_syscall_exception(m_wb_syscall_exception); |
cpu->m_wb_illegal_instruction(m_wb_illegal_instruction); |
cpu->m_wb_inst_addrl(m_wb_inst_addrl); // disaligned address in instmem during fetch stage |
cpu->m_wb_IBUS(m_wb_IBUS); //page fault in instmem |
cpu->m_wb_data_addrl(m_wb_data_addrl); //disaligned address in datamem during load instruction |
cpu->m_wb_data_addrs(m_wb_data_addrs); //disaligned address in datamem during store instruction |
cpu->m_wb_DBUS(m_wb_DBUS); //page fault in instmem |
cpu->m_wb_dataaddr(m_wb_dataaddr); |
cpu->m_wb_instaddr_s(m_wb_instaddr); |
cpu->interrupt_signal(interrupt_signal); |
cpu->m_wb_interrupt_signal(m_wb_interrupt_signal); |
cpu->enable_interrupt(enable_interrupt); |
cpu->enable_kernel_mode(enable_kernel_mode); |
|
|
co0 = new cp0("cp0_module"); |
co0->in_clk(in_clk); |
co0->reset(reset); |
// to IF stage |
co0->new_pc(new_pc); |
co0->load_epc(load_epc); |
// to/from ID stage |
co0->pc_out(pc_out); |
co0->pc_in(pc_in); |
co0->id_ex_datarw(id_ex_datarw); |
co0->id_ex_datareq(id_ex_datareq); |
co0->id_branch(id_branch); |
co0->id_ctrl(id_ctrl); |
// co0->inst_break(inst_break); |
// co0->inst_syscall(inst_syscall); |
// to ID stage |
co0->cp0_inst(cp0_inst); |
co0->reg_no(reg_no); |
co0->reg_rw(reg_rw); |
co0->reg_out(reg_out); |
// from ID stage |
co0->reg_rs(reg_rs); |
// from EX stage |
co0->ex_alu(ex_id_forward); |
|
// to EX stage |
co0->addr_err(addr_err); |
// to all stages |
co0->x_insthold(insthold); // input to cp0 |
co0->insthold(x_insthold); // output from cp0*/ |
|
// EXCEPTION STATUS VECTOR FROM CPU TO CP0 |
co0->m_wb_inst_addrl(m_wb_inst_addrl); // disaligned address in instmem during fetch stage |
co0->m_wb_IBUS(m_wb_IBUS); //page fault in instmem |
co0->m_wb_data_addrl(m_wb_data_addrl); //disaligned address in datamem during load instruction |
co0->m_wb_data_addrs(m_wb_data_addrs); //disaligned address in datamem during store instruction |
co0->m_wb_DBUS(m_wb_DBUS); //page fault in instmem |
co0->m_wb_syscall_exception(m_wb_syscall_exception); |
co0->m_wb_illegal_instruction(m_wb_illegal_instruction); |
co0->m_wb_ovf_excep(m_wb_ovf_excep); |
co0->m_wb_dataaddr(m_wb_dataaddr); |
co0->m_wb_instaddr(m_wb_instaddr); |
co0->m_wb_interrupt_signal(m_wb_interrupt_signal); |
co0->enable_interrupt(enable_interrupt); |
co0->enable_kernel_mode(enable_kernel_mode); |
|
} |
|
/trunk/cpu/cpu/if_stage.h
0,0 → 1,103
//! IF Stage module |
// |
// $Id: if_stage.h,v 1.1 2006-01-21 03:37:32 igorloi Exp $ |
// |
#ifndef _IF_STAGE_H |
#define _IF_STAGE_H |
|
#include <systemc.h> |
#include "./if_stage/add.h" |
#include "./if_stage/reg_if.h" |
#include "./if_stage/select_next_pc.h" |
#include "./if_stage/if_ctrl.h" |
|
SC_MODULE(if_stage) |
{ |
sc_in<bool> in_clk; |
sc_in<bool> reset; |
|
sc_in<bool> insthold; |
sc_in<bool> datahold; |
|
sc_in<sc_lv<32> > pc_out; |
sc_in<sc_lv<32> > id_new_pc; |
sc_in<sc_lv<32> > id_jmp_tar; |
sc_in<sc_logic> id_ctrl; |
sc_in<sc_logic> id_branch; |
|
sc_out<sc_lv<32> > pc_in; |
|
sc_in<sc_lv<32> > instdataread; |
sc_out<sc_lv<32> > if_id_inst; |
sc_out<sc_lv<32> > if_id_next_pc; |
|
// cp0 connections |
sc_in<sc_lv<32> > new_pc; |
sc_in<sc_logic> load_epc; |
|
// exception signals |
sc_in<sc_logic> IBUS; |
sc_in<sc_logic> inst_addrl; |
sc_out<sc_logic> if_id_IBUS; |
sc_out<sc_logic> if_id_inst_addrl; |
sc_in<sc_uint<32> > pc_if_instaddr; |
sc_out<sc_uint<32> > if_id_instaddr; |
|
sc_out<sc_logic> if_exception; |
sc_in<sc_logic> enable_fetch; |
|
// Signals |
sc_signal<sc_lv<32> > if_pc_add; |
|
reg_if *reg_if1; |
add *add1; |
select_next_pc *select_next_pc1; |
if_ctrl *if_ctrl1; |
|
//! Constructor |
/*! |
No description |
*/ |
SC_CTOR(if_stage) |
{ |
reg_if1 = new reg_if("reg_if"); |
reg_if1->in_clk(in_clk); |
reg_if1->reset(reset); |
reg_if1->insthold(insthold); |
reg_if1->datahold(datahold); |
reg_if1->instdataread(instdataread); |
reg_if1->if_pc_add(if_pc_add); |
reg_if1->if_id_inst(if_id_inst); |
reg_if1->if_id_next_pc(if_id_next_pc); |
//exception signals |
reg_if1->IBUS(IBUS); |
reg_if1->inst_addrl(inst_addrl); |
reg_if1->if_id_IBUS(if_id_IBUS); |
reg_if1->if_id_inst_addrl(if_id_inst_addrl); |
reg_if1->pc_if_instaddr(pc_if_instaddr); |
reg_if1->if_id_instaddr(if_id_instaddr); |
reg_if1->enable_fetch(enable_fetch); |
|
|
add1 = new add("add"); |
add1->if_pc_add(if_pc_add); |
add1->pc_out(pc_out); |
|
select_next_pc1 = new select_next_pc("select_next_pc"); |
select_next_pc1->new_pc(new_pc); |
select_next_pc1->load_epc(load_epc); |
select_next_pc1->id_ctrl(id_ctrl); |
select_next_pc1->id_branch(id_branch); |
select_next_pc1->if_pc_add(if_pc_add); |
select_next_pc1->id_new_pc(id_new_pc); |
select_next_pc1->id_jmp_tar(id_jmp_tar); |
select_next_pc1->pc_in(pc_in); |
|
if_ctrl1 = new if_ctrl("if_ctrl"); |
if_ctrl1->IBUS(IBUS); |
if_ctrl1->inst_addrl(inst_addrl); |
if_ctrl1->if_exception(if_exception); |
} |
}; |
|
#endif |
/trunk/cpu/cpu/cp0.h
0,0 → 1,218
|
// |
// $Id: cp0.h,v 1.1 2006-01-21 03:37:32 igorloi Exp $ |
// |
|
#ifndef _CP0_H |
#define _CP0_H |
|
#include <systemc.h> |
|
#include "./cp0/cp0_register.h" |
#include "./cp0/exception.h" |
|
#include "./cp0/set_stop_pc.h" |
|
#include "../constants/config.h" |
#include "../constants/constants.h" |
#include "../constants/cp0constants.h" |
#include "../constants/avrconstants.h" |
#include "../constants/mipsconstants.h" |
|
SC_MODULE(cp0) |
{ |
sc_in<bool> in_clk; |
sc_in<bool> reset; |
|
//! Current instruction address |
/*! |
The current instruction address. |
*/ |
sc_in<sc_lv<32> > pc_out; |
|
//! Next instrition address |
/*! |
The next instruction address. |
This address can bee the new address after af jump. |
*/ |
sc_in<sc_lv<32> > pc_in; |
|
//! Data read/write signal, 1 is write |
sc_in<sc_logic> id_ex_datarw; |
|
//! Data req |
/*! |
Data req signal |
*/ |
sc_in<sc_logic> id_ex_datareq; |
|
//! Branch signal |
/*! |
Indicate that the instruction is a branch if signal bit is set. |
*/ |
sc_in<sc_logic> id_branch; |
|
//! Jump signal |
/*! |
Indicate that the instruction is a jump if signal bit is set. |
*/ |
sc_in<sc_logic> id_ctrl; |
|
//! Break signal |
/*! |
This signal indicate that a break instruction has occured. |
*/ |
// sc_in<sc_logic> inst_break; |
|
//! Syscall signal |
/*! |
This signal indicate a syscall instruction has occured. |
*/ |
// sc_in<sc_logic> inst_syscall; |
|
//! New pc signal |
/*! |
When an exception occurs, the program counter is loaded with at new value. |
*/ |
sc_out<sc_lv<32> > new_pc; |
|
//! Load EPC in stead of PC? |
/*! |
This signal tells the mux to select new_pc from cp0 |
*/ |
sc_out<sc_logic> load_epc; |
|
|
|
//! The data addres - from EX stage |
/*! |
The data addres, which is use to load or store a word. |
*/ |
sc_in<sc_lv<32> > ex_alu; |
|
//! Address error indicator to MEM stage |
/*! |
addr_err is raised to prevent a memory action to take place when an |
Address Error Exception occurs |
*/ |
sc_out<sc_logic> addr_err; |
|
//! The current cp0 instruction in id_stage (if any) |
/* |
Tells cp0 if the instruction in id_stage is relevant |
*/ |
sc_in<sc_lv<4> > cp0_inst; |
|
//! To all stages. Stops the cpu by halting cpu |
sc_in<bool> x_insthold; |
sc_out<bool> insthold; |
|
//! Output register no. defined by address in reg_no |
sc_in<sc_uint<5> > reg_no; |
sc_in<sc_logic> reg_rw; |
sc_in<sc_lv<32> > reg_rs; |
sc_out<sc_lv<32> > reg_out; |
|
|
// EXCEPTIONS SIGNAL FROM DATAMEM aND INSTMEM |
sc_in<sc_logic> m_wb_inst_addrl; // disaligned address in instmem during fetch stage |
sc_in<sc_logic> m_wb_IBUS; //page fault in instmem |
sc_in<sc_logic> m_wb_data_addrl; //disaligned address in datamem during load instruction |
sc_in<sc_logic> m_wb_data_addrs; //disaligned address in datamem during store instruction |
sc_in<sc_logic> m_wb_DBUS; //page fault in datamem |
|
// EXCEPTION SIGNAL FROM INSTRUCTION FETCH STAGE |
sc_in<sc_logic> m_wb_illegal_instruction; |
sc_in<sc_logic> m_wb_syscall_exception; |
|
// This signal is set to 1 by the ALU when an overflow occurs. |
sc_in<sc_logic> m_wb_ovf_excep; |
|
// INTERRUPT SIGNAL |
sc_in<bool> m_wb_interrupt_signal; |
|
sc_in<sc_uint<32> > m_wb_dataaddr; |
sc_in<sc_uint<32> > m_wb_instaddr; |
|
|
sc_signal<sc_lv<32> > cause; |
sc_signal<bool> check_excep; |
sc_signal<sc_uint<32> > to_EPC; |
sc_signal<sc_uint<32> > to_BadVAddr; |
sc_signal<sc_uint<32> > EPC_FOR_RFE; |
|
//! Old Branch indication |
/*! |
This register is used to store informationen of previous branchs or jumps. |
*/ |
sc_signal<sc_logic> id_ex_branch_or_jump; |
|
// 32 registers 32 bit CP0 |
sc_signal<sc_lv<32> > cp0regs[32]; |
|
sc_out<sc_logic> enable_interrupt; |
sc_out<sc_logic> enable_kernel_mode; |
|
|
|
cp0_register *cp0_r; |
exception *excp; |
set_stop_pc *sspc; |
|
|
|
SC_CTOR(cp0) |
{ |
|
cp0_r = new cp0_register("cp0_register"); |
cp0_r->in_clk(in_clk); |
cp0_r->reset(reset); |
cp0_r->reg_no(reg_no); |
cp0_r->reg_rw(reg_rw); |
cp0_r->reg_rs(reg_rs); |
cp0_r->reg_out(reg_out); |
cp0_r->cause(cause); |
cp0_r->check_excep(check_excep); |
cp0_r->to_EPC(to_EPC); |
cp0_r->to_BadVAddr(to_BadVAddr); |
cp0_r->EPC_FOR_RFE(EPC_FOR_RFE); |
cp0_r->cp0_inst(cp0_inst); |
cp0_r->enable_interrupt(enable_interrupt); |
cp0_r->enable_kernel_mode(enable_kernel_mode); |
|
excp = new exception("exception"); |
excp->in_clk(in_clk); |
excp->reset(reset); |
excp->m_wb_IBUS(m_wb_IBUS); |
excp->m_wb_inst_addrl(m_wb_inst_addrl); |
excp->m_wb_syscall_exception(m_wb_syscall_exception); |
excp->m_wb_illegal_instruction(m_wb_illegal_instruction); |
excp->m_wb_ovf_excep(m_wb_ovf_excep); |
excp->m_wb_DBUS(m_wb_DBUS); |
excp->m_wb_data_addrl(m_wb_data_addrl); |
excp->m_wb_data_addrs(m_wb_data_addrs); |
excp->m_wb_dataaddr(m_wb_dataaddr); |
excp->m_wb_instaddr(m_wb_instaddr); |
excp->cause(cause); |
excp->check_excep(check_excep); |
excp->to_EPC(to_EPC); |
excp->to_BadVAddr(to_BadVAddr); |
excp->m_wb_interrupt_signal(m_wb_interrupt_signal); |
excp->cp0_inst(cp0_inst); |
|
|
sspc = new set_stop_pc("set_stop_pc"); |
sspc->in_clk(in_clk); |
sspc->reset(reset); |
sspc->x_insthold(x_insthold); |
sspc->insthold(insthold); |
sspc->pc_in(pc_in); |
sspc->cp0_inst(cp0_inst); |
sspc->new_pc(new_pc); |
sspc->load_epc(load_epc); |
sspc->check_excep(check_excep); |
sspc->EPC_FOR_RFE(EPC_FOR_RFE); |
} |
}; |
|
#endif |
/trunk/cpu/cpu/pc_stage.h
0,0 → 1,58
// |
// $Id: pc_stage.h,v 1.1 2006-01-21 03:37:32 igorloi Exp $ |
// |
#ifndef _PC_STAGE_H |
#define _PC_STAGE_H |
|
#include <systemc.h> |
#include "./pc_stage/reg_pc.h" |
#include "../constants/constants.h" |
#include "../constants/config.h" |
|
SC_MODULE(pc_stage) |
{ |
|
sc_in<bool> in_clk; |
sc_in<bool> reset; |
|
sc_in<bool> insthold; |
sc_in<bool> datahold; |
|
sc_in<sc_logic> enable_pc; |
|
sc_in<sc_lv<32> > pc_in; |
sc_out<sc_lv<32> > pc_out; |
|
sc_out<sc_uint<32> > instaddr; |
sc_out<sc_lv<32> > instdatawrite; |
|
sc_out<sc_logic> instreq; |
sc_out<sc_logic> instrw; |
|
reg_pc *reg_pc1; |
|
SC_CTOR(pc_stage) |
{ |
reg_pc1 = new reg_pc("reg_pc"); |
|
reg_pc1->in_clk(in_clk); |
reg_pc1->reset(reset); |
|
reg_pc1->insthold(insthold); |
reg_pc1->datahold(datahold); |
|
reg_pc1->enable_pc(enable_pc); |
|
reg_pc1->pc_in(pc_in); |
reg_pc1->pc_out(pc_out); |
|
reg_pc1->instaddr(instaddr); |
reg_pc1->instdatawrite(instdatawrite); |
|
reg_pc1->instreq(instreq); |
reg_pc1->instrw(instrw); |
} |
}; |
|
#endif |
|
/trunk/cpu/cpu/sc_risc.h
0,0 → 1,113
// |
// $Id: sc_risc.h,v 1.1 2006-01-21 03:37:32 igorloi Exp $ |
// |
#ifndef _SC_RISC_H |
#define _SC_RISC_H |
|
#include <systemc.h> |
#include "../constants/constants.h" |
#include "../constants/config.h" |
#include "sc_cpu.h" |
#include "cp0.h" |
|
SC_MODULE(sc_risc) |
{ |
// |
// Very basic signals for the CPU! |
// |
//! Main clock signal |
sc_in<bool> in_clk; |
//! Main reset signal |
sc_in<bool> reset; |
|
// |
// Instruction memory interface |
// |
//! Instruction memory input data |
sc_in<sc_lv<32> > instdataread; |
sc_out<sc_lv<32> > instdatawrite; |
//! Instruction memory address |
sc_out<sc_uint<32> > instaddr; |
//! Instruction memory request |
sc_out<sc_logic> instreq; |
//! Instruction memory read/write signal. 1 for write. 0 for read. |
sc_out<sc_logic> instrw; |
//! Hold signal from instruction memory |
sc_in<bool> insthold; |
|
// |
// Data memory interface |
// |
//! Data memory in/out data |
sc_in<sc_lv<32> > dataread; |
sc_out<sc_lv<32> > datawrite; |
//! Data memory address |
sc_out<sc_uint<32> > dataaddr; |
//! Data memory request |
sc_out<sc_logic> datareq; |
//! Data memory read/write signal. 1 for write. 0 for read. |
sc_out<sc_logic> datarw; |
//! Byte select signal. Select bytes to be written. 01 for byte, 10 for halfword |
sc_out<sc_lv<2> > databs; |
//! Hold signal from data memory |
sc_in<bool> datahold; |
|
//INTERRUPT SIGNAL FROM TOP_MODULE |
sc_in<bool> interrupt_signal; |
sc_signal<bool> m_wb_interrupt_signal; |
|
//interrupt enable and Kernel_mode or User_mode Signal |
sc_signal<sc_logic> enable_interrupt; |
sc_signal<sc_logic> enable_kernel_mode; |
|
//exceptions signal from datamem and instmem |
sc_in<sc_logic> inst_addrl; // disaligned address in instmem during fetch stage |
sc_in<sc_logic> IBUS; //page fault in instmem |
sc_in<sc_logic> data_addrl; //disaligned address in datamem during load instruction |
sc_in<sc_logic> data_addrs; //disaligned address in datamem during store instruction |
sc_in<sc_logic> DBUS; //page fault in datamem |
|
sc_signal<sc_logic> m_wb_inst_addrl; |
sc_signal<sc_logic> m_wb_IBUS; |
sc_signal<sc_logic> m_wb_data_addrl; |
sc_signal<sc_logic> m_wb_data_addrs; |
sc_signal<sc_logic> m_wb_DBUS; |
sc_signal<sc_logic> m_wb_syscall_exception; // Syscall |
sc_signal<sc_logic> m_wb_illegal_instruction; // illegal instruction |
sc_signal<sc_logic> m_wb_ovf_excep; // Overflow |
sc_signal<sc_uint<32> > m_wb_instaddr; //victim address in INSTMEM |
sc_signal<sc_uint<32> > m_wb_dataaddr; //Victim Address in DATAMEM |
sc_signal<sc_uint<32> > ex_m_instaddr; //address of the last non-completed instruction during interrupt |
|
|
// to CP0_STAGE |
sc_signal<sc_lv<32> > new_pc; |
sc_signal<sc_logic> load_epc; |
sc_signal<sc_lv<32> > pc_in; |
sc_signal<sc_lv<32> > pc_out; |
sc_signal<sc_logic> id_branch; |
sc_signal<sc_logic> id_ctrl; |
sc_signal<sc_logic> id_ex_datarw; |
sc_signal<sc_logic> id_ex_datareq; |
|
sc_signal<sc_logic> addr_err; |
sc_signal<bool> x_insthold; |
sc_signal<sc_lv<4> > cp0_inst; |
sc_signal<sc_lv<32> > reg_rs; |
sc_signal<sc_lv<32> > reg_out; |
sc_signal<sc_uint<5> > reg_no; |
sc_signal<sc_logic> reg_rw; |
sc_signal<sc_lv<32> > ex_id_forward; |
|
sc_signal<sc_logic> interrupt_exception; |
|
sc_cpu *cpu; |
cp0 *co0; |
|
|
SC_HAS_PROCESS(sc_risc); |
sc_risc (const sc_module_name& name_); |
|
}; |
|
#endif |