j0.v 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164
  1. // J0 is a stripped-down J1.
  2. // Major changes:
  3. // stacks are only 16 deep
  4. // program counter is only 7 bits (128 instructions)
  5. // DEPTH and LSHIFT instructions removed
  6. // multiply and swab instructions added
  7. module j0(
  8. input sys_clk_i, input sys_rst_i,
  9. output [6:0] insn_addr,
  10. input [15:0] insn,
  11. output mem_rd,
  12. output mem_wr,
  13. output [15:0] mem_addr,
  14. output [15:0] mem_dout,
  15. input [15:0] mem_din,
  16. input pause
  17. );
  18. wire [15:0] immediate = { 1'b0, insn[14:0] };
  19. wire [15:0] ramrd;
  20. reg [4:0] dsp; // Data stack pointer
  21. reg [4:0] _dsp;
  22. reg [15:0] st0; // Top of data stack
  23. reg [15:0] _st0;
  24. wire dstkW; // D stack write
  25. reg [6:0] pc;
  26. reg [6:0] _pc;
  27. reg [4:0] rsp;
  28. reg [4:0] _rsp;
  29. reg rstkW; // R stack write
  30. reg [15:0] rstkD; // R stack write value
  31. wire [6:0] pc_plus_1 = pc + 1;
  32. // The D and R stacks
  33. reg [15:0] dstack[0:31];
  34. reg [15:0] rstack[0:31];
  35. wire [15:0] st1 = dstack[dsp];
  36. wire [15:0] rst0 = rstack[rsp];
  37. // st0sel is the ALU operation. For branch and call the operation
  38. // is T, for 0branch it is N. For ALU ops it is loaded from the instruction
  39. // field.
  40. reg [4:0] st0sel;
  41. always @*
  42. begin
  43. case (insn[14:13])
  44. 2'b00: st0sel <= 0; // ubranch
  45. 2'b10: st0sel <= 0; // call
  46. 2'b01: st0sel <= 1; // 0branch
  47. 2'b11: st0sel <= {insn[4], insn[11:8]}; // ALU
  48. default: st0sel <= 4'bxxxx;
  49. endcase
  50. // Compute the new value of T.
  51. if (insn[15])
  52. _st0 <= immediate;
  53. else
  54. case (st0sel)
  55. 5'b00000: _st0 <= st0;
  56. 5'b00001: _st0 <= st1;
  57. 5'b00010: _st0 <= st0 + st1;
  58. 5'b00011: _st0 <= st0 & st1;
  59. 5'b00100: _st0 <= st0 | st1;
  60. 5'b00101: _st0 <= st0 ^ st1;
  61. 5'b00110: _st0 <= ~st0;
  62. 5'b00111: _st0 <= {16{(st1 == st0)}};
  63. 5'b01000: _st0 <= {16{($signed(st1) < $signed(st0))}};
  64. 5'b01001: _st0 <= st1 >> st0[3:0];
  65. 5'b01010: _st0 <= st0 - 1;
  66. 5'b01011: _st0 <= rst0;
  67. 5'b01100: _st0 <= mem_din;
  68. 5'b01101: _st0 <= st1 * st0;
  69. 5'b01110: _st0 <= {st0[7:0], st0[15:8]};
  70. 5'b01111: _st0 <= {16{(st1 < st0)}};
  71. default: _st0 <= 16'hxxxx;
  72. endcase
  73. end
  74. wire is_alu = (insn[15:13] == 3'b011);
  75. wire is_lit = (insn[15]);
  76. // assign mem_rd = (is_alu & (insn[11:8] == 4'hc));
  77. assign mem_rd = (st0sel == 5'hc);
  78. assign mem_wr = is_alu & insn[5];
  79. assign mem_addr = st0;
  80. assign mem_dout = st1;
  81. assign dstkW = is_lit | (is_alu & insn[7]);
  82. wire [1:0] dd = insn[1:0]; // D stack delta
  83. wire [1:0] rd = insn[3:2]; // R stack delta
  84. always @*
  85. begin
  86. if (is_lit) begin // literal
  87. _dsp = dsp + 1;
  88. _rsp = rsp;
  89. rstkW = 0;
  90. rstkD = _pc;
  91. end else if (is_alu) begin // ALU
  92. _dsp = dsp + {dd[1], dd[1], dd[1], dd};
  93. _rsp = rsp + {rd[1], rd[1], rd[1], rd};
  94. rstkW = insn[6];
  95. rstkD = st0;
  96. end else begin // jump/call
  97. // predicated jump is like DROP
  98. if (insn[15:13] == 3'b001) begin
  99. _dsp = dsp - 1;
  100. end else begin
  101. _dsp = dsp;
  102. end
  103. if (insn[15:13] == 3'b010) begin // call
  104. _rsp = rsp + 1;
  105. rstkW = 1;
  106. rstkD = {pc_plus_1, 1'b0};
  107. end else begin
  108. _rsp = rsp;
  109. rstkW = 0;
  110. rstkD = _pc;
  111. end
  112. end
  113. if (sys_rst_i)
  114. _pc = pc;
  115. else
  116. if ((insn[15:13] == 3'b000) |
  117. ((insn[15:13] == 3'b001) & (|st0 == 0)) |
  118. (insn[15:13] == 3'b010))
  119. _pc = insn[6:0];
  120. else if (is_alu & insn[12])
  121. _pc = rst0[7:1];
  122. else
  123. _pc = pc_plus_1;
  124. end
  125. assign insn_addr = pause ? pc : _pc;
  126. always @(posedge sys_clk_i)
  127. begin
  128. if (sys_rst_i) begin
  129. pc <= 0;
  130. dsp <= 0;
  131. st0 <= 0;
  132. rsp <= 0;
  133. end else if (!pause) begin
  134. pc <= _pc;
  135. dsp <= _dsp;
  136. st0 <= _st0;
  137. rsp <= _rsp;
  138. if (dstkW)
  139. dstack[_dsp] = st0;
  140. if (rstkW)
  141. rstack[_rsp] = rstkD;
  142. end
  143. end
  144. endmodule // j1