RISC5.v 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184
  1. `timescale 1ns / 1ps // 31.8.2018
  2. //with interrupt and floating-point
  3. module RISC5(
  4. input clk, rst, irq, stallX,
  5. input [31:0] inbus, codebus,
  6. output [23:0] adr,
  7. output rd, wr, ben,
  8. output [31:0] outbus);
  9. localparam StartAdr = 22'h3FF800;
  10. reg [21:0] PC;
  11. reg [31:0] IR; // instruction register
  12. reg N, Z, C, OV; // condition flags
  13. reg [31:0] H; // aux register
  14. reg stallL1;
  15. wire [21:0] pcmux, pcmux0, nxpc;
  16. wire cond, S;
  17. wire sa, sb, sc;
  18. wire p, q, u, v; // instruction fields
  19. wire [3:0] op, ira, ira0, irb, irc;
  20. wire [2:0] cc;
  21. wire [15:0] imm;
  22. wire [19:0] off;
  23. wire [21:0] disp;
  24. wire regwr;
  25. wire stall, stallL0, stallM, stallD, stallFA, stallFM, stallFD;
  26. wire nn, zz, cx, vv;
  27. reg irq1, intEnb, intPnd, intMd;
  28. reg [25:0] SPC; // saved PC on interrupt
  29. wire intAck;
  30. wire [31:0] A, B, C0, C1, aluRes, regmux, inbus1;
  31. wire [31:0] lshout, rshout;
  32. wire [31:0] quotient, remainder;
  33. wire [63:0] product;
  34. wire [31:0] fsum, fprod, fquot;
  35. wire ADD, SUB, MUL, DIV;
  36. wire FAD, FSB, FML, FDV;
  37. wire LDR, STR, BR, RTI;
  38. Registers regs (.clk(clk), .wr(regwr), .rno0(ira0), .rno1(irb),
  39. .rno2(irc), .din(regmux), .dout0(A), .dout1(B), .dout2(C0));
  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. LeftShifter LSUnit (.x(B), .y(lshout), .sc(C1[4:0]));
  45. RightShifter RSUnit(.x(B), .y(rshout), .sc(C1[4:0]), .md(IR[16]));
  46. FPAdder fpaddx (.clk(clk), .run(FAD|FSB), .u(u), .v(v), .stall(stallFA),
  47. .x(B), .y({FSB^C0[31], C0[30:0]}), .z(fsum));
  48. FPMultiplier fpmulx (.clk(clk), .run(FML), .stall(stallFM),
  49. .x(B), .y(C0), .z(fprod));
  50. FPDivider fpdivx (.clk(clk), .run(FDV), .stall(stallFD),
  51. .x(B), .y(C0), .z(fquot));
  52. assign p = IR[31];
  53. assign q = IR[30];
  54. assign u = IR[29];
  55. assign v = IR[28];
  56. assign cc = IR[26:24];
  57. assign ira = IR[27:24];
  58. assign irb = IR[23:20];
  59. assign op = IR[19:16];
  60. assign irc = IR[3:0];
  61. assign imm = IR[15:0]; // reg instr.
  62. assign off = IR[19:0]; // mem instr.
  63. assign disp = IR[21:0]; // branch instr.
  64. assign ADD = ~p & (op == 8);
  65. assign SUB = ~p & (op == 9);
  66. assign MUL = ~p & (op == 10);
  67. assign DIV = ~p & (op == 11);
  68. assign FAD = ~p & (op == 12);
  69. assign FSB = ~p & (op == 13);
  70. assign FML = ~p & (op == 14);
  71. assign FDV = ~p & (op == 15);
  72. assign LDR = p & ~q & ~u;
  73. assign STR = p & ~q & u;
  74. assign BR = p & q;
  75. assign RTI = BR & ~u & ~v & IR[4];
  76. // Arithmetic-logical unit (ALU)
  77. assign ira0 = BR ? 15 : ira;
  78. assign C1 = q ? {{16{v}}, imm} : C0;
  79. assign adr = stallL0 ? B[23:0] + {{4{off[19]}}, off} : {pcmux, 2'b00};
  80. assign rd = LDR & ~stallX & ~stallL1;
  81. assign wr = STR & ~stallX & ~stallL1;
  82. assign ben = p & ~q & v & ~stallX & ~stallL1; // byte enable
  83. assign aluRes =
  84. ~op[3] ?
  85. (~op[2] ?
  86. (~op[1] ?
  87. (~op[0] ?
  88. (q ? // MOV
  89. (~u ? {{16{v}}, imm} : {imm, 16'b0}) :
  90. (~u ? C0 : (~v ? H : {N, Z, C, OV, 20'b0, 8'h53}))) :
  91. lshout) : // LSL
  92. rshout) : // ASR, ROR
  93. (~op[1] ?
  94. (~op[0] ? B & C1 : B & ~C1) : // AND, ANN
  95. (~op[0] ? B | C1 : B ^ C1))) : // IOR. XOR
  96. (~op[2] ?
  97. (~op[1] ?
  98. (~op[0] ? B + C1 + (u&C) : B - C1 - (u&C)) : // ADD, SUB
  99. (~op[0] ? product[31:0] : quotient)) : // MUL, DIV
  100. (~op[1] ? // flt.pt.
  101. fsum :
  102. (~op[0] ? fprod : fquot)));
  103. assign regwr = ~p & ~stall | (LDR & ~stallX & ~stallL1) | (BR & cond & v & ~stallX);
  104. assign inbus1 = ~ben ? inbus :
  105. {24'b0, (adr[1] ? (adr[0] ? inbus[31:24] : inbus[23:16]) :
  106. (adr[0] ? inbus[15:8] : inbus[7:0]))};
  107. assign regmux = LDR ? inbus1 : (BR & v) ? {8'b0, nxpc, 2'b0} : aluRes;
  108. assign outbus = ~ben ? A :
  109. adr[1] ? (adr[0] ? {A[7:0], 24'b0} : {8'b0, A[7:0], 16'b0}) :
  110. (adr[0] ? {16'b0, A[7:0], 8'b0} : {24'b0, A[7:0]});
  111. // Control unit CU
  112. assign S = N ^ OV;
  113. assign nxpc = PC + 1;
  114. assign cond = IR[27] ^
  115. ((cc == 0) & N | // MI, PL
  116. (cc == 1) & Z | // EQ, NE
  117. (cc == 2) & C | // CS, CC
  118. (cc == 3) & OV | // VS, VC
  119. (cc == 4) & (C|Z) | // LS, HI
  120. (cc == 5) & S | // LT, GE
  121. (cc == 6) & (S|Z) | // LE, GT
  122. (cc == 7)); // T, F
  123. assign intAck = intPnd & intEnb & ~intMd & ~stall;
  124. assign pcmux = ~rst | stall | intAck | RTI ?
  125. (~rst | stall ? (~rst ? StartAdr : PC) :
  126. (intAck ? 1 : SPC)) : pcmux0;
  127. assign pcmux0 = (BR & cond) ? (u? nxpc + disp : C0[23:2]) : nxpc;
  128. assign sa = aluRes[31];
  129. assign sb = B[31];
  130. assign sc = C1[31];
  131. assign nn = RTI ? SPC[25] : regwr ? regmux[31] : N;
  132. assign zz = RTI ? SPC[24] : regwr ? (regmux == 0) : Z;
  133. assign cx = RTI ? SPC[23] :
  134. ADD ? (~sb&sc&~sa) | (sb&sc&sa) | (sb&~sa) :
  135. SUB ? (~sb&sc&~sa) | (sb&sc&sa) | (~sb&sa) : C;
  136. assign vv = RTI ? SPC[22] :
  137. ADD ? (sa&~sb&~sc) | (~sa&sb&sc):
  138. SUB ? (sa&~sb&sc) | (~sa&sb&~sc) : OV;
  139. assign stallL0 = (LDR|STR) & ~stallL1;
  140. assign stall = stallL0 | stallM | stallD | stallX | stallFA | stallFM | stallFD;
  141. always @ (posedge clk) begin
  142. PC <= pcmux;
  143. IR <= stall ? IR : codebus;
  144. stallL1 <= stallX ? stallL1 : stallL0;
  145. N <= nn; Z <= zz; C <= cx; OV <= vv;
  146. H <= MUL ? product[63:32] : DIV ? remainder : H;
  147. irq1 <= irq; // edge detector
  148. intPnd <= rst & ~intAck & ((~irq1 & irq) | intPnd);
  149. intMd <= rst & ~RTI & (intAck | intMd);
  150. intEnb <= ~rst ? 0 : (BR & ~u & ~v & IR[5]) ? IR[0] : intEnb;
  151. SPC <= (intAck) ? {nn, zz, cx, vv, pcmux0} : SPC;
  152. end
  153. endmodule