%i "acc.sfl" %i "alu.sfl" %i "ir.sfl" %i "pc.sfl" %i "sp.sfl" submod_class acc { input in<8> ; output out<8> ; instrin load ; instrin hold ; instrin reset ; instr_arg load(in) ; instr_arg hold() ; instr_arg reset() ; } submod_class alu { input a<8> ; input b<8> ; output out<8> ; output zero ; instrin trans_a ; instrin trans_b ; instrin add ; instrin and ; instrin xor ; instr_arg trans_a(a) ; instr_arg trans_b(b) ; instr_arg add(a,b) ; instr_arg and(a,b) ; instr_arg xor(a,b) ; } submod_class ir { input in<8> ; output out<8> ; instrin load ; instrin hold ; instrin reset ; instr_arg load(in) ; instr_arg hold() ; instr_arg reset() ; } submod_class pc { input in<8> ; output out<8> ; instrin load ; instrin inc ; instrin hold ; instrin reset ; instr_arg load(in) ; instr_arg hold() ; instr_arg inc() ; instr_arg reset() ; } submod_class sp { output out<8> ; instrin dec ; instrin inc ; instrin reset ; instrin hold ; instr_arg dec() ; instr_arg inc() ; instr_arg reset() ; instr_arg hold() ; } module inside { input in_data<8> ; output out_data<8> ; output address<8> ; tmp oprand<8> ; tmp opcode<8> ; tmp pc_out<8> ; tmp alu_out<8> ; tmp acc_out<8> ; tmp sp_out<8> ; /* */ output acc_a<8>,pc_a<8>,sp_a<8> ; instrin reset ; instrin start ; instrout read ; instrout write ; acc acc0 ; alu alu0 ; ir ir0,ir1 ; pc pc0 ; sp sp0 ; stage_name fetch_exec { task run() ; } instruct reset par { /* reset registers */ acc_out = acc0.reset().out ; pc_out = pc0.reset().out ; sp_out = sp0.reset().out ; ir0.reset() ; ir1.reset() ; /* read mode for RAM */ read() ; /* drive output terminals */ alu_out = alu0.trans_a(in_data).out ; out_data = alu_out ; address = pc_out ; /* for monitoring */ /* */ acc_a = acc_out ; pc_a = pc_out ; sp_a = sp_out ; } instruct start generate fetch_exec.run() ; stage fetch_exec { state_name fetch0 ; state_name fetch1 ; state_name exec ; first_state fetch0 ; state fetch0 /* instruction fetch state phase I */ par { /* increment program counter for next instruction */ pc_out = pc0.inc().out ; acc_out = acc0.hold().out ; sp_out = sp0.hold().out ; alu_out = alu0.trans_a(in_data).out ; /* drive output terminals */ address = pc_out ; out_data = alu_out ; /* read mode for RAM */ read() ; /* load instruction register from RAM */ ir0.load(in_data) ; /* for monitoring */ /* */ acc_a = acc_out ; pc_a = pc_out ; sp_a = sp_out ; goto fetch1 ; } state fetch1 /* instruction fetch state phase II */ par { /* increment program counter for next instruction */ pc_out = pc0.inc().out ; acc_out = acc0.hold().out ; sp_out = sp0.hold().out ; alu_out = alu0.trans_a(in_data).out ; /* drive output terminals */ address = pc_out ; out_data = alu_out ; /* read mode for RAM */ read() ; /* load instruction register from RAM */ ir1.load(in_data) ; /* for monitoring */ /* */ acc_a = acc_out ; pc_a = pc_out ; sp_a = sp_out ; goto exec ; } state exec /* execution stage */ par { opcode = ir0.hold().out ; oprand = ir1.hold().out ; /* drive output terminals */ /* for monitoring */ /* */ acc_a = acc_out ; pc_a = pc_out ; sp_a = sp_out ; /* instruction set */ any { opcode == 0b00000000 : /* load acc */ par { read() ; alu_out = alu0.trans_a(in_data).out ; acc_out = acc0.load(alu_out).out ; pc_out = pc0.hold().out ; sp_out = sp0.hold().out ; out_data = alu_out ; address = oprand ; } opcode == 0b00000001 : /* add acc */ par { read() ; alu_out = alu0.add(in_data,acc_out).out ; acc_out = acc0.load(alu_out).out ; pc_out = pc0.hold().out ; sp_out = sp0.hold().out ; out_data = alu_out ; address = oprand ; } opcode == 0b00000010 : /* jump */ par { read() ; pc0.load(oprand) ; alu_out = alu0.trans_a(in_data).out ; pc_out = pc0.hold().out ; acc_out = acc0.hold().out ; sp_out = sp0.hold().out ; out_data = alu_out ; address = oprand ; } opcode == 0b00000011 : par { read() ; alu_out = alu0.trans_a(in_data).out ; pc_out = pc0.hold().out ; acc_out = acc0.hold().out ; sp_out = sp0.hold().out ; out_data = alu_out ; address = oprand ; } opcode == 0b00000100 : par { read() ; alu_out = alu0.trans_a(in_data).out ; pc_out = pc0.hold().out ; acc_out = acc0.hold().out ; sp_out = sp0.hold().out ; out_data = alu_out ; address = oprand ; } opcode == 0b00000101 : par { read() ; alu_out = alu0.trans_a(in_data).out ; pc_out = pc0.hold().out ; acc_out = acc0.hold().out ; sp_out = sp0.hold().out ; out_data = alu_out ; address = oprand ; } opcode == 0b00000110 : par { read() ; alu_out = alu0.trans_a(in_data).out ; pc_out = pc0.hold().out ; acc_out = acc0.hold().out ; sp_out = sp0.hold().out ; out_data = alu_out ; address = oprand ; } opcode == 0b00000111 : par { read() ; alu_out = alu0.trans_a(in_data).out ; pc_out = pc0.hold().out ; acc_out = acc0.hold().out ; sp_out = sp0.hold().out ; out_data = alu_out ; address = oprand ; } opcode == 0b10000000 : /* push */ par { write() ; alu_out = alu0.trans_a(in_data).out ; pc_out = pc0.hold().out ; acc_out = acc0.hold().out ; sp_out = sp0.dec().out ; out_data = pc_out ; address = sp_out ; } opcode == 0b10000001 : /* pop */ par { read() ; alu_out = alu0.trans_a(in_data).out ; pc_out = pc0.load(in_data).out ; acc_out = acc0.hold().out ; sp_out = sp0.inc().out ; out_data = alu_out ; address = sp_out ; } } /* for the next instruction */ goto fetch0 ; } } }