j1.v 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187
  1. module j1(
  2. input sys_clk_i, input sys_rst_i, input [15:0] io_din,
  3. output io_rd, output io_wr, output [15:0] io_addr, output [15:0] io_dout);
  4. wire [15:0] insn;
  5. wire [15:0] immediate = { 1'b0, insn[14:0] };
  6. wire [15:0] ramrd;
  7. reg [4:0] dsp; // Data stack pointer
  8. reg [4:0] _dsp;
  9. reg [15:0] st0; // Return stack pointer
  10. reg [15:0] _st0;
  11. wire _dstkW; // D stack write
  12. reg [12:0] pc;
  13. reg [12:0] _pc;
  14. reg [4:0] rsp;
  15. reg [4:0] _rsp;
  16. reg _rstkW; // R stack write
  17. reg [15:0] _rstkD;
  18. wire _ramWE; // RAM write enable
  19. wire [15:0] pc_plus_1;
  20. assign pc_plus_1 = pc + 1;
  21. // The D and R stacks
  22. reg [15:0] dstack[0:31];
  23. reg [15:0] rstack[0:31];
  24. always @(posedge sys_clk_i)
  25. begin
  26. if (_dstkW)
  27. dstack[_dsp] = st0;
  28. if (_rstkW)
  29. rstack[_rsp] = _rstkD;
  30. end
  31. wire [15:0] st1 = dstack[dsp];
  32. wire [15:0] rst0 = rstack[rsp];
  33. // st0sel is the ALU operation. For branch and call the operation
  34. // is T, for 0branch it is N. For ALU ops it is loaded from the instruction
  35. // field.
  36. reg [3:0] st0sel;
  37. always @*
  38. begin
  39. case (insn[14:13])
  40. 2'b00: st0sel = 0; // ubranch
  41. 2'b10: st0sel = 0; // call
  42. 2'b01: st0sel = 1; // 0branch
  43. 2'b11: st0sel = insn[11:8]; // ALU
  44. default: st0sel = 4'bxxxx;
  45. endcase
  46. end
  47. `define RAMS 3
  48. genvar i;
  49. `define w (16 >> `RAMS)
  50. `define w1 (`w - 1)
  51. generate
  52. for (i = 0; i < (1 << `RAMS); i=i+1) begin : ram
  53. // RAMB16_S18_S18
  54. RAMB16_S2_S2
  55. ram(
  56. .DIA(0),
  57. // .DIPA(0),
  58. .DOA(insn[`w*i+`w1:`w*i]),
  59. .WEA(0),
  60. .ENA(1),
  61. .CLKA(sys_clk_i),
  62. .ADDRA({_pc}),
  63. .DIB(st1[`w*i+`w1:`w*i]),
  64. // .DIPB(2'b0),
  65. .WEB(_ramWE & (_st0[15:14] == 0)),
  66. .ENB(|_st0[15:14] == 0),
  67. .CLKB(sys_clk_i),
  68. .ADDRB(_st0[15:1]),
  69. .DOB(ramrd[`w*i+`w1:`w*i]));
  70. end
  71. endgenerate
  72. // Compute the new value of T.
  73. always @*
  74. begin
  75. if (insn[15])
  76. _st0 = immediate;
  77. else
  78. case (st0sel)
  79. 4'b0000: _st0 = st0;
  80. 4'b0001: _st0 = st1;
  81. 4'b0010: _st0 = st0 + st1;
  82. 4'b0011: _st0 = st0 & st1;
  83. 4'b0100: _st0 = st0 | st1;
  84. 4'b0101: _st0 = st0 ^ st1;
  85. 4'b0110: _st0 = ~st0;
  86. 4'b0111: _st0 = {16{(st1 == st0)}};
  87. 4'b1000: _st0 = {16{($signed(st1) < $signed(st0))}};
  88. 4'b1001: _st0 = st1 >> st0[3:0];
  89. 4'b1010: _st0 = st0 - 1;
  90. 4'b1011: _st0 = rst0;
  91. 4'b1100: _st0 = |st0[15:14] ? io_din : ramrd;
  92. 4'b1101: _st0 = st1 << st0[3:0];
  93. 4'b1110: _st0 = {rsp, 3'b000, dsp};
  94. 4'b1111: _st0 = {16{(st1 < st0)}};
  95. default: _st0 = 16'hxxxx;
  96. endcase
  97. end
  98. wire is_alu = (insn[15:13] == 3'b011);
  99. wire is_lit = (insn[15]);
  100. assign io_rd = (is_alu & (insn[11:8] == 4'hc));
  101. assign io_wr = _ramWE;
  102. assign io_addr = st0;
  103. assign io_dout = st1;
  104. assign _ramWE = is_alu & insn[5];
  105. assign _dstkW = is_lit | (is_alu & insn[7]);
  106. wire [1:0] dd = insn[1:0]; // D stack delta
  107. wire [1:0] rd = insn[3:2]; // R stack delta
  108. always @*
  109. begin
  110. if (is_lit) begin // literal
  111. _dsp = dsp + 1;
  112. _rsp = rsp;
  113. _rstkW = 0;
  114. _rstkD = _pc;
  115. end else if (is_alu) begin
  116. _dsp = dsp + {dd[1], dd[1], dd[1], dd};
  117. _rsp = rsp + {rd[1], rd[1], rd[1], rd};
  118. _rstkW = insn[6];
  119. _rstkD = st0;
  120. end else begin // jump/call
  121. // predicated jump is like DROP
  122. if (insn[15:13] == 3'b001) begin
  123. _dsp = dsp - 1;
  124. end else begin
  125. _dsp = dsp;
  126. end
  127. if (insn[15:13] == 3'b010) begin // call
  128. _rsp = rsp + 1;
  129. _rstkW = 1;
  130. _rstkD = {pc_plus_1[14:0], 1'b0};
  131. end else begin
  132. _rsp = rsp;
  133. _rstkW = 0;
  134. _rstkD = _pc;
  135. end
  136. end
  137. end
  138. always @*
  139. begin
  140. if (sys_rst_i)
  141. _pc = pc;
  142. else
  143. if ((insn[15:13] == 3'b000) |
  144. ((insn[15:13] == 3'b001) & (|st0 == 0)) |
  145. (insn[15:13] == 3'b010))
  146. _pc = insn[12:0];
  147. else if (is_alu & insn[12])
  148. _pc = rst0[15:1];
  149. else
  150. _pc = pc_plus_1;
  151. end
  152. always @(posedge sys_clk_i)
  153. begin
  154. if (sys_rst_i) begin
  155. pc <= 0;
  156. dsp <= 0;
  157. st0 <= 0;
  158. rsp <= 0;
  159. end else begin
  160. dsp <= _dsp;
  161. pc <= _pc;
  162. st0 <= _st0;
  163. rsp <= _rsp;
  164. end
  165. end
  166. endmodule // j1