/* * pico16.sfl */ /* IR15-11 */ %d ROP 0b00000 /* Register Type operation */ %d LDLI 0b11100 %d LDHI 0b11101 /* IR 4-0 */ %d LD 0b01000 %d ST 0b01001 %d SL 0b01100 %d SR 0b01101 /* State */ %d IF 0b0001 %d RF 0b0010 %d EX 0b0100 %d EX2 0b1000 declare alu16 { input ina<16>, inb<16>, com<4>; output y<16>; instrin enable; instr_arg enable(ina, inb, com); } declare reg_file { input addr1<3>, addr2<3>; input din<16>; output dout1<16>, dout2<16>; instrin read, write; instr_arg read(addr1, addr2); instr_arg write(addr1, din); } declare addsub16 { input ina<16>, inb<16>, sub; output sumdiff<16> ; instrin enable; instr_arg enable(ina, inb, sub); } declare faddr { input a, b, c; output so, co; instrin enable; instr_arg enable(a, b, c); } module bpico16 { input datain<16>; /* data input */ input rst; /* reset */ output dataout<16>; /* data output */ output address<16>; /* address */ instrout oe, we; /* output enable (active low) */ instrin enable; alu16 ALU; reg_file REG; reg pc<16>; /* program counter */ reg ir<16>; /* instruction register */ reg mar<16>; /* memory address register */ reg mdr<16>; /* memory data register */ reg reg1<16>, reg2<16>; /* temporary register for register file */ reg stat<4>; /* stat */ sel_v sbus1<16>, sbus2<16>, dbus<16>; instruct enable par{ dataout = mdr; alt { ^rst: par { /* Initialize */ pc := 0x0000; mar := 0x0000; mdr := 0x0000; ir := 0x0000; reg1:=0x0000; reg2:=0x0000; stat := IF; } else: alt { stat == IF: par { /* Instruction Fetch */ address = pc; oe(); dbus = datain; ir := dbus; stat := RF; } stat == RF: par { /* Register Fetch */ address = mar; sbus1 = pc; sbus2 = 0x0002; dbus = ALU.enable(sbus1,sbus2,0b0110).y; pc := dbus; reg1 := REG.read(ir<10:8>, ir<7:5>).dout1; reg2 := REG.read(ir<10:8>, ir<7:5>).dout2; alt {(ir<15:11> == ROP) & (ir<4:0> == ST): mdr:= REG.dout2;} /* ST */ stat := EX; } stat == EX: par { /* Execution 1 */ address = mar; alt { ir<15:11> == ROP: alt { /* R type functions */ ir<4:0>== LD: par{ /* LD */ sbus1 = reg1; sbus2 = reg2; dbus = ALU.enable(sbus1,sbus2,0b0001).y; mar := dbus; stat := EX2;} ir<4:0>== ST: par { /* ST */ sbus1 = reg1; sbus2 = reg2; dbus = ALU.enable(sbus1,sbus2,0b0000).y; mar := dbus; stat := EX2;} ir<4:3>== 0b00: par { /* ALU instructions */ sbus1 = reg1; sbus2 = reg2; dbus = ALU.enable(sbus1,sbus2,ir<3:0>).y; REG.write(ir<10:8>, dbus); stat := IF;} (ir<4:0>== SL)|(ir<4:0> == SR): par { /* SL, SR */ sbus1 = reg1; sbus2 = reg2; dbus = ALU.enable(sbus1,sbus2,0b1||ir<2:0>).y; REG.write(ir<10:8>, dbus); stat := IF; } } ir<15:11>==LDLI: par { /* LDLI */ sbus1 = reg1; sbus2 = 16# ir<7:0>; dbus = ALU.enable(sbus1,sbus2,0b0001).y; REG.write(ir<10:8>, dbus); stat := IF;} ir<15:11>==LDHI: par { /* LDHI */ sbus1 = reg1; sbus2 = ir<7:0> || 0b00000000; dbus = ALU.enable(sbus1,sbus2,0b0001).y; REG.write(ir<10:8>, dbus); stat := IF;} ir<15:14>==0b00: par { /* ADDI/SUBI/ANDI/ORI/XORI */ sbus1 = reg1; alt{ ir<13>&ir<12>: sbus2 = 16 # ir<7:0>; ir<13:11>== 0b010: sbus2 = 0xff || ir<7:0>; else: sbus2 = 0x00 || ir<7:0>; } dbus = ALU.enable(sbus1,sbus2,ir<14:11>).y; REG.write(ir<10:8>, dbus); stat := IF;} } } stat==EX2: par { /* Execution 2 */ address = mar; alt { ir<4:0> == LD: par { dbus = datain; oe(); /* LD */ REG.write(ir<10:8>, dbus);} ir<4:0> == ST: we(); } /* ST */ stat := IF;} } } } } /* pico 16 */ /* * 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 ; /* Exclusive OR */ com==0b0101: y = ^inb; /* Not */ com==0b1100: y = inb<14:0>|| 0b0 ; /* Shift Left */ com==0b1101: y = 0b0||inb<15:1>; /* Shift Right */ else: y = as16.enable(ina, inb, com<0>).sumdiff;/* SUB/ADD */ } } /* * addsub16 */ module addsub16 { input ina<16>, inb<16>, sub; output sumdiff<16> ; instrin enable; faddr fa0, fa1, fa2, fa3, fa4, fa5, fa6, fa7; faddr fa8, fa9, fa10, fa11, fa12, fa13, fa14, fa15; sel s0, s1, s2, s3, s4, s5, s6, s7; sel s8, s9, s10, s11, s12, s13, s14, s15; sel c0, c1, c2, c3, c4, c5, c6, c7; sel c8, c9, c10, c11, c12, c13, c14; sel b<16>; instruct enable par { alt {sub: b = ^inb; else: b = inb; } s0 = fa0.enable(ina<0>, b<0>, sub).so; c0 = fa0.co; s1 = fa1.enable(ina<1>, b<1>, c0).so; c1 = fa1.co; s2 = fa2.enable(ina<2>, b<2>, c1).so; c2 = fa2.co; s3 = fa3.enable(ina<3>, b<3>, c2).so; c3 = fa3.co; s4 = fa4.enable(ina<4>, b<4>, c3).so; c4 = fa4.co; s5 = fa5.enable(ina<5>, b<5>, c4).so; c5 = fa5.co; s6 = fa6.enable(ina<6>, b<6>, c5).so; c6 = fa6.co; s7 = fa7.enable(ina<7>, b<7>, c6).so; c7 = fa7.co; s8 = fa8.enable(ina<8>, b<8>, c7).so; c8 = fa8.co; s9 = fa9.enable(ina<9>, b<9>, c8).so; c9 = fa9.co; s10 = fa10.enable(ina<10>, b<10>, c9).so; c10 = fa10.co; s11 = fa11.enable(ina<11>, b<11>, c10).so; c11 = fa11.co; s12 = fa12.enable(ina<12>, b<12>, c11).so; c12 = fa12.co; s13 = fa13.enable(ina<13>, b<13>, c12).so; c13 = fa13.co; s14 = fa14.enable(ina<14>, b<14>, c13).so; c14 = fa14.co; s15 = fa15.enable(ina<15>, b<15>, c14).so; sumdiff = s15 || s14 || s13 || s12 || s11 || s10 || s9 || s8 || s7 || s6 || s5 || s4 || s3 || s2 || s1 || s0; } } /* addsub16 */ /* * fdaddr --- full adder */ module faddr { input a, b, c; output so, co; instrin enable; instruct enable par { so = (a & ^b & ^c) | (^a & b & ^c) | (^a & ^b & c) | (a & b & c); co = (a & b) | (b & c) | (c & a); } } /* faddr */ /* * reg_file --- register file with two output ports */ module reg_file { input addr1<3>; input addr2<3>; input din<16>; output dout1<16>; output dout2<16>; instrin read; instrin write; reg register0<16>; reg register1<16>; reg register2<16>; reg register3<16>; reg register4<16>; reg register5<16>; reg register6<16>; reg register7<16>; instruct read par { alt{ 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{ 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; } } instruct write alt { addr1 == 0b000: register0 := din; addr1 == 0b001: register1 := din; addr1 == 0b010: register2 := din; addr1 == 0b011: register3 := din; addr1 == 0b100: register4 := din; addr1 == 0b101: register5 := din; addr1 == 0b110: register6 := din; addr1 == 0b111: register7 := din; } } /* reg_file */