RISC5.v 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210
  1. `timescale 1ns / 1ps // 25.9.2015
  2. module RISC5(
  3. input clk, rst, stallX,
  4. input [31:0] inbus, codebus,
  5. output [23:0] adr,
  6. output rd, wr, ben,
  7. output [31:0] outbus);
  8. localparam StartAdr = 22'h3FF800;
  9. reg [21:0] PC;
  10. reg [31:0] IR; // instruction register
  11. reg N, Z, C, OV; // condition flags
  12. reg [31:0] R [0:15]; // array of 16 registers
  13. reg [31:0] H; // aux register
  14. reg stall1, PMsel;
  15. wire [31:0] ins, pmout;
  16. wire [21:0] pcmux, nxpc;
  17. wire cond, S;
  18. wire sa, sb, sc;
  19. wire p, q, u, v, w; // instruction fields
  20. wire [3:0] op, ira, ira0, irb, irc;
  21. wire [2:0] cc;
  22. wire [15:0] imm;
  23. wire [19:0] off;
  24. wire [23:0] offL;
  25. wire regwr;
  26. wire stall, stallL, stallM, stallD, stallFA, stallFM, stallFD;
  27. wire [1:0] sc1, sc0; // shift counts
  28. wire a0, a1, a2, a3;
  29. wire [7:0] inbusL, outbusB0, outbusB1, outbusB2, outbusB3;
  30. wire [23:0] inbusH;
  31. wire [31:0] A, B, C0, C1, aluRes, regmux;
  32. wire [31:0] s1, s2, s3, t1, t2, t3;
  33. wire [31:0] quotient, remainder;
  34. wire [63:0] product;
  35. wire [31:0] fsum, fprod, fquot;
  36. wire MOV, LSL, ASR, ROR, AND, ANN, IOR, XOR; // operation signals
  37. wire ADD, SUB, MUL, DIV; wire FAD, FSB, FML, FDV;
  38. wire LDR, STR, BR;
  39. PROM PM (.adr(pcmux[8:0]), .data(pmout), .clk(clk));
  40. Multiplier mulUnit (.clk(clk), .run(MUL), .stall(stallM),
  41. .u(~u), .x(B), .y(C1), .z(product));
  42. Divider divUnit (.clk(clk), .run(DIV), .stall(stallD),
  43. .u(~u), .x(B), .y(C1), .quot(quotient), .rem(remainder));
  44. FPAdder fpaddx (.clk(clk), .run(FAD|FSB), .u(u), .v(v), .stall(stallFA),
  45. .x(B), .y({FSB^C0[31], C0[30:0]}), .z(fsum));
  46. FPMultiplier fpmulx (.clk(clk), .run(FML), .stall(stallFM),
  47. .x(B), .y(C0), .z(fprod));
  48. FPDivider fpdivx (.clk(clk), .run(FDV), .stall(stallFD),
  49. .x(B), .y(C0), .z(fquot));
  50. assign ins = PMsel ? pmout : IR; // decoding
  51. assign p = ins[31];
  52. assign q = ins[30];
  53. assign u = ins[29];
  54. assign v = ins[28];
  55. assign w = ins[16];
  56. assign cc = ins[26:24];
  57. assign ira = ins[27:24];
  58. assign irb = ins[23:20];
  59. assign op = ins[19:16];
  60. assign irc = ins[3:0];
  61. assign imm = ins[15:0]; // reg instr.
  62. assign off = ins[19:0]; // mem instr.
  63. assign offL = ins[23:0]; // branch instr.
  64. assign MOV = ~p & (op == 0);
  65. assign LSL = ~p & (op == 1);
  66. assign ASR = ~p & (op == 2);
  67. assign ROR = ~p & (op == 3);
  68. assign AND = ~p & (op == 4);
  69. assign ANN = ~p & (op == 5);
  70. assign IOR = ~p & (op == 6);
  71. assign XOR = ~p & (op == 7);
  72. assign ADD = ~p & (op == 8);
  73. assign SUB = ~p & (op == 9);
  74. assign MUL = ~p & (op == 10);
  75. assign DIV = ~p & (op == 11);
  76. assign FAD = ~p & (op == 12);
  77. assign FSB = ~p & (op == 13);
  78. assign FML = ~p & (op == 14);
  79. assign FDV = ~p & (op == 15);
  80. assign LDR = p & ~q & ~u;
  81. assign STR = p & ~q & u;
  82. assign BR = p & q;
  83. assign A = R[ira0]; // register data signals
  84. assign B = R[irb];
  85. assign C0 = R[irc];
  86. // Arithmetic-logical unit (ALU)
  87. assign ira0 = BR ? 15 : ira;
  88. assign C1 = q ? {{16{v}}, imm} : C0;
  89. assign adr = stallL ? B[23:0] + {4'b0, off} : {pcmux, 2'b00};
  90. assign rd = LDR & ~stallX & ~stall1;
  91. assign wr = STR & ~stallX & ~stall1;
  92. assign ben = p & ~q & v & ~stallX & ~stall1; // byte enable
  93. assign sc0 = C1[1:0];
  94. assign sc1 = C1[3:2];
  95. // shifter for ASR and ROR
  96. assign s1 = (sc0 == 3) ? {(w ? B[2:0] : {3{B[31]}}), B[31:3]} :
  97. (sc0 == 2) ? {(w ? B[1:0] : {2{B[31]}}), B[31:2]} :
  98. (sc0 == 1) ? {(w ? B[0] : B[31]), B[31:1]} : B;
  99. assign s2 = (sc1 == 3) ? {(w ? s1[11:0] : {12{s1[31]}}), s1[31:12]} :
  100. (sc1 == 2) ? {(w ? s1[7:0] : {8{s1[31]}}), s1[31:8]} :
  101. (sc1 == 1) ? {(w ? s1[3:0] : {4{s1[31]}}), s1[31:4]} : s1;
  102. assign s3 = C1[4] ? {(w ? s2[15:0] : {16{s2[31]}}), s2[31:16]} : s2;
  103. // shifter for LSL
  104. assign t1 = (sc0 == 3) ? {B[28:0], 3'b0} :
  105. (sc0 == 2) ? {B[29:0], 2'b0} :
  106. (sc0 == 1) ? {B[30:0], 1'b0} : B;
  107. assign t2 = (sc1 == 3) ? {t1[19:0], 12'b0} :
  108. (sc1 == 2) ? {t1[23:0], 8'b0} :
  109. (sc1 == 1) ? {t1[27:0], 4'b0} : t1;
  110. assign t3 = C1[4] ? {t2[15:0], 16'b0} : t2;
  111. assign aluRes =
  112. MOV ? (q ?
  113. (~u ? {{16{v}}, imm} : {imm, 16'b0}) :
  114. (~u ? C0 : (~v ? H : {N, Z, C, OV, 20'b0, 8'h50}))) :
  115. LSL ? t3 :
  116. (ASR|ROR) ? s3 :
  117. AND ? B & C1 :
  118. ANN ? B & ~C1 :
  119. IOR ? B | C1 :
  120. XOR ? B ^ C1 :
  121. ADD ? B + C1 + (u & C) :
  122. SUB ? B - C1 - (u & C) :
  123. MUL ? product[31:0] :
  124. DIV ? quotient :
  125. (FAD|FSB) ? fsum :
  126. FML ? fprod :
  127. FDV ? fquot :
  128. 0;
  129. assign regwr = ~p & ~stall | (LDR & ~stallX & ~stall1) | (BR & cond & v & ~stallX);
  130. assign a0 = ~adr[1] & ~adr[0];
  131. assign a1 = ~adr[1] & adr[0];
  132. assign a2 = adr[1] & ~adr[0];
  133. assign a3 = adr[1] & adr[0];
  134. assign inbusL = (~ben | a0) ? inbus[7:0] :
  135. a1 ? inbus[15:8] : a2 ? inbus[23:16] : inbus[31:24];
  136. assign inbusH = ~ben ? inbus[31:8] : 24'b0;
  137. assign regmux = LDR ? {inbusH, inbusL} : (BR & v) ? {8'b0, nxpc, 2'b0} : aluRes;
  138. assign outbusB0 = A[7:0];
  139. assign outbusB1 = ben & a1 ? A[7:0] : A[15:8];
  140. assign outbusB2 = ben & a2 ? A[7:0] : A[23:16];
  141. assign outbusB3 = ben & a3 ? A[7:0] : A[31:24];
  142. assign outbus = {outbusB3, outbusB2, outbusB1, outbusB0};
  143. // Control unit CU
  144. assign S = N ^ OV;
  145. assign nxpc = PC + 1;
  146. assign cond = ins[27] ^
  147. ((cc == 0) & N | // MI, PL
  148. (cc == 1) & Z | // EQ, NE
  149. (cc == 2) & C | // CS, CC
  150. (cc == 3) & OV | // VS, VC
  151. (cc == 4) & (C|Z) | // LS, HI
  152. (cc == 5) & S | // LT, GE
  153. (cc == 6) & (S|Z) | // LE, GT
  154. (cc == 7)); // T, F
  155. assign pcmux = ~rst ? StartAdr :
  156. stall ? PC :
  157. (BR & cond & u) ? offL[21:0] + nxpc :
  158. (BR & cond & ~u) ? C0[23:2] : nxpc;
  159. assign sa = aluRes[31];
  160. assign sb = B[31];
  161. assign sc = C1[31];
  162. assign stall = stallL | stallM | stallD | stallX | stallFA | stallFM | stallFD;
  163. assign stallL = (LDR|STR) & ~stall1;
  164. always @ (posedge clk) begin
  165. PC <= pcmux;
  166. PMsel <= ~rst | (pcmux[21:12] == 10'h3FF);
  167. IR <= stall ? IR : codebus;
  168. stall1 <= stallX ? stall1 : stallL;
  169. R[ira0] <= regwr ? regmux : A;
  170. N <= regwr ? regmux[31] : N;
  171. Z <= regwr ? (regmux == 0) : Z;
  172. C <= ADD ? (~sb&sc&~sa) | (sb&sc&sa) | (sb&~sa) :
  173. SUB ? (~sb&sc&~sa) | (sb&sc&sa) | (~sb&sa) : C;
  174. OV <= ADD ? (sa&~sb&~sc) | (~sa&sb&sc):
  175. SUB ? (sa&~sb&sc) | (~sa&sb&~sc) : OV;
  176. H <= MUL ? product[63:32] : DIV ? remainder : H;
  177. end
  178. endmodule