package Elf (sysElf) where import RegFile ---------------------------------- -- Types, Interfaces, Modules -- ---------------------------------- type IWord = Bit 32 type Word = Bit 16 type CPUReg = Bit 5 sysElf :: Module Empty sysElf = mkState mkState :: Module Empty mkState = module pc :: Reg Word pc <- mkReg 0 rf :: RegFile CPUReg Word rf <- mkRegFileFull imem :: RegFile Word IWord imem <- mkRegFileFull dmem :: RegFile Word Word dmem <- mkRegFileFull addRules $ mkRules pc rf imem dmem mkRules :: Reg Word -> RegFile CPUReg Word -> RegFile Word IWord -> RegFile Word Word -> Rules mkRules pc rf imem dmem = let instr :: IWord instr = imem.sub pc opcode :: Bit 3 opcode = instr[27:25] pc' :: Word pc' = pc + 1 dst :: CPUReg dst = instr[20:16] src1 :: CPUReg src1 = instr[15:11] src2 :: CPUReg src2 = instr[10:6] in rules "LoadC": when opcode == 2 ==> action { pc := pc'; rf.upd dst (imem.sub pc)[15:0]; } "LoadPC": when opcode == 1 ==> action { pc := pc'; rf.upd dst pc; } "Load": when opcode == 3 ==> action { pc := pc'; rf.upd dst (dmem.sub (rf.sub src1)); } "Store": when opcode == 5 ==> action { pc := pc'; dmem.upd (rf.sub src1) (rf.sub src2); } "Sub": when opcode == 0 ==> action { pc := pc'; rf.upd dst (rf.sub src1 - rf.sub src2); } "Jump": when opcode == 4 ==> action { pc := rf.sub src1; } "JZ": when opcode == 6 rules { "taken": when rf.sub src2 == 0 ==> action { pc := rf.sub src1; }; "not taken": when rf.sub src2 /= 0 ==> action { pc := pc'; } } "LT": when opcode == 7 ==> action { pc := pc'; rf.upd dst (if rf.sub src1 < rf.sub src2 then 1 else 0); }