diff options
| author | Gabriel Kerneis | 2013-11-21 10:51:51 +0000 |
|---|---|---|
| committer | Gabriel Kerneis | 2013-11-21 10:51:51 +0000 |
| commit | 81ccd74f0cc1dbd7bacbeadd86250edf7d6b244a (patch) | |
| tree | 686cffe9ff847191ff9924e113fcf356a8ee743c /src/test | |
| parent | 49cb64787f6a3df07b42baa373623270f3111993 (diff) | |
Begin tiny conversion
Diffstat (limited to 'src/test')
| -rw-r--r-- | src/test/tiny.sail | 228 |
1 files changed, 228 insertions, 0 deletions
diff --git a/src/test/tiny.sail b/src/test/tiny.sail new file mode 100644 index 00000000..4666c18b --- /dev/null +++ b/src/test/tiny.sail @@ -0,0 +1,228 @@ + +(* is the following typedef equivalent to this? + typedef regT = bit[7] +do you want/need something like this instead? + typedef regT = register bits [0:6] { 0..6: regT } +*) + +typedef regT = bit[0..6] +typedef wordT = bit[0..31] +typedef immT = bit[0..23] +typedef addrT = bit[0..9] +typedef memT = addrT -> wordT { wmem, rmem } + +(* exception Reserved -- no support for exceptions (yet?) *) + +(* beware: L3 has "construct", and we have "const struct", but the + equivalent of "construct" is either "const union" or "enumerate" *) + +typedef funcT = enumerate {fADD; fSUB; fINC; fDEC; fAND; fOR; fXOR; fReserved} +typedef shiftT = enumerate {noShift; RCY1; RCY8; RCY16} +typedef conditionT = enumerate {skipNever; skipNeg; skipZero; skipInRdy} + +(* the previous one will convert to/from integers; safer alternative: +typedef funcT = const union { unit fADD; ... } + +*) + +(**** +--------------------------------------------- +-- State +--------------------------------------------- + +declare +{ + PC :: addrT -- Program Counter + R :: regT -> wordT -- Registers + IM :: memT -- Instruction Memory +(* not sure the interpreter will recognize rmem through the typedef *) + DM :: memT -- Data Memory + InRdy :: bool -- Input Ready + InData :: wordT -- Input Data + OutStrobe :: wordT -- Output Data +} + +--------------------------------------------- +-- Operations +--------------------------------------------- + +wordT function (func::funcT, a:: wordT, b:: wordT) = + match func + { + case fADD => a + b + case fSUB => a - b + case fINC => b + 1 + case fDEC => b - 1 + case fAND => a && b + case fOR => a || b + case fXOR => a ?? b + case _ => #Reserved + } + +wordT shifter (shift::shiftT, a::wordT) = + match shift + { + case noShift => a + case RCY1 => a #>> 1 + case RCY8 => a #>> 8 + case RCY16 => a #>> 16 + } + +wordT ALU (func::funcT, shift::shiftT, a::wordT, b::wordT) = + shifter (shift, function (func, a, b)) + +unit incPC (skip::conditionT, alu::wordT) = + match skip + { + case skipNever => PC <- PC + 1 + case skipNeg => PC <- PC + if alu < 0 then 2 else 1 + case skipZero => PC <- PC + if alu == 0 then 2 else 1 + case skipInRdy => PC <- PC + if InRdy then 2 else 1 + } + +-- Common functionality +unit norm (func::funcT, shift::shiftT, skip::conditionT, + wback::bool, strobe::bool, w::regT, a::regT, b::regT) = +{ + alu = ALU (func, shift, R(a), R(b)); + when wback do R(w) <- alu; + when strobe do OutStrobe <- alu; + incPC (skip, alu) +} + +--------------------------------------------- +-- Instructions +--------------------------------------------- + +define Normal (func::funcT, shift::shiftT, skip::conditionT, + w::regT, a::regT, b::regT) = + norm (func, shift, skip, true, false, w, a, b) + + +define StoreDM (func::funcT, shift::shiftT, skip::conditionT, + w::regT, a::regT, b::regT) = +{ + DM([R(b)]) <- R(a); + norm (func, shift, skip, true, false, w, a, b) +} + +define StoreIM (func::funcT, shift::shiftT, skip::conditionT, + w::regT, a::regT, b::regT) = +{ + IM([R(b)]) <- R(a); + norm (func, shift, skip, true, false, w, a, b) +} + +define Out (func::funcT, shift::shiftT, skip::conditionT, + w::regT, a::regT, b::regT) = + norm (func, shift, skip, true, true, w, a, b) + +define LoadDM (func::funcT, shift::shiftT, skip::conditionT, + w::regT, a::regT, b::regT) = +{ + R(w) <- DM([R(b)]); + norm (func, shift, skip, false, false, w, a, b) +} + +define In (func::funcT, shift::shiftT, skip::conditionT, + w::regT, a::regT, b::regT) = +{ + R(w) <- InData; + norm (func, shift, skip, false, false, w, a, b) +} + +define Jump (func::funcT, shift::shiftT, w::regT, a::regT, b::regT) = +{ + R(w) <- ZeroExtend (PC + 1); + PC <- [ALU (func, shift, R(a), R(b))] +} + +define LoadConstant (w::regT, imm::immT) = +{ + R(w) <- ZeroExtend (imm); + PC <- PC + 1 +} + +define ReservedInstr = #Reserved + +define Run + +--------------------------------------------- +-- Decode +--------------------------------------------- + +instruction Decode (opc::wordT) = + match opc + { + case 'Rw 1 imm`24' => LoadConstant (Rw, imm) + case 'Rw 0 Ra Rb Function Shift Skip Op' => + { + func = [Function :: bits(3)] :: funcT; + shift = [Shift :: bits(2)] :: shiftT; + skip = [Skip :: bits(2)] :: conditionT; + match Op + { + case 0 => Normal (func, shift, skip, Rw, Ra, Rb) + case 1 => StoreDM (func, shift, skip, Rw, Ra, Rb) + case 2 => StoreIM (func, shift, skip, Rw, Ra, Rb) + case 3 => Out (func, shift, skip, Rw, Ra, Rb) + case 4 => LoadDM (func, shift, skip, Rw, Ra, Rb) + case 5 => In (func, shift, skip, Rw, Ra, Rb) + case 6 => Jump (func, shift, Rw, Ra, Rb) + case 7 => ReservedInstr + } + } + } + +--------------------------------------------- +-- Next State +--------------------------------------------- + +unit Next = +{ + i = Decode (IM (PC)); + when i <> ReservedInstr do Run (i) +} + +--------------------------------------------- +-- Encode +--------------------------------------------- + +wordT enc + (args::funcT * shiftT * conditionT * regT * regT * regT, opc::bits(3)) = +{ + func, shift, skip, w, a, b = args; + return (w : '0' : a : b : [func]`3 : [shift]`2 : [skip]`2 : opc) +} + +wordT Encode (i::instruction) = + match i + { + case LoadConstant (Rw, imm) => Rw : '1' : imm + case Normal (args) => enc (args, '000') + case StoreDM (args) => enc (args, '001') + case StoreIM (args) => enc (args, '010') + case Out (args) => enc (args, '011') + case LoadDM (args) => enc (args, '100') + case In (args) => enc (args, '101') + case Jump (func, shift, Rw, Ra, Rb) => + enc ((func, shift, skipNever, Rw, Ra, Rb), '110') + case ReservedInstr => 0b111 + } + +--------------------------------------------- +-- Load into Instruction Memory +--------------------------------------------- + +unit LoadIM (a::addrT, i::instruction list) measure Length (i) = + match i + { + case Nil => nothing + case Cons (h, t) => + { + IM(a) <- Encode (h); + LoadIM (a + 1, t) + } + } + +*****) |
