依据此过程,可以将CPU指令集分为四类:
(IF:取指令;ID:译码;EX:执行; MEM:存取数据;WB:数据寄存)
模式1:
指令:LOAD
IF |
ID |
EX |
MEM |
WB |
模式2:
指令:STORE,JMPR,BZ,BNZ,BN,BNN,BC,BNC
IF |
ID |
EX |
MEM |
NOP |
模式3:
指令:CMP,JUMP,NOP
XXXX |
XXXX |
XXXX |
NOP |
NOP |
模式4:
指令: LDIH,ADD,ADDI,ADDC,SUB,SUBI,SUBC,AND,OR,XOR,SLL,SRL,SLA,SRA
IF |
ID |
EX |
NOP |
WB |
在模式4中流水线第四级没有任何有建设性的操作,故可以将流水线第五级(WB阶段)提前一级(滤过)。当然,在对流水线第五级进行提前时,要判断上一条指令是否对WB有进行操作,当上一条指令对WB阶段有操作时,若此时把流水线第五级提前,则会与上一条指令产生冲突;而对于上一条指令为模式2的指令,由于当上一条指令处于第四级时,当前指令处于第三级,还未产生旁路变换,从而不会与旁路过程产生冲突。对于模式3,由于对流水线第五级不做操作,所以无需提前。
代码如下:
`define NOP 5'b00000
`define HALT 5'b00001
`define LOAD 5'b00010
`define STORE 5'b00011
`define LDIH 5'b10000
`define ADD 5'b01000
`define ADDI 5'b01001
`define ADDC 5'b10001
`define SUB 5'b01010
`define SUBI 5'b01011
`define SUBC 5'b10010
`define CMP 5'b01100
//Logical / shift
`define AND 5'b01101
`define OR 5'b01110
`define XOR 5'b01111
`define SLL 5'b00100
`define SRL 5'b00111
`define SLA 5'b00101
`define SRA 5'b00110
//Control
`define JUMP 5'b11000
`define JMPR 5'b11001
`define BZ 5'b11010
`define BNZ 5'b11011
`define BN 5'b11100
`define BNN 5'b11101
`define BC 5'b11110
`define BNC 5'b11111
//Statement
`define idle 1'b0
`define exec 1'b1
/**********************************************************/
module PCPU(
input wire clk, mclk, reset, enable, start,
input wire [15:0] i_datain, d_datain,
output reg d_we,
output reg [7:0] d_addr,// pc,
output reg [15:0] d_dataout,
output wire [7:0] i_addr
);
/**********************************************************/
/**********************************************************/
reg state;
reg [7:0] pc;
reg [15:0] gr[7:0];
reg [15:0] id_ir, wb_ir, mem_ir;
reg [15:0] reg_A, reg_B, smdr=16'b0, ex_ir;
reg [15:0] reg_C, reg_C1;
reg [15:0] smdr1, ALU0;
reg dw, zf, nf, cf, in;
/**********************************************************/
assign i_addr = pc;
/**********************************************************/
//CPU_Control
reg next_state = 1'b0;
always @ (posedge mclk or posedge reset)
begin
if(reset)
state <= `idle;
else
state <= next_state;
end
always @ (*)
begin
case(state)
`idle: begin
if((enable==1'b1)&&(start==1'b1)) next_state <= `exec;
else next_state <= `idle;
end
`exec: begin
if((enable==1'b0)||(wb_ir[15:11]==`HALT)) next_state <= `idle;