Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- module J1M
- #(parameter init_file = "forth_ram.txt")
- (
- input wire clk,
- input wire reset,
- output wire [14:0] addr,
- output wire [15:0] data_out,
- output wire write_enable,
- input wire [15:0] data_in
- );
- reg [15:0] istr = 0;
- reg [12:0] pc = 0;
- reg [15:0] RAM [8191:0];
- initial $readmemb(init_file, RAM, 0, 8191);
- reg [15:0] RSTACK_SP = 0;
- reg [15:0] RSTACK [31:0];
- reg [5:0] DSTACK_DEPTH = 0;
- reg [15:0] DSTACK [31:0];
- reg [15:0] DSTACK_T;
- reg [15:0] DSTACK_N;
- reg [15:0] ALU_OUT;
- assign addr = DSTACK_T[14:0];
- assign write_enable = istr[5] && (istr[15:13] == 3'b011);
- assign data_out = DSTACK_N;
- reg [12:0] istrAddr = 0;
- reg [15:0] RAM_T = 0;
- always @(posedge clk) begin
- istr <= RAM[istrAddr];
- RAM_T <= RAM[DSTACK_T >> 1];
- if (istr[5] && (istr[15:13] == 3'b011) && DSTACK_T[15:14] == 0)
- RAM[DSTACK_T >> 1] <= DSTACK_N;
- end
- always @* begin
- if (istr[15:13] == 3'b000) // Jump
- istrAddr = istr[12:0];
- else if (istr[15:13] == 3'b001 && DSTACK_T == 0) // Conditional jump
- istrAddr = istr[12:0];
- else if (istr[15:13] == 3'b010) // Call
- istrAddr = istr[12:0];
- else if (istr[15:13] == 3'b011 && istr[12])
- istrAddr = RSTACK[RSTACK_SP] >> 1;
- else
- istrAddr = pc + 1;
- end
- always @* begin
- case (istr[11:8])
- 0: ALU_OUT = DSTACK_T; // T
- 1: ALU_OUT = DSTACK_N; // N
- 2: ALU_OUT = DSTACK_T + DSTACK_N; // T + N
- 3: ALU_OUT = DSTACK_T & DSTACK_N; // T and N
- 4: ALU_OUT = DSTACK_T | DSTACK_N; // T or N
- 5: ALU_OUT = {DSTACK_T[7:0], DSTACK_T[15:8]};
- 6: ALU_OUT = ~DSTACK_T; // ~T
- 7: ALU_OUT = DSTACK_T == DSTACK_N ? 16'hFFFF: 15'h0; // N == T
- 8: ALU_OUT = $signed(DSTACK_N) < $signed(DSTACK_T) ? 16'hFFFF: 15'h0; // N < T
- 9: ALU_OUT = DSTACK_T >> 1; // T >> 1
- 10: ALU_OUT = DSTACK_T - 1; // T - 1
- 11: ALU_OUT = RSTACK[RSTACK_SP]; // R
- 12: ALU_OUT = DSTACK_T[15:14] == 0 ? RAM_T : data_in; // [T]
- 13: ALU_OUT = DSTACK_T << 1; // T << 1
- 14: ALU_OUT = DSTACK_DEPTH; // DEPTH
- 15: ALU_OUT = DSTACK_N < DSTACK_T ? 16'hFFFF: 15'h0; // Nu < T
- endcase
- end
- always @(posedge clk or posedge reset) begin
- if (reset) begin
- pc <= 0;
- RSTACK_SP <= 0;
- DSTACK_DEPTH <= 0;
- end else begin
- casez (istr[15:13])
- 3'b1??: begin
- // Literal
- DSTACK_DEPTH <= DSTACK_DEPTH + 1;
- DSTACK[DSTACK_DEPTH + 1] <= DSTACK_N;
- DSTACK_N <= DSTACK_T;
- DSTACK_T <= {1'b0, istr[14:0]};
- pc <= pc + 1;
- end
- 3'b000:
- pc <= istr[12:0]; // Jump
- 3'b001: begin
- // Conditional jump
- DSTACK_DEPTH <= DSTACK_DEPTH - 1;
- DSTACK_T <= DSTACK_N;
- DSTACK_N <= DSTACK[DSTACK_DEPTH];
- if (DSTACK_T == 0)
- pc <= istr[12:0];
- else
- pc <= pc + 1;
- end
- 3'b010: begin
- // Call
- RSTACK_SP <= RSTACK_SP + 1;
- RSTACK[RSTACK_SP + 1] <= {1'b0, pc + 1, 1'b0};
- pc <= istr[12:0];
- end
- 3'b011: begin
- // ALU
- DSTACK_T <= ALU_OUT;
- case (istr[1:0]) // dstack+-
- 2'b00: begin
- if (istr[7])
- DSTACK_N <= DSTACK_T;
- end
- 2'b01: begin
- DSTACK_DEPTH <= DSTACK_DEPTH + 1;
- DSTACK_N <= DSTACK_T;
- DSTACK[DSTACK_DEPTH + 1] <= DSTACK_N;
- if (istr[7])
- DSTACK_N <= DSTACK_T;
- end
- 2'b11: begin
- DSTACK_DEPTH <= DSTACK_DEPTH - 1;
- DSTACK_N <= DSTACK[DSTACK_DEPTH];
- end
- endcase
- case (istr[3:2]) // rstack+-
- 2'b01: begin
- RSTACK_SP <= RSTACK_SP + 1;
- RSTACK[RSTACK_SP + 1] <= DSTACK_T;
- end
- 2'b11: begin
- RSTACK_SP <= RSTACK_SP - 1;
- end
- endcase
- if (istr[12]) begin // R -> PC
- pc <= RSTACK[RSTACK_SP] >> 1;
- end else begin
- pc <= pc + 1;
- end
- end
- endcase
- end
- end
- endmodule
Advertisement
Add Comment
Please, Sign In to add comment