/**************************************************************** * RISC main module source file * * サブモジュール、メモリモジュールをインクルードして合成 * ****************************************************************/ /**** ファイルの読み込み(%i はCの #include と同じ) ****/ %i "alu32.sfl" /* 32ビットalu */ %i "sft32.sfl" /* 32ビットシフタ */ %i "adder32.sfl" /* 32ビット加算器 */ %i "reg_file.sfl" /* レジスタ・ファイル(32x32) */ %i "zero32.sfl" /* 32ビットゼロフラグ判定器 */ %i "cmp5.sfl" /* 5ビット比較器 */ %i "multi32.sfl" /* 32ビット乗算器(32,32>>64) */ %i "memory.sfl" /* メモリモジュール */ /***** マクロ *****/ %d ALUINST (^ir<31> & ^ir<30> & ^ir<29> & ^ir<28> & ^ir<27> & ^ir<26>) %d ADD (^ir<05> & ^ir<04> & ^ir<03> & ^ir<02> & ^ir<01> & ^ir<00>) %d ADDU (^ir<05> & ^ir<04> & ^ir<03> & ^ir<02> & ^ir<01> & ir<00>) %d SUB (^ir<05> & ^ir<04> & ^ir<03> & ^ir<02> & ir<01> & ^ir<00>) %d SUBU (^ir<05> & ^ir<04> & ^ir<03> & ^ir<02> & ir<01> & ir<00>) %d AND (^ir<05> & ^ir<04> & ^ir<03> & ir<02> & ^ir<01> & ^ir<00>) %d OR (^ir<05> & ^ir<04> & ^ir<03> & ir<02> & ^ir<01> & ir<00>) %d XOR (^ir<05> & ^ir<04> & ^ir<03> & ir<02> & ir<01> & ^ir<00>) %d MUL ( ir<05> & ir<04> & ^ir<03> & ^ir<02> & ^ir<01> & ^ir<00>) %d MULU ( ir<05> & ir<04> & ^ir<03> & ^ir<02> & ^ir<01> & ir<00>) %d SLL (^ir<05> & ir<04> & ^ir<03> & ^ir<02> & ^ir<01> & ^ir<00>) %d SRL (^ir<05> & ir<04> & ^ir<03> & ^ir<02> & ^ir<01> & ir<00>) %d SRA (^ir<05> & ir<04> & ^ir<03> & ^ir<02> & ir<01> & ^ir<00>) %d SLT (^ir<05> & ir<04> & ir<03> & ^ir<02> & ^ir<01> & ^ir<00>) %d SGT (^ir<05> & ir<04> & ir<03> & ^ir<02> & ^ir<01> & ir<00>) %d SLE (^ir<05> & ir<04> & ir<03> & ^ir<02> & ir<01> & ^ir<00>) %d SGE (^ir<05> & ir<04> & ir<03> & ^ir<02> & ir<01> & ir<00>) %d SEQ (^ir<05> & ir<04> & ir<03> & ir<02> & ^ir<01> & ^ir<00>) %d SNE (^ir<05> & ir<04> & ir<03> & ir<02> & ^ir<01> & ir<00>) %d JR (^ir<05> & ^ir<04> & ir<03> & ^ir<02> & ir<01> & ^ir<00>) %d JALR (^ir<05> & ^ir<04> & ir<03> & ^ir<02> & ir<01> & ir<00>) %d J (^ir<31> & ^ir<30> & ^ir<29> & ^ir<28> & ir<27> & ^ir<26>) %d JAL (^ir<31> & ^ir<30> & ^ir<29> & ^ir<28> & ir<27> & ir<26>) %d BEQZ (^ir<31> & ^ir<30> & ^ir<29> & ir<28> & ^ir<27> & ^ir<26>) %d BNEZ (^ir<31> & ^ir<30> & ^ir<29> & ir<28> & ^ir<27> & ir<26>) %d ADDI (^ir<31> & ^ir<30> & ir<29> & ^ir<28> & ^ir<27> & ^ir<26>) %d ADDUI (^ir<31> & ^ir<30> & ir<29> & ^ir<28> & ^ir<27> & ir<26>) %d SUBI (^ir<31> & ^ir<30> & ir<29> & ^ir<28> & ir<27> & ^ir<26>) %d SUBUI (^ir<31> & ^ir<30> & ir<29> & ^ir<28> & ir<27> & ir<26>) %d ANDI (^ir<31> & ^ir<30> & ir<29> & ir<28> & ^ir<27> & ^ir<26>) %d ORI (^ir<31> & ^ir<30> & ir<29> & ir<28> & ^ir<27> & ir<26>) %d XORI (^ir<31> & ^ir<30> & ir<29> & ir<28> & ir<27> & ^ir<26>) %d SLLI (^ir<31> & ir<30> & ^ir<29> & ^ir<28> & ^ir<27> & ^ir<26>) %d SRLI (^ir<31> & ir<30> & ^ir<29> & ^ir<28> & ^ir<27> & ir<26>) %d SRAI (^ir<31> & ir<30> & ^ir<29> & ^ir<28> & ir<27> & ^ir<26>) %d ORHI (^ir<31> & ir<30> & ^ir<29> & ir<28> & ^ir<27> & ^ir<26>) %d SLTI (^ir<31> & ir<30> & ir<29> & ^ir<28> & ^ir<27> & ^ir<26>) %d SGTI (^ir<31> & ir<30> & ir<29> & ^ir<28> & ^ir<27> & ir<26>) %d SLEI (^ir<31> & ir<30> & ir<29> & ^ir<28> & ir<27> & ^ir<26>) %d SGEI (^ir<31> & ir<30> & ir<29> & ^ir<28> & ir<27> & ir<26>) %d SEQI (^ir<31> & ir<30> & ir<29> & ir<28> & ^ir<27> & ^ir<26>) %d SNEI (^ir<31> & ir<30> & ir<29> & ir<28> & ^ir<27> & ir<26>) %d LB ( ir<31> & ^ir<30> & ^ir<29> & ^ir<28> & ^ir<27> & ^ir<26>) %d LBU ( ir<31> & ^ir<30> & ^ir<29> & ^ir<28> & ^ir<27> & ir<26>) %d LH ( ir<31> & ^ir<30> & ^ir<29> & ^ir<28> & ir<27> & ^ir<26>) %d LHU ( ir<31> & ^ir<30> & ^ir<29> & ^ir<28> & ir<27> & ir<26>) %d LW ( ir<31> & ^ir<30> & ^ir<29> & ir<28> & ^ir<27> & ^ir<26>) %d SB ( ir<31> & ^ir<30> & ir<29> & ^ir<28> & ^ir<27> & ^ir<26>) %d SH ( ir<31> & ^ir<30> & ir<29> & ^ir<28> & ir<27> & ^ir<26>) %d SW ( ir<31> & ^ir<30> & ir<29> & ir<28> & ^ir<27> & ^ir<26>) %d E_BJ (^op_e<5> & ^op_e<4> & ^op_e<3>) %d E_ALU (^op_e<5> & ^op_e<4> & op_e<3>) %d E_SFT (^op_e<5> & op_e<4> & ^op_e<3>) %d E_SET (^op_e<5> & op_e<4> & op_e<3>) %d E_LOD ( op_e<5> & ^op_e<4> & ^op_e<3>) %d E_STO ( op_e<5> & ^op_e<4> & op_e<3>) %d E_MD ( op_e<5> & op_e<4> & ^op_e<3>) %d E_ADD (^op_e<2> & ^op_e<1> & ^op_e<0>) %d E_ADDU (^op_e<2> & ^op_e<1> & op_e<0>) %d E_SUB (^op_e<2> & op_e<1> & ^op_e<0>) %d E_SUBU (^op_e<2> & op_e<1> & op_e<0>) %d E_AND ( op_e<2> & ^op_e<1> & ^op_e<0>) %d E_OR ( op_e<2> & ^op_e<1> & op_e<0>) %d E_XOR ( op_e<2> & op_e<1> & ^op_e<0>) %d E_MUL (^op_e<2> & ^op_e<1> & ^op_e<0>) %d E_MULU (^op_e<2> & ^op_e<1> & op_e<0>) %d E_SLL (^op_e<2> & ^op_e<1> & ^op_e<0>) %d E_SRL (^op_e<2> & ^op_e<1> & op_e<0>) %d E_SRA (^op_e<2> & op_e<1> & ^op_e<0>) %d E_ORH ( op_e<2> & ^op_e<1> & ^op_e<0>) %d E_SLT (^op_e<2> & ^op_e<1> & ^op_e<0>) %d E_SGT (^op_e<2> & ^op_e<1> & op_e<0>) %d E_SLE (^op_e<2> & op_e<1> & ^op_e<0>) %d E_SGE (^op_e<2> & op_e<1> & op_e<0>) %d E_SEQ ( op_e<2> & ^op_e<1> & ^op_e<0>) %d E_SNE ( op_e<2> & ^op_e<1> & op_e<0>) %d E_SB (^op_e<2> & ^op_e<1> & ^op_e<0>) %d E_SH (^op_e<2> & op_e<1> & ^op_e<0>) %d E_SW ( op_e<2> & ^op_e<1> & ^op_e<0>) %d M_LOD ( op_m<5> & ^op_m<4> & ^op_m<3>) %d M_STO ( op_m<5> & ^op_m<4> & op_m<3>) %d M_LB (^op_m<2> & ^op_m<1> & ^op_m<0>) %d M_LBU (^op_m<2> & ^op_m<1> & op_m<0>) %d M_LH (^op_m<2> & op_m<1> & ^op_m<0>) %d M_LHU (^op_m<2> & op_m<1> & op_m<0>) %d M_LW ( op_m<2> & ^op_m<1> & ^op_m<0>) %d W_LOD ( op_w<5> & ^op_w<4> & ^op_w<3>) module newcpu { /* サブモジュールの設定 */ submod_type alu32 { input a<32> ; input b<32> ; output out<32> ; output ov ; output z ; instrin add ; instrin sub ; instrin and ; instrin or ; instrin xor ; } submod_type sft32 { input a<32> ; input b<5> ; output out<32> ; instrin sll ; instrin srl ; instrin sra ; } submod_type adder32 { input in1<32> ; input in2<32> ; output out<32> ; instrin add ; } submod_type reg_file { input a_adrs<5> ; input b_adrs<5> ; input w_adrs<5> ; input w_data<32> ; output a<32> ; output b<32> ; instrin do ; } submod_type zero32 { input data<32> ; output zero ; instrin do ; } submod_type cmp5 { input in1<5> ; input in2<5> ; output same ; instrin do ; } submod_type multi32 { input in1<32> ; input in2<32> ; output out<64> ; instrin do ; } /* モジュールの構成要素の定義 */ instrin reset ; instrout i_read ; output ir_adrs<32> ; input ir_data<32> ; instrout o_read ; instrout o_write ; input or_data<32> ; output rw_adrs<32> ; output ow_data<32> ; output ow_loc<4> ; instrself set_pc ; tmp a_adrs<5> ; tmp b_adrs<5> ; tmp w_adrs<5> ; tmp a_data<32> ; tmp b_data<32> ; tmp w_data<32> ; tmp wb_adrs<5> ; tmp wb_data<32> ; tmp e_result<32> ; tmp m_align<32> ; tmp mul_dust<64> ; reg pc<32> ; /* プログラム・カウンタ */ reg ir<32> ; /* 命令レジスタ */ reg a<32> ; /* データA */ reg b<32> ; /* データB */ reg mdr_e<32> ; /* メモリ・データレジスタ(exe) */ reg mdr_m<32> ; /* メモリ・データレジスタ(mem) */ reg mdr_w<32> ; /* メモリ・データレジスタ(wb) */ reg rslt_m<32> ; /* 実行結果(mem) */ reg rslt_w<32> ; /* 実行結果(wb) */ reg op_e<6> ; /* 命令操作コード(exe) */ reg op_e_dist<5> ; /* デスティネーション・アドレス(exe) */ reg op_m<6> ; /* 命令操作コード(mem) */ reg op_m_dist<5> ; /* デスティネーション・アドレス(mem) */ reg op_w<6> ; /* 命令操作コード(wb) */ reg op_w_dist<5> ; /* デスティネーション・アドレス(wb) */ reg st_loc<4> ; /* ストア・ロケーション(8,16bit>>32bit) */ alu32 alu ; sft32 shift ; adder32 pc_add ; reg_file reg_file ; zero32 zero_check ; cmp5 cmp5a_e ; cmp5 cmp5b_e ; cmp5 cmp5a_m ; cmp5 cmp5b_m ; cmp5 cmp5a_w ; cmp5 cmp5b_w ; multi32 multi ; /* 制御端子の引数の定義 */ instr_arg i_read(ir_adrs); instr_arg o_read(rw_adrs); instr_arg o_write(rw_adrs,ow_loc,ow_data); /* サブ・モジュールの引数の定義 */ instr_arg alu.add(a,b) ; /* 加算 */ instr_arg alu.sub(a,b) ; /* 減算 */ instr_arg alu.and(a,b) ; /* and */ instr_arg alu.or(a,b) ; /* or */ instr_arg alu.xor(a,b) ; /* xor*/ instr_arg multi.do(in1,in2) ; /* 乗算 */ instr_arg shift.sll(a,b) ; /* 論理左シフト */ instr_arg shift.srl(a,b) ; /* 論理右シフト */ instr_arg shift.sra(a,b) ; /* 演算右シフト */ instr_arg pc_add.add(in1,in2) ; /* pc用加算 */ instr_arg reg_file.do(a_adrs,b_adrs,w_adrs,w_data) ;/* reg-file */ instr_arg zero_check.do(data) ; /* ゼロフラグ判定 */ instr_arg cmp5a_e.do(in1,in2) ; /* 比較A(ex) */ instr_arg cmp5b_e.do(in1,in2) ; /* 比較B(ex) */ instr_arg cmp5a_m.do(in1,in2) ; /* 比較A(mem) */ instr_arg cmp5b_m.do(in1,in2) ; /* 比較B(mem) */ instr_arg cmp5a_w.do(in1,in2) ; /* 比較A(wb) */ instr_arg cmp5b_w.do(in1,in2) ; /* 比較B(wb) */ /* ステージとタスクの定義 */ stage_name start { task startt() ; } stage_name if { task ift() ; } stage_name id { task idt() ; } stage_name ex { task ext() ; } stage_name mem { task memt() ; } stage_name wb { task wbt() ; } /* モジュールの共通動作の定義 */ /*****************************************************************************/ any { ^id.idt : op_e_dist := 0b00000 ; ^ex.ext : op_m_dist := 0b00000 ; ^mem.memt : op_w_dist := 0b00000 ; } instruct reset generate start.startt() ; /* ステージの動作手順の定義 */ /******* リセット************************************************************/ stage start { any { reset : finish ; else : par { pc := 0x00000000 ; relay if.ift() ; } } } /****** 命令フェッチ(IF) ****************************************************/ stage if { par { ir := i_read(pc).ir_data ; any { ^set_pc : par { pc := pc_add.add(pc, 0x00000004).out ; } } any { reset : finish ; else : par { relay id.idt() ; generate if.ift() ; } } } } /****** 命令デコードおよびレジスタ・フェッチ(ID) ****************************/ stage id { par { /*---------------------------------------------------------*/ a_adrs = ir<25:21> ; b_adrs = ir<20:16> ; any { wb.wbt : par { w_adrs = wb_adrs ; w_data = wb_data ; } else : par { w_adrs = 0b00000 ; w_data = rslt_w ; /* dummy */ } } reg_file.do(a_adrs, b_adrs, w_adrs, w_data) ; /*------------------- フォワーディングA ----------------------*/ any { a_adrs<4> | a_adrs<3> | a_adrs<2> | a_adrs<1> | a_adrs<0> : par { cmp5a_e.do(a_adrs,op_e_dist) ; cmp5a_m.do(a_adrs,op_m_dist) ; cmp5a_w.do(a_adrs,op_w_dist) ; alt { cmp5a_e.same & ^E_LOD : a_data = e_result ; cmp5a_m.same : any { M_LOD : a_data = m_align ; else : a_data = rslt_m ; } cmp5a_w.same : a_data = wb_data ; else : a_data = reg_file.a ; } } else : a_data = reg_file.a ; /* 次の命令のデータ */ } /*------------------- フォワーディングB ----------------------*/ any { b_adrs<4> | b_adrs<3> | b_adrs<2> | b_adrs<1> | b_adrs<0> : par { cmp5b_e.do(b_adrs,op_e_dist) ; cmp5b_m.do(b_adrs,op_m_dist) ; cmp5b_w.do(b_adrs,op_w_dist) ; alt { cmp5b_e.same & ^E_LOD : b_data = e_result ; cmp5b_m.same : any { M_LOD : b_data = m_align ; else : b_data = rslt_m ; } cmp5b_w.same : b_data = wb_data ; else : b_data = reg_file.b ; } } else : b_data = reg_file.b ; /* 次の命令のデータ */ } /*---------------------------------------------------------*/ any { ALUINST : any { ADD | ADDU | SUB | SUBU | AND | OR | XOR : par { op_e := 0b001 || ir<2:0> ; op_e_dist := ir<15:11> ; a := a_data ; b := b_data ; } SLL | SRL | SRA | SLT | SGT | SLE | SGE | SEQ | SNE : par { op_e := ir<5:0> ; op_e_dist := ir<15:11> ; a := a_data ; b := b_data ; } MUL | MULU : par { op_e := 0b110 || ir<2:0> ; op_e_dist := ir<15:11> ; a := a_data ; b := b_data ; } } LB | LBU | LH | LHU | LW : par { op_e := ir<31:26> ; op_e_dist := ir<20:16> ; a := a_data ; b := 32 # ir<15:0> ; } SB | SH | SW : par { op_e := ir<31:26> ; op_e_dist := 0b00000 ; mdr_e := b_data ; a := a_data ; b := 32 # ir<15:0> ; } ADDI | ADDUI | SUBI | SUBUI | ANDI | ORI | XORI | SLLI | SRLI | SRAI | SLTI | SGTI | SLEI | SGEI | SEQI | SNEI : par { op_e := ir<31:26> ; op_e_dist := ir<20:16> ; a := a_data ; b := 32 # ir<15:0> ; } ORHI : par { op_e := ir<31:26> ; op_e_dist := ir<20:16> ; a := a_data ; b := ir<15:0> || 0x0000 ; } BEQZ : par { op_e := ir<31:26> ; op_e_dist := 0b00000 ; a := a_data ; b := 32 # ir<15:0> ; any { zero_check.do(a_data).zero : par { set_pc() ; pc := pc_add.add(pc, 32 # ir<15:0>).out ; } } } BNEZ : par { op_e := ir<31:26> ; op_e_dist := 0b00000 ; a := a_data ; b := 32 # ir<15:0> ; any { ^zero_check.do(a_data).zero : par { set_pc() ; pc := pc_add.add(pc, 32 # ir<15:0>).out ; } } } ALUINST & JR : par { op_e := 0b000 || ir<2:0> ; op_e_dist := 0b00000 ; set_pc() ; a := a_data ; b := pc_add.add(pc, 0x00000004).out ; pc := b_data ; } ALUINST & JALR : par { op_e := 0b000 || ir<2:0> ; op_e_dist := 0b00001 ; set_pc() ; a := 0x00000000 ; b := pc_add.add(pc, 0x00000004).out ; pc := b_data ; } J : par { op_e := ir<31:26> ; op_e_dist := 0b00000 ; set_pc() ; a := a_data ; b := pc_add.add(pc, 0x00000004).out ; pc := pc<31:26> || ir<25:0> ; } JAL : par { op_e := ir<31:26> ; op_e_dist := 0b00001 ; set_pc() ; a := 0x00000000 ; b := pc_add.add(pc, 0x00000004).out ; pc := pc<31:26> || ir<25:0> ; } } any { reset : finish ; else : relay ex.ext() ; } } } /****** 実行および実行アドレス生成(EX) **************************************/ stage ex { par { op_m := op_e ; op_m_dist := op_e_dist ; rslt_m := e_result ; any { E_ALU : par { any { E_ADD : e_result = alu.add(a,b).out ; E_ADDU : e_result = alu.add(a,b).out ; E_SUB : e_result = alu.sub(a,b).out ; E_SUBU : e_result = alu.sub(a,b).out ; E_AND : e_result = alu.and(a,b).out ; E_OR : e_result = alu.or(a,b).out ; E_XOR : e_result = alu.xor(a,b).out ; } } E_MD : any { E_MUL : par { mul_dust = multi.do(a,b).out ; e_result = mul_dust<31:0> ; } E_MULU : par { mul_dust = multi.do(a,b).out ; e_result = mul_dust<31:0> ; } } E_SFT : any { E_SLL : e_result = shift.sll(a,b<4:0>).out ; E_SRL : e_result = shift.srl(a,b<4:0>).out ; E_SRA : e_result = shift.sra(a,b<4:0>).out ; E_ORH : e_result = alu.or(a,b).out ; } E_SET : par { alu.sub(a,b) ; any { E_SLT : any { alu.out<31> : e_result = 0x00000001 ; else : e_result = 0x00000000 ; } E_SGT : any { ^alu.out<31> & ^alu.z : e_result = 0x00000001 ; else : e_result = 0x00000000 ; } E_SLE : any { alu.out<31> | alu.z : e_result = 0x00000001 ; else : e_result = 0x00000000 ; } E_SGE : any { ^alu.out<31> : e_result = 0x00000001 ; else : e_result = 0x00000000 ; } E_SEQ : any { alu.z : e_result = 0x00000001 ; else : e_result = 0x00000000 ; } E_SNE : any { ^alu.z : e_result = 0x00000001 ; else : e_result = 0x00000000 ; } } } E_LOD : e_result = alu.add(a,b).out ; E_BJ : e_result = alu.add(a,b).out ; E_STO : par { e_result = alu.add(a,b).out ; any { E_SB : any { ^alu.out<1> & ^alu.out<0> : par { mdr_m := mdr_e<7:0> || 0x000000 ; st_loc := 0b0001 ; } ^alu.out<1> & alu.out<0> : par { mdr_m := 0x00 || mdr_e<7:0> || 0x0000 ; st_loc := 0b0010 ; } alu.out<1> & ^alu.out<0> : par { mdr_m := 0x0000 || mdr_e<7:0> || 0x00 ; st_loc := 0b0100 ; } alu.out<1> & alu.out<0> : par { mdr_m := 0x000000 || mdr_e<7:0> ; st_loc := 0b1000 ; } } E_SH : any { ^alu.out<1> : par { mdr_m := mdr_e<15:0> || 0x0000 ; st_loc := 0b0011 ; } alu.out<1> : par { mdr_m := 0x0000 || mdr_e<15:0> ; st_loc := 0b1100 ; } } E_SW : par { mdr_m := mdr_e ; st_loc := 0b1111 ; } } } } any { reset : finish ; else : relay mem.memt() ; } } } /****** メモリ・アクセス(MEM) **********************************************/ stage mem { par { op_w := op_m ; op_w_dist := op_m_dist ; rslt_w := rslt_m ; any { M_LOD : par { o_read(rslt_m) ; any { M_LB : any { ^rslt_m<1> & ^rslt_m<0> : m_align = 32 # or_data<31:24> ; ^rslt_m<1> & rslt_m<0> : m_align = 32 # or_data<23:16> ; rslt_m<1> & ^rslt_m<0> : m_align = 32 # or_data<15:8> ; rslt_m<1> & rslt_m<0> : m_align = 32 # or_data<7:0> ; } M_LBU : any { ^rslt_m<1> & ^rslt_m<0> : m_align = 0x000000 || or_data<31:24> ; ^rslt_m<1> & rslt_m<0> : m_align = 0x000000 || or_data<23:16> ; rslt_m<1> & ^rslt_m<0> : m_align = 0x000000 || or_data<15:8> ; rslt_m<1> & rslt_m<0> : m_align = 0x000000 || or_data<7:0> ; } M_LH : any { ^rslt_m<1> : m_align = 32 # or_data<31:16> ; rslt_m<1> : m_align = 32 # or_data<15:0> ; } M_LHU : any { ^rslt_m<1> : m_align = 0x0000 || or_data<31:16> ; rslt_m<1> : m_align = 0x0000 || or_data<15:0> ; } M_LW : m_align = or_data ; } mdr_w := m_align ; } M_STO : par { o_write(rslt_m, st_loc, mdr_m) ; } } any { reset : finish ; else : relay wb.wbt() ; } } } /****** 書き込み(WB) *******************************************************/ stage wb { par { wb_adrs = op_w_dist ; any { W_LOD : wb_data = mdr_w ; else : wb_data = rslt_w ; /* dummy */ } any { ^id.idt : par { a_adrs = ir<25:21> ; /* dummy */ b_adrs = ir<20:16> ; /* dummy */ w_adrs = wb_adrs ; w_data = wb_data ; reg_file.do(a_adrs, b_adrs, w_adrs, w_data) ; } } finish ; } } }