RISC5.Lola.txt 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214
  1. MODULE RISC5 (IN clk, rst, stallX: BIT; (*NW 18.9.2016*)
  2. IN inbus, codebus: WORD;
  3. OUT adr: [24] BIT;
  4. rd, wr, ben: BIT;
  5. outbus: WORD);
  6. CONST StartAdr = 3FF800H'22;
  7. TYPE PROM := MODULE (IN clk: BIT;
  8. IN adr: [9] BIT;
  9. OUT data: WORD) ^;
  10. Multiplier := MODULE (IN clk, run, u: BIT;
  11. OUT stall: BIT;
  12. IN x, y: WORD;
  13. OUT z: [64] BIT) ^;
  14. Divider := MODULE (IN clk, run, u: BIT;
  15. OUT stall: BIT;
  16. IN x, y: WORD;
  17. OUT quot, rem: WORD) ^;
  18. FPAdder := MODULE (IN clk, run, u, v: BIT; OUT stall: BIT;
  19. IN x, y: WORD; OUT z: WORD) ^;
  20. FPMultiplier := MODULE (IN clk, run: BIT; OUT stall: BIT;
  21. IN x, y: WORD; OUT z: WORD) ^;
  22. FPDivider := MODULE (IN clk, run: BIT; OUT stall: BIT;
  23. IN x, y: WORD; OUT z: WORD) ^;
  24. REG (clk) PC: [22] BIT; (*program counter*)
  25. IR: WORD; (*instruction register*)
  26. N, Z, C, OV: BIT; (*condition flags*)
  27. stall1, PMsel: BIT;
  28. R: [16] WORD; (*data registers*)
  29. H: WORD; (*auxiliary register*)
  30. VAR PM: PROM; (*mem for boot loader*)
  31. mulUnit: Multiplier;
  32. divUnit: Divider;
  33. faddUnit: FPAdder;
  34. fmulUnit: FPMultiplier;
  35. fdivUnit: FPDivider;
  36. pcmux, nxpc: [22] BIT;
  37. cond, S: BIT;
  38. sa, sb, sc: BIT;
  39. ins, pmout: WORD;
  40. p, q, u, v, w: BIT; (*instruction fields*)
  41. op, ira, ira0, irb, irc: [4] BIT;
  42. cc: [3] BIT;
  43. imm: [16] BIT;
  44. off: [20] BIT;
  45. offL: [24] BIT;
  46. regwr, stall, stallL, stallM, stallD, stallFA, stallFM, stallFD: BIT;
  47. sc1, sc0: [2] BIT; (*shift counts*)
  48. a0, a1, a2, a3: BIT;
  49. inbusL, outbusB0, outbusB1, outbusB2, outbusB3: BYTE;
  50. inbusH: [24] BIT;
  51. A, B, C0, C1, aluRes, regmux: WORD;
  52. s1, s2, s3, t1, t2, t3: WORD; (*shifting*)
  53. quotient, remainder: WORD;
  54. product: [64] BIT;
  55. fsum, fprod, fquot: WORD;
  56. Add, Sub, Mul, Div: BIT;
  57. Fadd, Fsub, Fmul, Fdiv: BIT;
  58. Ldr, Str, Br: BIT;
  59. BEGIN PM(clk, pcmux[8:0], pmout);
  60. mulUnit (clk, Mul, ~u, stallM, B, C1, product);
  61. divUnit (clk, Div, ~u, stallD, B, C1, quotient, remainder);
  62. faddUnit (clk, Fadd|Fsub, u, v, stallFA, B, {Fsub^C0.31, C0[30:0]}, fsum);
  63. fmulUnit (clk, Fmul, stallFM, B, C0, fprod);
  64. fdivUnit (clk, Fdiv, stallFD, B, C0, fquot);
  65. ins := PMsel -> pmout : IR; (*current instruction*)
  66. p := ins.31; (*instruction fields*)
  67. q := ins.30;
  68. u := ins.29;
  69. v := ins.28;
  70. w := ins.16;
  71. cc:= ins[26:24];
  72. ira := ins[27:24];
  73. irb := ins[23:20];
  74. op := ins[19:16];
  75. irc := ins[3:0];
  76. imm := ins[15:0]; (*reg instr*)
  77. off := ins[19:0]; (*mem instr*)
  78. offL := ins[23:0]; (*branch instr*)
  79. Add := ~p & (op = 8);
  80. Sub := ~p & (op = 9);
  81. Mul := ~p & (op = 10);
  82. Div := ~p & (op = 11);
  83. Fadd := ~p & (op = 12);
  84. Fsub := ~p & (op = 13);
  85. Fmul := ~p & (op = 14);
  86. Fdiv := ~p & (op = 15);
  87. Ldr := p & ~q & ~u;
  88. Str := p & ~q & u;
  89. Br := p & q;
  90. (*ALU*)
  91. A := R[ira0]; (*main data path*)
  92. B := R[irb];
  93. C0 := R[irc];
  94. C1 := q -> {v!16, imm} : C0 ;
  95. ira0 := Br -> 15'4 : ira;
  96. adr := stallL -> B[23:0] + {off.19!4, off} : {pcmux, 0'2};
  97. rd := Ldr & ~stallX & ~stall1;
  98. wr := Str & ~stallX & ~stall1;
  99. ben := p & ~q & v & ~stallX & ~stall1; (*byte enable*)
  100. sc0 := C1[1:0];
  101. sc1 := C1[3:2];
  102. (*right shifter*)
  103. s1 := (sc0 = 3) -> {(w -> B[2:0] : {B.31 ! 3}), B[31:3]} :
  104. (sc0 = 2) -> {(w -> B[1:0] : {B.31 ! 2}), B[31:2]} :
  105. (sc0 = 1) -> {(w -> B.0 : B.31), B[31:1]} : B;
  106. s2 := (sc1 = 3) -> {(w -> s1[11:0] : {B.31 ! 12}), s1[31:12]} :
  107. (sc1 = 2) -> {(w -> s1[7:0] : {B.31 ! 8}), s1[31:8]} :
  108. (sc1 = 1) -> {(w -> s1[3:0] : {B.31 ! 4}), s1[31:4]} : s1;
  109. s3 := C1.4 -> {(w -> s2[15:0] : {s2.31 ! 16}), s2[31:16]} : s2;
  110. (*left shifter*)
  111. t1 := (sc0 = 3) -> {B[28:0], 0'3} :
  112. (sc0 = 2) -> {B[29:0], 0'2} :
  113. (sc0 = 1) -> {B[30:0], 0'1} : B;
  114. t2 := (sc1 = 3) -> {t1[19:0], 0'12} :
  115. (sc1 = 2) -> {t1[23:0], 0'8} :
  116. (sc1 = 1) -> {t1[27:0], 0'4} : t1;
  117. t3 := C1.4 -> {t2[15:0], 0'16} : t2;
  118. aluRes :=
  119. ~op.3 ->
  120. (~op.2 ->
  121. (~op.1 ->
  122. (~op.0 -> (*Mov*)
  123. (q ->
  124. (~u -> {v!16 , imm} : {imm, 0'16}) :
  125. (~u -> C0 : (~v -> H : {N, Z, C, OV, 0'20, 58H'8}))) :
  126. t3 ): (*Lsl*)
  127. s3) : (*Asr, Ror*)
  128. (~op.1 ->
  129. (~op.0 -> B & C1 : B & ~C1) : (*And, Ann*)
  130. (~op.0 -> B | C1 : B ^ C1)) ): (*Ior, Xor*)
  131. (~op.2 ->
  132. (~op.1 ->
  133. (~op.0 -> B + C + (u&C) : B - C1 - (u&C)) : (*Add, Sub*)
  134. (~op.0 -> product[31:0] : quotient)) : (*Mul, Div*)
  135. (~op.1 ->
  136. fsum : (*Fad, Fsb*)
  137. (~op.0 -> fprod : fquot))) ; (*Fml, Fdv*)
  138. regwr := ~p & ~stall | (Ldr & ~stallX & ~stall1) | (Br & cond & v & ~stallX);
  139. a0 := ~adr.1 & ~adr.0;
  140. a1 := ~adr.1 & adr.0;
  141. a2 := adr.1 & ~adr.0;
  142. a3 := adr.1 & adr.0;
  143. inbusL := (~ben | a0) -> inbus[7:0] : a1 -> inbus[15:8] : a2 -> inbus[23:16] : inbus[31:24];
  144. inbusH := ~ben -> inbus[31:8] : 0'24;
  145. regmux := Ldr -> {inbusH, inbusL} : (Br & v) -> {0'8, nxpc, 0'2} : aluRes ;
  146. outbusB0 := A[7:0];
  147. outbusB1 := ben & a1 -> A[7:0] : A[15:8];
  148. outbusB2 := ben & a2 -> A[7:0] : A[23:16];
  149. outbusB3 := ben & a3 -> A[7:0] : A[31:24];
  150. outbus := {outbusB3, outbusB2, outbusB1, outbusB0};
  151. (*control unit*)
  152. S := N ^ OV;
  153. nxpc := PC + 1;
  154. cond := ins.27 ^ (
  155. (cc = 0) & N | (*MI, PL*)
  156. (cc = 1) & Z | (*EQ, NE*)
  157. (cc = 2) & C | (*CS, CC*)
  158. (cc = 3) & OV | (*VS, VC*)
  159. (cc = 4) & (C|Z) | (*LS, HI*)
  160. (cc = 5) & S | (*LT, GE*)
  161. (cc = 6) & (S|Z) | (*LE, GT*)
  162. (cc = 7));
  163. pcmux := ~rst -> 3FF800H'22 :
  164. stall -> PC :
  165. (Br & cond & u) -> offL[21:0] + nxpc :
  166. (Br & cond & ~u) -> C0[23:2] : nxpc;
  167. sa := aluRes.31;
  168. sb := B.31;
  169. sc := C1.31;
  170. stall := stallL | stallM | stallD | stallFA | stallFM | stallFD | stallX;
  171. stallL := (Ldr | Str) & ~stall1;
  172. (*assignments to registers*)
  173. PC := pcmux;
  174. PMsel := ~rst | (pcmux[21:12] = 03FFH'10);
  175. IR := stall -> IR : codebus;
  176. stall1 := stallX -> stall1 : stallL;
  177. R[ira0] := regwr -> regmux : A;
  178. N := regwr -> regmux.31 : N;
  179. Z := regwr -> (regmux = 0) : Z;
  180. C := Add -> (sb&sc) | (~sa&~sb&sc) | (~sa&sb&~sc&sa) :
  181. Sub -> (~sb&sc) | (sa&~sb&~sc) | (sa&sb&sc) : C;
  182. OV := Add -> (sa&~sb&~sc) | (~sa&sb&sc) :
  183. Sub -> (sa&~sb&sc) | (~sa&sb&~sc) : OV;
  184. H := Mul -> product[63:32] : Div -> remainder : H
  185. END RISC5.