RISC5a.v 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147
  1. `timescale 1ns / 1ps // 1.9.2018
  2. //no interrupt, no 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, 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;
  26. wire [31:0] A, B, C0, C1, aluRes, regmux, inbus1;
  27. wire [31:0] lshout, rshout;
  28. wire [31:0] quotient, remainder;
  29. wire [63:0] product;
  30. wire ADD, SUB, MUL, DIV;
  31. wire LDR, STR, BR;
  32. Registers regs (.clk(clk), .wr(regwr), .rno0(ira0), .rno1(irb),
  33. .rno2(irc), .din(regmux), .dout0(A), .dout1(B), .dout2(C0));
  34. Multiplier mulUnit (.clk(clk), .run(MUL), .stall(stallM),
  35. .u(~u), .x(B), .y(C1), .z(product));
  36. Divider divUnit (.clk(clk), .run(DIV), .stall(stallD),
  37. .u(~u), .x(B), .y(C1), .quot(quotient), .rem(remainder));
  38. LeftShifter LSUnit (.x(B), .y(lshout), .sc(C1[4:0]));
  39. RightShifter RSUnit(.x(B), .y(rshout), .sc(C1[4:0]), .md(IR[16]));
  40. assign p = IR[31];
  41. assign q = IR[30];
  42. assign u = IR[29];
  43. assign v = IR[28];
  44. assign cc = IR[26:24];
  45. assign ira = IR[27:24];
  46. assign irb = IR[23:20];
  47. assign op = IR[19:16];
  48. assign irc = IR[3:0];
  49. assign imm = IR[15:0]; // reg instr.
  50. assign off = IR[19:0]; // mem instr.
  51. assign disp = IR[21:0]; // branch instr.
  52. assign ADD = ~p & (op == 8);
  53. assign SUB = ~p & (op == 9);
  54. assign MUL = ~p & (op == 10);
  55. assign DIV = ~p & (op == 11);
  56. assign LDR = p & ~q & ~u;
  57. assign STR = p & ~q & u;
  58. assign BR = p & q;
  59. // Arithmetic-logical unit (ALU)
  60. assign ira0 = BR ? 15 : ira;
  61. assign C1 = q ? {{16{v}}, imm} : C0;
  62. assign adr = stallL0 ? B[23:0] + {{4{off[19]}}, off} : {pcmux, 2'b00};
  63. assign rd = LDR & ~stallX & stallL0;
  64. assign wr = STR & ~stallX & stallL0;
  65. assign ben = p & ~q & v & ~stallX & stallL0; // byte enable
  66. assign aluRes =
  67. ~op[3] ?
  68. (~op[2] ?
  69. (~op[1] ?
  70. (~op[0] ?
  71. (q ? // MOV
  72. (~u ? {{16{v}}, imm} : {imm, 16'b0}) :
  73. (~u ? C0 : (~v ? H : {N, Z, C, OV, 20'b0, 8'h54}))) :
  74. lshout) : // LSL
  75. rshout) : // ASR, ROR
  76. (~op[1] ?
  77. (~op[0] ? B & C1 : B & ~C1) : // AND, ANN
  78. (~op[0] ? B | C1 : B ^ C1))) : // IOR. XOR
  79. (~op[2] ?
  80. (~op[1] ?
  81. (~op[0] ? B + C1 + (u&C) : B - C1 - (u&C)) : // ADD, SUB
  82. (~op[0] ? product[31:0] : quotient)) : // MUL, DIV
  83. 0);
  84. assign regwr = ~p & ~stall | (LDR & ~stallX & ~stallL1) | (BR & cond & v & ~stallX);
  85. assign inbus1 = ~ben ? inbus :
  86. {24'b0, (adr[1] ? (adr[0] ? inbus[31:24] : inbus[23:16]) :
  87. (adr[0] ? inbus[15:8] : inbus[7:0]))};
  88. assign regmux = LDR ? inbus1 : (BR & v) ? {8'b0, nxpc, 2'b0} : aluRes;
  89. assign outbus = ~ben ? A :
  90. adr[1] ? (adr[0] ? {A[7:0], 24'b0} : {8'b0, A[7:0], 16'b0}) :
  91. (adr[0] ? {16'b0, A[7:0], 8'b0} : {24'b0, A[7:0]});
  92. // Control unit CU
  93. assign S = N ^ OV;
  94. assign nxpc = PC + 1;
  95. assign cond = IR[27] ^
  96. ((cc == 0) & N | // MI, PL
  97. (cc == 1) & Z | // EQ, NE
  98. (cc == 2) & C | // CS, CC
  99. (cc == 3) & OV | // VS, VC
  100. (cc == 4) & (C|Z) | // LS, HI
  101. (cc == 5) & S | // LT, GE
  102. (cc == 6) & (S|Z) | // LE, GT
  103. (cc == 7)); // T, F
  104. assign pcmux = ~rst | stall ?
  105. (~rst ? StartAdr : PC) :
  106. (BR & cond) ? (u ? nxpc + disp : C0[23:2]) : nxpc;
  107. assign sa = aluRes[31];
  108. assign sb = B[31];
  109. assign sc = C1[31];
  110. assign stall = stallL0 | stallM | stallD | stallX;
  111. assign stallL0 = (LDR|STR) & ~stallL1;
  112. always @ (posedge clk) begin
  113. PC <= pcmux;
  114. IR <= stall ? IR : codebus;
  115. stallL1 <= stallX ? stallL1 : stallL0;
  116. N <= regwr ? regmux[31] : N;
  117. Z <= regwr ? (regmux == 0) : Z;
  118. C <= ADD ? (~sb&sc&~sa) | (sb&sc&sa) | (sb&~sa) :
  119. SUB ? (~sb&sc&~sa) | (sb&sc&sa) | (~sb&sa) : C;
  120. OV <= ADD ? (sa&~sb&~sc) | (~sa&sb&sc):
  121. SUB ? (sa&~sb&sc) | (~sa&sb&~sc) : OV;
  122. H <= MUL ? product[63:32] : DIV ? remainder : H;
  123. end
  124. endmodule