/* * pc.v - * program counter, stack, and related stuff for a PIC-family microprocessor. * specificly 16C62X, but similar to (and maybe same as) other 16C6x, 16C7x. * * Copyright 1999 Steve Tell. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public * License along with this program; if not, write to the Free * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * **************************************************************************** * * * this module also includes the PCLATH special-function register. * * We currently implement a 13-bit program counter and program memory address * like the microchip manual says, but I think this could easily go to * 16 bits by implementing a few more bits of the PCLatH register. * * Steve Tell * May 1, 1999 */ `include "funcs.v" module pcstack(Clk, Q, reset, Rpcl, Rpclath, Wpcl, Wpclath, literal, PCf, PC, busin, busout); input Clk; input [3:0] Q; input reset; input Rpcl, Rpclath, Wpcl, Wpclath; input [2:0] PCf; input [10:0] literal; input [7:0] busin; output [7:0] busout; output [12:0] PC; reg [7:0] PCLatH; reg [7:0] PCL; reg [12:0] PC; reg [7:0] busout; reg [12:0] stack[7:0]; reg [2:0] sp; always @(posedge Clk) if(Q[3] == 1) begin if(Wpclath == 1'b1) PCLatH <= busin; end // if (Q[3] == 1) always @(posedge Clk) if(reset == 1'b1) begin sp <= 0; PC <= 0; PCLatH <= 0; end else if(Q[3] == 1) begin // if (reset == 1'b1) if(PCf == `PGS) begin stack[sp] = PC; sp <= sp + 1; end if(PCf == `PGO || PCf == `PGS) PC <= {PCLatH[4:3], literal}; else if(PCf == `POP) begin sp = sp - 1; PC <= stack[sp]; end else begin // PCN if(Wpcl == 1'b1) PC <= {PCLatH[4:0], busin}; else PC <= PC+1; end // else: !if(PCf == `POP) end // if (Q[3] == 1) always @(Rpcl or PCL) if(Rpcl == 1) busout <= PCL; else busout <= 8'hzz; always @(Rpclath or PCLatH) if(Rpclath == 1) busout <= PCLatH; else busout <= 8'hzz; endmodule // pcstack