/*********************** * pico16.sfl * ***********************/ %d INTAD 0x00a0 /* Ope-code IR15-11 */ %d ROP 0b00000 /* Register Type operation */ %d NOP 0b00000 /* NOP */ %d LDLI 0b11100 %d LDHI 0b11101 %d BNEZ 0b01001 %d BEQZ 0b01010 %d BMI 0b01011 %d BPL 0b01100 %d JMP 0b01111 %d JAL 0b01101 %d JALR 0b01000 %d JR 0b01110 %d ANDI 0b00010 %d ORI 0b00011 %d XORI 0b00100 %d NOPCODE 0x0000 /* Ope-code IR 4-0 */ %d LD 0b01000 %d ST 0b01001 %d EINT 0b10001 %d DINT 0b10100 %d LIAR 0b10010 %d SIAR 0b10011 %d RFI 0b10000 /**** Module declaration ****/ declare if { input idata<16>, pcset, pcbra<16>, rfiar<16>, int_req, intrtn, inten, intdis, iarset; output ifpc<16>, ifir<16>, ifiar<16>; instrin enable; instr_arg enable(idata, pcset, pcbra, rfiar, int_req, intrtn, inten, intdis, iarset); } declare rf { input ifir<16>, ifpc<16>, rwe, rwen, c<16>, rwadr<3>, fdata<16>, ifiar<16>; output rfir<16>, rfpc<16>, a<16>, b<16>, imm<16>, badr<16>, rfiar<16>; instrout pcset, intrtn, inten, intdis, iarset; instrin enable; instr_arg enable(ifir, ifpc, rwe, rwen, rwadr, c, fdata, ifiar); } declare ex { input rfir<16>, rfpc<16>, rfim<16>, a<16>, b<16>, ddatain<16>; output c<16>, ddataout<16>, address<16>, rwadr<3>, fdata<16>; instrin enable; instrout dmoe, dmwe, rwen ; instr_arg enable(rfir, rfpc, rfim, a, b, ddatain); } declare wb { input rwen; output rwe; instrin enable; instr_arg enable(rwen); } declare regfile { input addr1<3>, addr2<3>, addr3<3>, din<16>, we; output dout1<16>, dout2<16>; instrin enable; instr_arg enable(addr1, addr2, addr3, din, we); } declare alu16 { input ina<16>, inb<16>, com<4>; output y<16>; instrin enable; instr_arg enable(ina, inb, com); } declare addsub16 { input ina<16>, inb<16>, sel; output sumdiff<16> ; instrin enable; instr_arg enable(ina, inb, sel); } declare add16 { input a<16>, b<16>, ci; output y<16>, co; instrin enable; instr_arg enable(a, b, ci); } declare cla4 { input a<4>, b<4>, ci; output y<4>, co, go, po; instrin enable; instr_arg enable(a,b,ci); } declare lcg4 { input g<4>, p<4>, ci; output c0, c1, c2, go, po; instrin enable; instr_arg enable(g,p,ci); } /**** Modules ****/ module ppico16 { input idata<16>, ddatain<16>, int_req; output iaddr<16>, daddr<16>, ddataout<16>; output dmoe, dmwe; instrin enable; if IFETCH; rf RFETCH; ex EXEC; wb WBACK; sel_v pcset, pcbra<16>, ifir<16>, ifpc<16>; sel_v a<16>, b<16>, c<16>; sel_v rwe, rwen, rfir<16>, rfpc<16>, rfim<16>, rwadr<3>, fdata<16> ; sel_v badr<16>, ifiar<16>, rfiar<16>; sel_v intrtn, inten, intdis, iarset; instruct enable par { IFETCH.enable(idata, pcset, badr, rfiar, int_req, intrtn, inten, intdis, iarset); RFETCH.enable(ifir, ifpc, rwe, rwen, rwadr, c, fdata, ifiar); EXEC.enable(rfir, rfpc, rfim, a, b, ddatain); WBACK.enable(rwen); iaddr = IFETCH.ifpc; ifpc = IFETCH.ifpc; ifir = IFETCH.ifir; ifiar = IFETCH.ifiar; rfir = RFETCH.rfir; rfpc = RFETCH.rfpc; a = RFETCH.a; b = RFETCH.b; rfim = RFETCH.imm; pcset = RFETCH.pcset; badr = RFETCH.badr; intrtn = RFETCH.intrtn; inten = RFETCH.inten; intdis = RFETCH.intdis; iarset = RFETCH.iarset; rfiar = RFETCH.rfiar; c = EXEC.c; rwen = EXEC.rwen; rwadr = EXEC.rwadr; dmoe = EXEC.dmoe; dmwe = EXEC.dmwe; daddr = EXEC.address; ddataout = EXEC.ddataout; fdata = EXEC.fdata; rwe = WBACK.rwe; } } /**** Instuction Fetch ****/ module if { input idata<16>, pcset, pcbra<16>, rfiar<16>, int_req, intrtn, inten, intdis, iarset; output ifpc<16>, ifir<16>, ifiar<16>; instrin enable; add16 PCINC; sel_v pctmp<16>; reg_wr pc<16>, ir<16>, iar<16>, ienable; instruct enable par { ifir = ir; ifpc = pc; ifiar = iar; alt { pcset: par { pc := pcbra; ir := idata; } else: alt { intrtn: par { pc := iar; ir := idata; ienable := 0b1; } else: alt { (ienable & int_req): par { iar := pc; pc := INTAD; ir := NOPCODE; ienable := 0b0; } else: par { pc := PCINC.enable(pc, 0x0002, 0b0).y; ir := idata; alt {iarset: iar := rfiar;} alt { inten: ienable := 0b1; intdis: ienable := 0b0; } } } } } } } /**** Register Fetch ****/ module rf { input ifir<16>, ifpc<16>, rwe, rwen, c<16>, rwadr<3>, fdata<16>, ifiar<16>; output rfir<16>, rfpc<16>, a<16>, b<16>, imm<16>, badr<16>, rfiar<16>; instrout pcset, intrtn, inten, intdis, iarset; instrin enable; regfile REG; add16 BADDER; reg_wr reg_ir<16>; reg_wr reg_a<16>, reg_b<16>, reg_im<16>, reg_pc<16>; sel_v frega<16>, fregb<16>; instruct enable par { a = reg_a; b = reg_b; imm = reg_im; rfpc = reg_pc; rfir = reg_ir; reg_pc := ifpc; REG.enable(ifir<10:8>, ifir<7:5>, rwadr, c, rwe); reg_a := frega; rfiar = fregb; alt { rwen & ^/|(rfir<10:8> @ ifir<10:8>): frega = fdata; else : frega = REG.dout1; } alt { rwen & ^/|(rfir<10:8> @ ifir<7:5>) : fregb = fdata; else : fregb = REG.dout2; } alt { (ifir<15:11> == JMP) | (ifir<15:11> == JAL): badr = BADDER.enable(ifpc,16#ifir<10:0>,0b0).y; (ifir<15:11> == JALR) | (ifir<15:11> == JR) : badr = frega; else : badr = BADDER.enable(ifpc,16#ifir<7:0>,0b0).y; } alt { (ifir<15:11> == JAL) | (ifir<15:11> == JALR): par { reg_b := ifpc; reg_ir := 0x0701; } ifir<15:11> == ROP : alt { ifir<4:0> == LIAR : par { reg_b := ifiar; reg_ir := ROP||ifir<10:8>||0x01; } else: par { reg_b := fregb; reg_ir := ifir;} } else : par { reg_b := fregb; reg_ir := ifir;} } alt { (ifir<15:11> == BEQZ) & ^/|frega : pcset(); (ifir<15:11> == BNEZ) & /|frega : pcset(); (ifir<15:11> == BMI) & frega<15> : pcset(); (ifir<15:11> == BPL) & ^frega<15> : pcset(); (ifir<15:11> == JMP) | (ifir<15:11> == JR) | (ifir<15:11> == JAL) | (ifir<15:11> == JALR) : pcset(); } alt { ifir<15:11> == ROP : alt{ ifir<4:0> == RFI : intrtn(); ifir<4:0> == EINT : inten(); ifir<4:0> == DINT : intdis(); ifir<4:0> == SIAR : iarset(); } } alt { ifir<15:11> == ANDI : reg_im := 0xff||ifir<7:0>; (ifir<15:11> == ORI)|(ifir<15:11> == XORI): reg_im := 0x00||ifir<7:0>; else : reg_im := 16#ifir<7:0>; } } } /**** Exection ****/ module ex { input rfir<16>, rfpc<16>, rfim<16>, a<16>, b<16>, ddatain<16>; output c<16>, ddataout<16>, address<16>, rwadr<3>, fdata<16>; instrin enable; instrout dmoe, dmwe, rwen ; alu16 ALU; reg reg_c<16>, reg_rwadr<3>; instruct enable par { c = reg_c; ddataout = b; rwadr = reg_rwadr; reg_rwadr := rfir<10:8>; alt{ (rfir<15:11> == ROP) & (rfir<4:0> == ST) : address = a; else : address = b; } alt{ rfir<15:11> == ROP: alt { /* R type functions */ rfir<4:0> == LD: par { /* LD */ dmoe(); rwen(); fdata = ddatain; reg_c := fdata; } rfir<4:0> == ST: dmwe(); /* ST */ else: par { /* ALU instructions */ fdata = ALU.enable(a,b,rfir<3:0>).y; reg_c := fdata; alt { /|rfir<4:0>: rwen(); } } } rfir<15:11> == LDLI: par { /* LDLI */ fdata = 16#rfir<7:0>; reg_c := fdata; rwen(); } rfir<15:11> == LDHI: par { /* LDHI */ fdata = rfir<7:0>||0x00; reg_c := fdata; rwen(); } rfir<15:14> == 0b00: par { /* ALU instructions */ fdata = ALU.enable(a,rfim,rfir<14:11>).y; reg_c := ALU.y; rwen(); } else: par { fdata = NOPCODE; reg_c := fdata; } } } } module wb { input rwen ; output rwe ; instrin enable; reg_wr rwe_reg; instruct enable par{ rwe = rwe_reg; rwe_reg:= rwen; } } /**** register file with two output ports ****/ module regfile { input addr1<3>, addr2<3>, addr3<3>, din<16>, we; output dout1<16>, dout2<16>; instrin enable; reg register0<16>, register1<16>, register2<16>; reg register3<16>, register4<16>, register5<16>; reg register6<16>, register7<16>; instruct enable par { alt{ we & ^/|(addr1 @ addr3): dout1 = din; addr1 == 0b000: dout1 = register0; addr1 == 0b001: dout1 = register1; addr1 == 0b010: dout1 = register2; addr1 == 0b011: dout1 = register3; addr1 == 0b100: dout1 = register4; addr1 == 0b101: dout1 = register5; addr1 == 0b110: dout1 = register6; addr1 == 0b111: dout1 = register7; } alt{ we & ^/|(addr2 @ addr3): dout2 = din; addr2 == 0b000: dout2 = register0; addr2 == 0b001: dout2 = register1; addr2 == 0b010: dout2 = register2; addr2 == 0b011: dout2 = register3; addr2 == 0b100: dout2 = register4; addr2 == 0b101: dout2 = register5; addr2 == 0b110: dout2 = register6; addr2 == 0b111: dout2 = register7; } alt { we & addr3 == 0b000: register0 := din; we & addr3 == 0b001: register1 := din; we & addr3 == 0b010: register2 := din; we & addr3 == 0b011: register3 := din; we & addr3 == 0b100: register4 := din; we & addr3 == 0b101: register5 := din; we & addr3 == 0b110: register6 := din; we & addr3 == 0b111: register7 := din; } } } /**** alu16 ****/ module alu16 { input ina<16>, inb<16>, com<4>; output y<16>; instrin enable; addsub16 as16; /* 16bit adder */ instruct enable alt { com == 0b0000: y = ina; /* Through A */ com == 0b0001: y = inb; /* Through B */ com == 0b0010: y = ina & inb; /* A and B */ com == 0b0011: y = ina | inb; /* A or B */ com == 0b0100: y = ina @ inb; /* A xor B */ com == 0b0101: y = ^inb; /* not B */ com == 0b1100: y = inb<14:0> || 0b0; /* Shift Left */ com == 0b1101: y = 0b0 || inb<15:1>; /* Shift Rigit */ else: y = as16.enable(ina, inb, com<0>).sumdiff; /* SUB/ADD */ } } /**** addsub16 ****/ module addsub16 { input ina<16>, inb<16>, sel; output sumdiff<16>; instrin enable; add16 add; instruct enable alt { sel: sumdiff = add.enable(ina, ^inb, sel).y; else: sumdiff = add.enable(ina, inb, sel).y; } } /**** 16-Bits Carry Lookahead Adder ****/ module add16 { input a<16>, b<16>, ci; output y<16>, co; instrin enable; cla4 CLA0; cla4 CLA1; cla4 CLA2; cla4 CLA3; lcg4 LCG; sel_v c0, c1, c2; sel_v g0, g1, g2, g3; sel_v p0, p1, p2, p3; sel_v s0<4>, s1<4>, s2<4>, s3<4>; instruct enable par { LCG.enable(g3||g2||g1||g0, p3||p2||p1||p0, ci); CLA0.enable(a< 3: 0>, b< 3: 0>, ci); CLA1.enable(a< 7: 4>, b< 7: 4>, c0); CLA2.enable(a<11: 8>, b<11: 8>, c1); CLA3.enable(a<15:12>, b<15:12>, c2); c0 = LCG.c0; c1 = LCG.c1; c2 = LCG.c2; g0 = CLA0.go; g1 = CLA1.go; g2 = CLA2.go; g3 = CLA3.go; p0 = CLA0.po; p1 = CLA1.po; p2 = CLA2.po; p3 = CLA3.po; s0 = CLA0.y; s1 = CLA1.y; s2 = CLA2.y; s3 = CLA3.y; co = CLA3.co; y = s3 || s2 || s1 || s0; } } module cla4 { input a<4>, b<4>, ci; output y<4>, co, go, po; instrin enable; sel_v c0, c1, c2; instruct enable par { c0 = (a<0> & b<0>) | ((a<0> | b<0>) & ci); c1 = (a<1> & b<1>) | ((a<1> | b<1>) & a<0> & b<0>) | ((a<1> | b<1>) & (a<0> | b<0>) & ci); c2 = (a<2> & b<2>) | ((a<2> | b<2>) & a<1> & b<1>) | ((a<2> | b<2>) & (a<1> | b<1>) & a<0> & b<0>) | ((a<2> | b<2>) & (a<1> | b<1>) & (a<0> | b<0>) & ci); go = (a<3> & b<3>) | ((a<3> | b<3>) & a<2> & b<2>) | ((a<3> | b<3>) & (a<2> | b<2>) & a<1> & b<1>) | ((a<3> | b<3>) & (a<2> | b<2>) & (a<1> | b<1>) & a<0> & b<0>); po = (a<3>|b<3>) & (a<2>|b<2>) & (a<1>|b<1>) & (a<0>|b<0>); co = go | (po & ci); y = a @ b @ (c2 || c1 || c0 || ci); } } module lcg4 { input g<4>, p<4>, ci; output c0, c1, c2, go, po; instrin enable; instruct enable par { c0 = g<0>|(p<0>&ci); c1 = g<1>|(p<1>&g<0>)|(p<1>&p<0>&ci); c2 = g<2>|(p<2>&g<1>)|(p<2>&p<1>&g<0>)|(p<2>&p<1>&p<0>&ci); go = g<3>|(p<3>&g<2>)|(p<3>&p<2>&g<1>)|(p<3>&p<2>&p<1>&g<0>); po = p<3> & p<2> & p<1> & p<0>; } }