📄 pc.v
字号:
/* PC.V
**
** This core adheres to GNU Public Licence
** Jeung Joon Lee *** www.cmosexod.com
** joon.lee@quantum.com
**
** JJL 12/12/98
** updated 3/16/2000
**
** Highest module for the 8 bit general purpose microprocessor
** Two submodules are declerared here, popcorn.v and sequencer.v
** The role and functions of these modules are as following:
** PC.V wrapper, and clock generator. Provides to the submodules
** sys_clk and phase_1_clk
** POPCORN.V The 8 bit datapath. Contains the ALU, register file,
** the program counter, stack pointer and all of the muxes.
** SEQUENCER.V The sequencer state machine. BAsed on the fetched opcode,
** generates all of the sequence of control signals to
** fetch more operands or finish executing the opcode.
**
*/
`include "inc.h"
module pc( sys_clk,
sys_rst,
addx_bus,
data_bus,
code_cs_l,
code_rd_l,
code_wr_l,
sram_cs_l,
slow_clk,
port
`ifdef show_debug_pins
,
w_opl,
w_pc,
w_oplo,
state,
w_acc,
w_ax,
w_bx,
w_p,
w_ophi,
w_flag,
phase_1_clk,
slow_clk4,
reg_flag,
tst_bus,
reg_acc,
reg_ax,
reg_bx,
reg_p,
reg_opl
`endif
);
parameter N=6;
input sys_clk;
input sys_rst;
inout [7:0] data_bus;
inout [7:0] port;
//input [1:0] tst_bus_sel;
output [11:0] addx_bus;
//output [7:0] tst_bus;
output code_cs_l, code_rd_l, code_wr_l, sram_cs_l;
output slow_clk;
`ifdef show_debug_pins
// DEBUG SIGNALS
output w_opl;
output w_pc;
output w_oplo;
output [3:0] state;
output w_acc;
output w_ax;
output w_bx;
output w_p;
output w_ophi;
output w_flag;
output phase_1_clk;
output slow_clk4;
output [2:0] reg_flag;
output tst_bus;
output [7:0] reg_acc;
output [7:0] reg_ax;
output [7:0] reg_bx;
output [7:0] reg_p;
output [7:0] reg_opl;
`endif
wire w_acc,w_ax,w_bx,w_p,w_flag;
wire pc_mux,w_pc,w_oplo,w_ophi,w_opl;
wire slow_clk4;
wire [2:0] bbus_mux;
wire [3:0] alu_func;
wire [2:0] reg_flag;
wire [7:0] port;
reg [1:0] state_slow_clk4;
reg phase_1_clk;
wire xx,slow_clk;
wire [5:0] state;
wire [7:0] b_bus,c_bus;
wire [11:0] d_bus;
wire [7:0] tst_bus;
wire sp_mux, w_sp;
wire [1:0] addx_mux;
wire data_bus_wr;
wire sram_cs_l, code_wr_l;
wire flag_mux;
wire [7:0] reg_acc;
wire [7:0] reg_ax;
wire [7:0] reg_bx;
wire [7:0] reg_p;
wire [7:0] reg_opl;
//wire [7:0] port_in;
//wire port_bus_ena;
// define test bus
/*
always @(tst_bus_sel or reg_opl or c_bus or b_bus or d_bus)
case (tst_bus_sel)
2'b00: tst_bus <= reg_opl;
//2'b01: tst_bus <= b_bus;
default: tst_bus <= b_bus;
//2'b10: tst_bus <= c_bus;
//default: tst_bus <= c_bus;
//2'b11: tst_bus <= d_bus;
endcase
*/
//assign tst_bus=tst_bus_sel[0] ? b_bus : c_bus;
assign tst_bus=c_bus;
`ifdef use_clock_divider
//
// CLOCK DIVIDER
//
//
// N=5 sets for 1Mhz operation
// N=7 sets for 250Khz op. good for slow speed debug
reg [N-1:0] clk;
always @(posedge sys_clk or negedge sys_rst)
if (~sys_rst) clk <=0;
else clk <= clk + 1;
assign slow_clk = clk[N-1];
assign slow_clk4 = ~clk[N-3];
`else
reg [1:0] clk;
always @(posedge sys_clk or negedge sys_rst)
if (~sys_rst) clk <= 2'b00;
else clk <= clk + 1;
assign slow_clk = clk[1];
assign slow_clk4 = sys_clk;
`endif
/* define phase_1 clock
** | |
** | ___ ___ ___ ___ | ___ ___
** slow_clk*4 |/ \___/ \___/ \___/ \___|/ \___/ \___
** | _______ _______ | _______
** slow_clk*2 |/ \_______/ \_______|/ \_______
** | _______________ | _______________
** slow_clk |/ \_______________|/
** |________ _______|_
** phase_1 | \_______________/ |
** | |
*/
always @(posedge slow_clk4 or negedge sys_rst)
if (~sys_rst) begin
state_slow_clk4<=2'b00;
phase_1_clk<=1'b1;
end
else case (state_slow_clk4)
2'b00: begin state_slow_clk4<=2'b01; phase_1_clk<=1'b1; end
2'b01: begin state_slow_clk4<=2'b11; phase_1_clk<=1'b1; end
2'b11: begin state_slow_clk4<=2'b10; phase_1_clk<=1'b0; end
2'b10: begin state_slow_clk4<=2'b00; phase_1_clk<=1'b0; end
endcase
// instantiate the datapath
popcorn POPCORN( .sys_clk(slow_clk),
.sys_rst(sys_rst),
.w_acc(w_acc),
.w_ax(w_ax),
.w_bx(w_bx),
.w_p(w_p),
.w_flag(w_flag),
.bbus_mux(bbus_mux),
.alu_func(alu_func),
.pc_mux(pc_mux),
.sp_mux(sp_mux),
.flag_mux(flag_mux),
.addx_mux(addx_mux),
.w_pc(w_pc),
.w_sp(w_sp),
.w_oplo(w_oplo),
.w_ophi(w_ophi),
.w_opl(w_opl),
.data_bus(data_bus),
.port(port),
// .port_in(port_in),
.addx_bus(addx_bus),
.reg_opl(reg_opl),
.reg_flag(reg_flag),
.b_bus(b_bus),
.c_bus(c_bus),
.d_bus(d_bus),
.data_bus_wr(data_bus_wr),
.code_wr_l(code_wr_l),
.reg_acc(reg_acc),
.reg_ax(reg_ax),
.reg_bx(reg_bx),
.reg_p(reg_p)
);
// instantiate the sequencer
sequencer SEQ ( .sys_clk(slow_clk),
.phase_1_clk(phase_1_clk),
.sys_rst(sys_rst),
.w_acc(w_acc),
.w_ax(w_ax),
.w_bx(w_bx),
.w_p(w_p),
.w_flag(w_flag),
.bbus_mux(bbus_mux),
.alu_func(alu_func),
.pc_mux(pc_mux),
.addx_mux(addx_mux),
.sp_mux(sp_mux),
.flag_mux(flag_mux),
.w_pc(w_pc),
.w_sp(w_sp),
.w_oplo(w_oplo),
.w_ophi(w_ophi),
.w_opl(w_opl),
.reg_opl(reg_opl),
.code_cs_l(code_cs_l),
.code_rd_l(code_rd_l),
.code_wr_l(code_wr_l),
.sram_cs_l(sram_cs_l),
.reg_flag(reg_flag),
.data_bus_wr(data_bus_wr),
.next_state(state)
);
endmodule
/*
** Note on pin assignment:
** o use pin file : "finalpin.pin"
** o use global clock Y0 for 66Mhz source
** o use global reset for reset.
** o use N=6. This requires 64Mhz to give internal clock speed of 1Mhz.
**
** 2/12/99
** o Fixed the LDM ACC,xx bug. ALU was not being set for c_bus = b_bus.
** Call this 'popcorn - final'
**
** 2/11/99
** o Uncovered and fixed 2 bugs relating the IO PORT:
** 1.The signals 'reg_port_gate' which controls the gate of the port
** output buffer has the wrong polarity. This was causing the port
** to drive the port IO pin only when it was being read.
** 2.The state of the bbus_mux[2:0] during LDACC/STADD was set to unknown.
** This was causing the reg_port_gate to be deasserted during LDACC PORT
** or STACC PORT instructions for 1 cycle, causing glitches in the IO port
** pin
**
** 1/8/99
** o Succesfully ran a timer program which toggles all bits of the
** port register at 2mS interval (period=4mS). The program uses
** an instrunctions timed 2mS delay subroutine.
**
** 1/7/99
** o Somewhat final version. The test bus (TST[7:0]) has been dropped
** and PORT[7:0] been used. All instructions works at least at 2 Mhz.
** Call this 'popcorn -v5'
**
** 1/5/99
** o Droppped the automatic pushing and popping of the flags when CALL/RET
** are executed, (could not fit). So reduced the size of REG_OPHI down
** to 4 from 8 bits. Instead the pushing of the flag is now done with
** LDACC flag
** LDM flag, #addx
** PUSH flag
** POP flag
** instructions. The flag register still is muxed from ALU and c_bus.
** Thanks Lord.
** All that remains now is implementation of interrupt support.
**
** 1/3/99
** o Removed DX and CX register from the register file, to free-up
** the b_mux. The freed b_bus mux inputs are used by the PC (hi and low).
** This allows PC to be pushed into the stack as well as CALL and RET
** and push flag instructions
**
** 1/1/99
** o Removed 7 level-deep hardware stack - it was obvious that this is not
** a very robust way of having a stack. It limits the CALL/RET depth.
** However my initial rational for not implementing the SP was that I
** did not wanted to have a SRAM for stack. SRAM automatically implies
** an extenal IC (since on FPGA you could not provide the required
** amount of space).
** o Added another addressing mode: direct mode, and 2 instructions: LDM and
** STM (load mem, store mem). This brings the modes
** to: register direct, immediate and direct.
** Why not, I had decided to have exnal SRAM, so let's make use of it
**
** 12/28/98
** o Added 7-level deep hardware LIFO to implement pushacc/popacc
** instructions
** o Implemented pushacc and popacc instructions in the sequencer.v
**
** 12/27/98
** o Fixed a number of bugs, including CMPACC (reg direct) and ALU ops (reg
** direct) being decoded as same.
**
** 12/26/98
** o Shortenend the PC to 12 bits from 16, to reduce design size.
** o REduced the datapath width to 8 from 16, to reduce design size.
**
** Lots of previous history not accounted for. Started to work on POPCORN
** about 12/12/98
*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -