RISC5.v 6.1 KB

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