/******************** MODULE INFO ****************************/ /* * File name : data11.sfl * * AUTHOR : Yoshihiro Iida (3aepm001@keyaki.cc.u-tokai.ac.jp) * VERSION : 1.0 * DATE : Oct 16, 2003 * * Compiler : sfl2vl * Project : POP-11: PDP-11 compatible On Programmable chip * Functions : Datapath of POP-11 * * Copyright (c) Yoshihiro Iida, Tokai University, Shimizu Lab., Japan. (http://shimizu-lab.dt.u-tokai.ac.jp) This software is the property of Tokai University, Shimizu Lab., Japan. The POP-11 is free set of files; you can use it, redistribute it and/or modify it under the following terms: 1. You are not allowed to remove or modify this copyright notice and License paragraphs, even if parts of the software is used. 2. The improvements and/or extentions you make SHALL be available for the community under THIS license, source code included. Improvements or extentions, including adaptions to new architectures/languages, SHALL be reported and transmitted to Tokai University, Shimizu Lab., Japan. 3. You must cause the modified files to carry prominent notices stating that you changed the files, what you did and the date of changes. 4. You may NOT distribute this set of files under another license without explisit permission from Tokai University, Shimizu Lab., Japan. 5. This set of files is free, and distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. You SHALL NOT use this software unless you accept to carry all risk and cost of defects or limitations. * * ------------ CHANGE RECORD ---------------- * Yoshihiro Iida (3aepm001@keyaki.cc.u-tokai.ac.jp) Sep 21, 2004: * First free version of this software published. * */ %i "define.sfl" %i "alu11.sfl" declare data11 { input dbi<16>; output dbo<16>, dba<16>, opc<16>, psw<16>; instrin inc2, dec2, inc, dec, clr, com, neg, adc, sbc, tst, ror, rol, asr, asl, sxt, mov, cmp, bit, bic, bis, add, sub, exor, swab, mmu; instrin setopc, dbiDst, dbiSrc, dbiPC, dbiReg, dbiPS, dbaPC, dbaSP, dbaDst, dbaSrc, dbaAdr, dboSEL, dboDst, dboSrc, dboAdr, pcALU1, spALU1, dstALU1, srcALU1, dstALU2, srcALU2, adrALU1, ofs8ALU2, ofs6ALU2, selALU1, regSEL, regSEL2, setReg, setReg2, ALUreg, DSTreg, PCreg, SRCreg, ADRreg, ALUpc, ALUsp, ALUdst, ALUdstb, ALUsrc, ALUcc, SELdst, SELsrc, SELadr, SELpc, DSTadr, SRCadr, adrPC, save_stat, FPpc, dbiFP, setPCrom; instrin change_opr, change_mode, kernel_mode, reset_byte, vectorPS; instrin ccclr, ccset, cctaken; instrin buserr, err, bpt, emt, iot, svc, segerr; instrin spl, ccget; instrin clrADR, oddReg, mul, ash, ashc; instrin div, div_end, div_ini0, div_ini1, div_ini2, div_fin0, div_fin1, tstSRC, tstSRCADR; instrout ashdone; output alucc<4>; output taken; } module data11 { input dbi<16>; output dbo<16>, dba<16>, opc<16>, psw<16>; instrin inc2, dec2, inc, dec, clr, com, neg, adc, sbc, tst, ror, rol, asr, asl, sxt, mov, cmp, bit, bic, bis, add, sub, exor, swab, mmu; instrin setopc, dbiDst, dbiSrc, dbiPC, dbiReg, dbiPS, dbaPC, dbaSP, dbaDst, dbaSrc, dbaAdr, dboSEL, dboDst, dboSrc, dboAdr, pcALU1, spALU1, dstALU1, srcALU1, dstALU2, srcALU2, adrALU1, ofs8ALU2, ofs6ALU2, selALU1, regSEL, regSEL2, setReg, setReg2, ALUreg, DSTreg, PCreg, SRCreg, ADRreg, ALUpc, ALUsp, ALUdst, ALUdstb, ALUsrc, ALUcc, SELdst, SELsrc, SELadr, SELpc, DSTadr, SRCadr, adrPC, save_stat, FPpc, dbiFP, setPCrom; instrin change_opr, change_mode, kernel_mode, reset_byte, vectorPS; instrin ccclr, ccset, cctaken; instrin buserr, err, bpt, emt, iot, svc, segerr; instrin spl, ccget; instrin clrADR, oddReg, mul, ash, ashc; instrin div, div_end, div_ini0, div_ini1, div_ini2, div_fin0, div_fin1, tstSRC, tstSRCADR; instrout ashdone; output alucc<4>; output taken; reg_wr PC<16>; reg_wr R0<16>, R1<16>, R2<16>, R3<16>, R4<16>, R5<16>; reg_wr kSP<16>, uSP<16>; reg_wr OPC_BYTE, OPC<15>, SRC<16>, DST<16>, ADR<16>; reg_wr cmode<2>, pmode<2>, priority<3>, trapbit, fn, fz, fv, fc; reg_wr multmp, dividen, divider; sel ALU1<16>, ALU2<16>, REGsel<16>, REGin<16>, mul_HI<16>; alu11 alu; par { opc = OPC_BYTE || OPC; psw = cmode||pmode||(0x0)||priority||trapbit||fn||fz||fv||fc; alu.ni = fn; alu.ci = fc; alu.bi = OPC_BYTE; } instruct setPCrom PC := 0xe000; instruct spl priority := OPC<2:0>; instruct ALUcc any { alu.ccmask<3>: fn := alu.ccout<3>; alu.ccmask<2>: fz := alu.ccout<2>; alu.ccmask<1>: fv := alu.ccout<1>; alu.ccmask<0>: fc := alu.ccout<0>; } instruct ccget alucc = alu.ccout; instruct ccset any { OPC<3>: fn := OPC<4>; OPC<2>: fz := OPC<4>; OPC<1>: fv := OPC<4>; OPC<0>: fc := OPC<4>; } instruct cctaken taken = ( ((OPC_BYTE||OPC<10:9>)==0o0) )| ( ((OPC_BYTE||OPC<10:9>)==0o1) & (^OPC<8> @ fz ) )| ( ((OPC_BYTE||OPC<10:9>)==0o2) & (^OPC<8> @ (fn@fv) ) )| ( ((OPC_BYTE||OPC<10:9>)==0o3) & (^OPC<8> @ ((fn@fv)|fz) ) )| ( ((OPC_BYTE||OPC<10:9>)==0o4) & (^OPC<8> @ fn ) )| ( ((OPC_BYTE||OPC<10:9>)==0o5) & (^OPC<8> @ (fc|fz) ) )| ( ((OPC_BYTE||OPC<10:9>)==0o6) & (^OPC<8> @ fv ) )| ( ((OPC_BYTE||OPC<10:9>)==0o7) & (^OPC<8> @ fc ) ); instruct setopc par { OPC_BYTE := dbi<15>; OPC := dbi<14:00>; } instruct dbiDst DST := dbi; instruct dbiSrc SRC := dbi; instruct dbiPC PC := dbi; instruct dbiFP R5 := dbi; instruct dbiReg REGin = dbi; instruct dbiPS par { cmode := dbi<15:14>; pmode := dbi<13:12>; priority := dbi<7:5>; trapbit := dbi<4>; fn := dbi<3>; fz := dbi<2>; fv := dbi<1>; fc := dbi<0>; } instruct vectorPS par { priority := dbi<7:5>; trapbit := dbi<4>; fn := dbi<3>; fz := dbi<2>; fv := dbi<1>; fc := dbi<0>; } instruct save_stat par { DST := cmode||pmode||(0x0)||priority||trapbit||fn||fz||fv||fc; ADR := PC; } instruct dbaPC dba = PC; instruct dbaSP any { (^/|cmode): dba = kSP; ( /&cmode): dba = uSP; } instruct dbaDst dba = DST; instruct dbaSrc dba = SRC; instruct dbaAdr dba = ADR; instruct dboSEL dbo = REGsel; instruct dboDst dbo = DST; instruct dboSrc dbo = SRC; instruct dboAdr dbo = ADR; instruct pcALU1 ALU1 = PC; instruct spALU1 any { (^/|cmode): ALU1 = kSP; ( /&cmode): ALU1 = uSP; } instruct dstALU1 ALU1 = DST; instruct srcALU1 ALU1 = SRC; instruct adrALU1 ALU1 = ADR; instruct dstALU2 ALU2 = DST; instruct srcALU2 ALU2 = SRC; instruct ofs8ALU2 ALU2 = 7#opc<7> || opc<7:0> || 0b0 ; instruct ofs6ALU2 ALU2 = 0x00 || (0b0 || opc<5:0> || 0b0); instruct selALU1 ALU1 = REGsel; instruct regSEL any { OPC<2:0> == 0o0: REGsel = R0; OPC<2:0> == 0o1: REGsel = R1; OPC<2:0> == 0o2: REGsel = R2; OPC<2:0> == 0o3: REGsel = R3; OPC<2:0> == 0o4: REGsel = R4; OPC<2:0> == 0o5: REGsel = R5; OPC<2:0> == 0o7: REGsel = PC; ((OPC<2:0> == 0o6) &^/|cmode): REGsel = kSP; ((OPC<2:0> == 0o6) & /&cmode): REGsel = uSP; } instruct regSEL2 any { OPC<8:6> == 0o0: REGsel = R0; OPC<8:6> == 0o1: REGsel = R1; OPC<8:6> == 0o2: REGsel = R2; OPC<8:6> == 0o3: REGsel = R3; OPC<8:6> == 0o4: REGsel = R4; OPC<8:6> == 0o5: REGsel = R5; OPC<8:6> == 0o7: REGsel = PC; ((OPC<8:6> == 0o6) &^/|cmode): REGsel = kSP; ((OPC<8:6> == 0o6) & /&cmode): REGsel = uSP; } instruct setReg any { OPC<2:0> == 0o0: R0 := REGin; OPC<2:0> == 0o1: R1 := REGin; OPC<2:0> == 0o2: R2 := REGin; OPC<2:0> == 0o3: R3 := REGin; OPC<2:0> == 0o4: R4 := REGin; OPC<2:0> == 0o5: R5 := REGin; OPC<2:0> == 0o7: PC := REGin; ((OPC<2:0> == 0o6) &^/|cmode): kSP := REGin; ((OPC<2:0> == 0o6) & /&cmode): uSP := REGin; } instruct setReg2 any { OPC<8:6> == 0o0: R0 := REGin; OPC<8:6> == 0o1: R1 := REGin; OPC<8:6> == 0o2: R2 := REGin; OPC<8:6> == 0o3: R3 := REGin; OPC<8:6> == 0o4: R4 := REGin; OPC<8:6> == 0o5: R5 := REGin; OPC<8:6> == 0o7: PC := REGin; ((OPC<8:6> == 0o6) &^/|cmode): kSP := REGin; ((OPC<8:6> == 0o6) & /&cmode): uSP := REGin; } instruct ALUreg REGin = alu.out; instruct DSTreg REGin = DST; instruct SRCreg REGin = SRC; instruct ADRreg REGin = ADR; instruct PCreg REGin = PC; instruct FPpc PC := R5; instruct ALUpc PC := alu.out; instruct ALUsp any { (^/|cmode): kSP := alu.out; ( /&cmode): uSP := alu.out; } instruct ALUdst DST := alu.out; instruct ALUdstb any { ( OPC_BYTE): DST := DST<15:8> || alu.out<7:0>; (^OPC_BYTE): DST := alu.out; } instruct ALUsrc SRC := alu.out; instruct SELdst DST := REGsel; instruct SELsrc SRC := REGsel; instruct SELadr ADR := REGsel; instruct SELpc PC := REGsel; instruct DSTadr ADR := DST; instruct SRCadr ADR := SRC; instruct adrPC PC := ADR; instruct reset_byte OPC_BYTE := 0b0; instruct change_opr OPC := OPC<14:12> || OPC<5:0> || OPC<11:06>; instruct change_mode par { pmode := cmode; cmode := pmode; } instruct kernel_mode par { cmode := 0b00; pmode := cmode; } instruct buserr SRC := TRAP_BUS; instruct segerr SRC := TRAP_SEG; instruct err SRC := TRAP_ERR; instruct bpt SRC := TRAP_BPT; instruct emt SRC := TRAP_EMT; instruct iot SRC := TRAP_IOT; instruct svc SRC := TRAP_SVC; instruct inc2 alu.inc2(ALU1); instruct dec2 alu.dec2(ALU1); instruct inc alu.inc(ALU1); instruct dec alu.dec(ALU1); instruct clr alu.clr(ALU1); instruct com alu.com(ALU1); instruct neg alu.neg(ALU1); instruct adc alu.adc(ALU1); instruct sbc alu.sbc(ALU1); instruct tst alu.tst(ALU1); instruct mmu alu.mmu(ALU1); instruct ror alu.ror(ALU1); instruct rol alu.rol(ALU1); instruct asr alu.asr(ALU1); instruct asl alu.asl(ALU1); instruct sxt alu.sxt(ALU1); instruct mov alu.mov(ALU1); instruct cmp alu.cmp(ALU1,ALU2); instruct bit alu.bit(ALU1,ALU2); instruct bic alu.bic(ALU1,ALU2); instruct bis alu.bis(ALU1,ALU2); instruct add alu.add(ALU1,ALU2); instruct exor alu.exor(ALU1,ALU2); instruct swab alu.swab(ALU1); instruct sub alu.sub(ALU1,ALU2); instruct oddReg OPC := OPC<14:07>||^OPC<6>||OPC<5:0>; instruct clrADR par { ADR := 0x0000; multmp := 0b0; } instruct tstSRC par { fn := SRC<15>; fz := ^/|SRC; } instruct tstSRCADR par { fz := ^/|(ADR||SRC); } instruct mul par { any { (SRC<0>||multmp) == 0b00: mul_HI = ADR; (SRC<0>||multmp) == 0b01: mul_HI = alu.add(ADR,DST).out; (SRC<0>||multmp) == 0b10: mul_HI = alu.sub(ADR,DST).out; (SRC<0>||multmp) == 0b11: mul_HI = ADR; } multmp := SRC<0>; SRC := mul_HI<0>||SRC<15:01>; ADR := mul_HI<15>||mul_HI<15:01>; fn := mul_HI<15>; fc := ^(/&mul_HI<15:1> | ^/|mul_HI<15:1>); fv := 0b0; } instruct div_ini0 par { divider := DST<15>; if(DST<15>) DST := alu.neg(DST).out; if(^DST<15>) par { alu.tst(DST); if(^alu.ccout<2>) par { fc := 0b0; fv := 0b0; } if( alu.ccout<2>) par { fc := 0b1; fv := 0b1; } } } instruct div_ini1 par { if(SRC<15>) ADR := alu.neg(ADR).out; dividen := SRC<15>; fv := alu.ccout<2>; /* dividen negate borrow */ } instruct div_ini2 any { dividen & fv: SRC := alu.neg(SRC).out; dividen &^fv: SRC := alu.com(SRC).out; } instruct div_fin0 any { (^dividen & divider)| ( dividen &^divider): SRC := alu.neg(SRC).out; } instruct div_fin1 any { ( dividen &^divider)| ( dividen & divider): ADR := alu.neg(ADR).out; } instruct div par { alu.sub(SRC,DST); if(alu.out<15>) par { if(^div_end) SRC := SRC<14:0>||ADR<15>; if( div_end) fv := /|ADR<15:14>; ADR := ADR<14:0>||0b0; } if(^alu.out<15>) par { if(^div_end) SRC := alu.out<14:0>||ADR<15>; if( div_end) SRC := alu.out; if( div_end) fv := /|ADR<15>; ADR := ADR<14:0>||0b1; /* fv := /|(alu.out||ADR<15>); */ } } instruct ash any { (DST<5:0> == 0o00): ashdone(); ^(DST<5:0> == 0o00): any { DST<5>: par { DST := alu.inc(DST).out; SRC := SRC<15>||SRC<15:01>; fc := SRC<0>; fv := SRC<15>@SRC<14>; } ^DST<5>: par { DST := alu.dec(DST).out; SRC := SRC<14:00>||0b0; fc := SRC<15>; fv := SRC<15>@SRC<14>; } } } instruct ashc any { (DST<5:0> == 0o00): ashdone(); ^(DST<5:0> == 0o00): any { DST<5>: par { DST := alu.inc(DST).out; SRC := SRC<15>||SRC<15:01>; ADR := SRC<00>||ADR<15:01>; fc := ADR<0>; fn := SRC<15>; fv := SRC<15>@SRC<14>; } ^DST<5>: par { DST := alu.dec(DST).out; SRC := SRC<14:00>||ADR<15>; ADR := ADR<14:00>||0b0; fc := SRC<15>; fn := SRC<14>; fv := SRC<15>@SRC<14>; } } } }