/* 16bits Stack Machine MUSE */ %i "inc16.sfl" %i "dec16.sfl" %i "alu16.sfl" %d LADRS (ir<23:16> == 0b00000000) %d LCONST (ir<23:16> == 0b00000001) %d LOAD (ir<23:16> == 0b00000010) %d STORE (ir<23:16> == 0b00000011) %d POPUP (ir<23:16> == 0b00000100) %d CALL (ir<23:16> == 0b00000101) %d FNENT (ir<23:16> == 0b00000110) %d INCSP (ir<23:16> == 0b00000111) %d FNRET (ir<23:16> == 0b00001000) %d JUMP (ir<23:16> == 0b00001001) %d FJUMP (ir<23:16> == 0b00001010) %d TJUMP (ir<23:16> == 0b00001011) %d HALT (ir<23:16> == 0b00001100) %d NEGATE (ir<23:16> == 0b00001101) %d NOT (ir<23:16> == 0b00001110) %d COMPL (ir<23:16> == 0b00001111) %d MULT (ir<23:16> == 0b00010000) %d DIV (ir<23:16> == 0b00010001) %d MOD (ir<23:16> == 0b00010010) %d ADD (ir<23:16> == 0b00010011) %d SUB (ir<23:16> == 0b00010100) %d ANDOP (ir<23:16> == 0b00010101) %d OROP (ir<23:16> == 0b00010110) %d EQOP (ir<23:16> == 0b00010111) %d NEOP (ir<23:16> == 0b00011000) %d LEOP (ir<23:16> == 0b00011001) %d LTOP (ir<23:16> == 0b00011010) %d GEOP (ir<23:16> == 0b00011011) %d GTOP (ir<23:16> == 0b00011100) submod_class muse16 { input din<24>; output dout<16>; output ia<16>; output da<16>; instrin start; instrout imem_rd, dmem_rd, dmem_wr; } module muse16 { input din<24>; output dout<16>; output ia<16>; output da<16>; instrin start; instrout imem_rd, dmem_rd, dmem_wr; reg_wr ir<24>, dmar<16>, temp1<16>, temp2<16>, temp3<16>, temp4<16>; reg_wr ic<16>, sp<16>, fp<16>, nf; inc16 inc; dec16 dec; alu16 alu; instr_arg imem_rd(ia); instr_arg dmem_rd(da); instr_arg dmem_wr(da, dout); stage_name all { task t(); } instruct start generate all.t(); stage all { state_name fetch, exec1, exec2, exec3, exec4, exec5; segment_name mult,div; first_state fetch; state fetch par { ir := imem_rd(ic).din; ic := inc.do(ic).out; goto exec1; } state exec1 any { LADRS : par { dmem_wr(sp, alu.do(0b00, fp, ir<15:0>, 0b0).out); /* push */ sp := inc.do(sp).out; goto fetch; } LCONST : par { dmem_wr(sp, ir<15:0>); /* push */ sp := inc.do(sp).out; goto fetch; } LOAD : par { dmar := dmem_rd(dec.do(sp).out).din<15:0>; /* pop */ sp := dec.out; goto exec2; } STORE : par { temp1 := dmem_rd(dec.do(sp).out).din<15:0>; /* pop */ sp := dec.out; goto exec2; } POPUP : par { sp := dec.do(sp).out; /* pop */ goto fetch; } CALL : par { dmem_wr(sp, ic); /* push */ sp := inc.do(sp).out; goto exec2; } FNENT : par { temp1 := alu.do(0b00, ir<15:0>, 0x0002, 0b0).out; goto exec2; } INCSP : par { sp := alu.do(0b00, sp, ir<15:0>, 0b0).out; goto fetch; } FNRET : par { temp1 := dmem_rd(dec.do(sp).out).din<15:0>; /* pop */ sp := dec.out; goto exec2; } JUMP : par { ic := ir<15:0>; goto fetch; } FJUMP : par { sp := dec.out; /* pop */ any { ^(/| dmem_rd(dec.do(sp).out).din<15:0>) : par { ic := ir<15:0>; goto fetch; } else : goto fetch; } } TJUMP : par { sp := dec.out; /* pop */ any { (/| dmem_rd(dec.do(sp).out).din<15:0>) : par { ic := ir<15:0>; goto fetch; } else : goto fetch; } } HALT : finish; NEGATE : par { temp1 := alu.do(0b00, ^(dmem_rd(dec.do(sp).out).din<15:0>), 0x0001, 0b0).out; /* pop */ sp := dec.out; goto exec2; } NOT : any { (/| dmem_rd(dec.do(sp).out).din<15:0>) : par { /* pop*/ sp := dec.out; temp1 := 0x0000; goto exec2; } else : par { sp := dec.out; temp1 := 0x0001; goto exec2; } } COMPL : par { temp1 := ^(dmem_rd(dec.do(sp).out).din<15:0>); /* pop */ sp := dec.out; goto exec2; } MULT | DIV | MOD | ADD | SUB | ANDOP | OROP | EQOP | NEOP | LEOP | LTOP | GEOP | GTOP : par { temp1 := dmem_rd(dec.do(sp).out).din<15:0>; /* pop */ sp := dec.out; goto exec2; } } state exec2 any { LOAD : par { temp1 := dmem_rd(dmar).din<15:0>; goto exec3; } STORE : par { dmar := dmem_rd(dec.do(sp).out).din<15:0>; /* pop */ sp := dec.out; goto exec3; } CALL : par { dmem_wr(sp, fp); /* push */ sp := inc.do(sp).out; ic := ir<15:0>; goto fetch; } FNENT : par { fp := alu.do(0b01, sp, temp1, 0b1).out; goto fetch; } FNRET : par { sp := alu.do(0b01, sp, ir<15:0>, 0b1).out; temp2 := fp; goto exec3; } NEGATE | NOT | COMPL : par { dmem_wr(sp,temp1); /* push */ sp := inc.do(sp).out; goto fetch; } MULT : par { temp2 := dmem_rd(dec.do(sp).out).din<15:0>; /* pop */ temp3 := 0x0000; temp4 := 0x0008; call mult(exec3); sp := dec.out; } DIV | MOD : par { temp2 := dmem_rd(dec.do(sp).out).din<15:0>; /* pop */ temp3 := 0x0000; temp4 := 0x0010; call div(exec3); sp := dec.out; } ADD : par { temp1 := alu.do(0b00, dmem_rd(dec.do(sp).out).din<15:0>, temp1, 0b0).out; /* pop */ sp := dec.out; goto exec3; } SUB : par { temp1 := alu.do(0b01, dmem_rd(dec.do(sp).out).din<15:0>, temp1, 0b1).out; /* pop */ sp := dec.out; goto exec3; } ANDOP : par { temp1 := alu.do(0b10, dmem_rd(dec.do(sp).out).din<15:0>, temp1, 0b0).out; /* pop */ sp := dec.out; goto exec3; } OROP : par { temp1 := alu.do(0b11, dmem_rd(dec.do(sp).out).din<15:0>, temp1, 0b0).out; /* pop */ sp := dec.out; goto exec3; } EQOP | NEOP | LEOP | LTOP | GEOP | GTOP : par { temp1 := alu.do(0b01, dmem_rd(dec.do(sp).out).din<15:0>, temp1, 0b1).out; /* pop */ sp := dec.out; temp2 := 0x000 || 0b000 || alu.n_ou; goto exec3; } } state exec3 any { LOAD : par { dmem_wr(sp, temp1); /* push */ sp := inc.do(sp).out; goto fetch; } STORE : par { dmem_wr(dmar, temp1); goto exec4; } FNRET : par { fp := dmem_rd(dec.do(sp).out).din<15:0>; /* pop */ sp := dec.out; goto exec4; } MULT | DIV | MOD | ADD | SUB | ANDOP | OROP : par { dmem_wr(sp, temp1); /* push */ sp := inc.do(sp).out; goto fetch; } EQOP : par { any { ^(/| temp1) : dmem_wr(sp, 0x0001); /* push */ else : dmem_wr(sp, 0x0000); /* push */ } sp := inc.do(sp).out; goto fetch; } NEOP : par { any { ^(/| temp1) : dmem_wr(sp, 0x0000); /* push */ else : dmem_wr(sp, 0x0001); /* push */ } sp := inc.do(sp).out; goto fetch; } LEOP : par { any { (^(/| temp1) | (/| temp2)) : dmem_wr(sp, 0x0001); /* push */ else : dmem_wr(sp, 0x0000); /* push */ } sp := inc.do(sp).out; goto fetch; } LTOP : par { any { (/| temp2) : dmem_wr(sp, 0x0001); /* push */ else : dmem_wr(sp, 0x0000); /* push */ } sp := inc.do(sp).out; goto fetch; } GEOP : par { any { (^(/| temp1) | ^(/| temp2)) : dmem_wr(sp, 0x0001); /* push */ else : dmem_wr(sp, 0x0000); /* push */ } sp := inc.do(sp).out; goto fetch; } GTOP : par { any { ^(/| temp2) & (/|temp1) : dmem_wr(sp, 0x0001); /* push */ else : dmem_wr(sp, 0x0000); /* push */ } sp := inc.do(sp).out; goto fetch; } } state exec4 any { STORE : par { dmem_wr(sp, temp1); /* push */ sp := inc.do(sp).out; goto fetch; } FNRET : par { ic := dmem_rd(dec.do(sp).out).din<15:0>; /* pop */ sp := temp2; goto exec5; } } state exec5 any { FNRET : par { dmem_wr(sp, temp1); /* push */ sp := inc.do(sp).out; goto fetch; } } /* Multiplier */ segment mult { state_name s1, s2; first_state s1; state s1 par { any { ^(/| temp4) : par { temp1 := temp3<7:0> || temp2<7:0>; return; } else : any { temp2<0> : par { temp3 := alu.do(0b00, temp3, temp1, 0b0).out; goto s2; } else : goto s2; } } } state s2 par { temp2 := 0x00 || temp3<0> || temp2<7:1>; temp3 := 0x00 || 0b0 || temp3<7:1>; temp4 := dec.do(temp4).out; goto s1; } } /* Divider */ segment div { state_name s1, s2, s3; first_state s1; state s1 par { any { ^(/| temp4) : par { any { MOD : temp1 := temp3; DIV : temp1 := temp2; } return; } else : par { temp3 := temp3<14:0> || temp2<15>; goto s2; } } } state s2 par { temp3 := alu.do(0b01, temp3, temp1, 0b1).out; nf := alu.out<15>; goto s3; } state s3 par { any { nf : par { temp2 := temp2<14:0> || 0b0; temp3 := alu.do(0b00, temp3, temp1, 0b0).out; } else : temp2 := temp2<14:0> || 0b1; } temp4 := dec.do(temp4).out; goto s1; } } } }