Advertisement
Guest User

Untitled

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