?? pcpu.v
字號:
// Project #2: 16-bit pipeline processor// Verilog source file for "System LSI design"// 2007.6 T. Ikenaga// // Operation code (please add operaions!)`define NOP 5'b00000`define HALT 5'b00001`define LOAD 5'b00010`define STORE 5'b00011`define ADD 5'b01000`define CMP 5'b01100`define BZ 5'b11010`define BN 5'b11100// FSM for CPU control`define idle 1'b0`define exec 1'b1module pcpu (reset, clock, enable, start, i_addr, i_datain, d_addr, d_datain, d_dataout, d_we, select_y, y);input reset, clock, enable, start;input [15:0] i_datain;output [7:0] i_addr;output [7:0] d_addr;input [15:0] d_datain;output [15:0] d_dataout;output d_we;// for debugginginput [3:0] select_y;output [15:0] y;// definition of registersreg [7:0] pc;reg [15:0] id_ir, ex_ir, mem_ir, wb_ir;reg [15:0] gr [0:7];reg [15:0] reg_A, reg_B, reg_C, reg_C1, smdr, smdr1;reg zf, nf, dw;reg state;// definition of variablesreg [15:0] ALUo;reg [15:0] y;reg next_state;assign i_addr = pc;assign d_we = dw;assign d_addr = reg_C[7:0];assign d_dataout = smdr1;// CPU control (FSM)always @(posedge clock or negedge reset) begin if (!reset) state <= `idle; else state <= next_state; endalways @(state or enable or start or wb_ir[15:11]) begin case (state) `idle : if ((enable == 1'b1) && (start == 1'b1)) next_state <= `exec; else next_state <= `idle; `exec : if ((enable == 1'b0) || (wb_ir[15:11] == `HALT)) next_state <= `idle; else next_state <= `exec; endcase end// IF_module (stage 1)always @(posedge clock or negedge reset) begin if(!reset) begin id_ir <= 16'b0000000000000000; pc <= 8'b00000000; end else if(state==`exec) begin id_ir <= i_datain; if (((mem_ir[15:11] == `BZ) && (zf == 1'b1)) || ((mem_ir[15:11] == `BN) && (nf == 1'b1))) pc <= reg_C[7:0]; else pc <= pc + 1; end end// ID_module (stage 2)always @(posedge clock or negedge reset) begin if(!reset) begin ex_ir <= 16'b0000000000000000; reg_A <= 16'b0000000000000000; reg_B <= 16'b0000000000000000; smdr <= 16'b0000000000000000; end else if(state==`exec) begin ex_ir <= id_ir; if ((id_ir[15:11] == `BZ) || (id_ir[15:11] == `BN)) reg_A <= gr[(id_ir[10:8])]; else reg_A <= gr[(id_ir[6:4])]; if (id_ir[15:11] == `LOAD) reg_B <= {12'b000000000000, id_ir[3:0]}; else if (id_ir[15:11] == `STORE) begin reg_B <= {12'b000000000000, id_ir[3:0]}; smdr <= gr[id_ir[10:8]]; end else if ((id_ir[15:11] == `BZ) || (id_ir[15:11] == `BN)) reg_B <= {8'b00000000, id_ir[7:0]}; else reg_B <= gr[id_ir[2:0]]; end end// EX_module (stage 3)always @(posedge clock or negedge reset) begin if(!reset) begin mem_ir <= 16'b0000000000000000; reg_C <= 16'b0000000000000000; smdr1 <= 16'b0000000000000000; zf <= 1'b0; nf <= 1'b0; dw <= 1'b0; end else if(state==`exec) begin mem_ir <= ex_ir; reg_C <= ALUo; if ((ex_ir[15:11] == `ADD) || (ex_ir[15:11] == `CMP)) begin if (ALUo == 16'b0000000000000000) zf <= 1'b1; else zf <= 1'b0; if (ALUo [15] == 1'b1) nf <= 1'b1; else nf <= 1'b0; end if (ex_ir[15:11] == `STORE) begin dw <= 1'b1; smdr1 <= smdr; end else dw <= 1'b0; end end// MEM_module (stage 4)always @(posedge clock or negedge reset) begin if(!reset) begin wb_ir <= 16'b0000000000000000; reg_C1 <= 16'b0000000000000000; end else if(state==`exec) begin wb_ir <= mem_ir; if (mem_ir[15:11] == `LOAD) reg_C1 <= d_datain; else reg_C1 <= reg_C; end end// WB_module (stage 5)always @(posedge clock or negedge reset) begin if(!reset) begin gr[0] <= 16'b0000000000000000; gr[1] <= 16'b0000000000000000; gr[2] <= 16'b0000000000000000; gr[3] <= 16'b0000000000000000; gr[4] <= 16'b0000000000000000; gr[5] <= 16'b0000000000000000; gr[6] <= 16'b0000000000000000; gr[7] <= 16'b0000000000000000; end else if(state==`exec) begin if (wb_ir[10:8] != 3'b000) if ((wb_ir[15:11] == `LOAD) || (wb_ir[15:11] == `ADD)) gr[wb_ir[10:8]] <= reg_C1; end end// ALU_modulealways @(reg_A or reg_B or ex_ir[15:11]) case (ex_ir[15:11]) `LOAD : ALUo = reg_A + reg_B; `STORE : ALUo = reg_A + reg_B; `ADD : ALUo = reg_A + reg_B; `CMP : ALUo = reg_A - reg_B; `BZ : ALUo = reg_A + reg_B; `BN : ALUo = reg_A + reg_B; default : ALUo = 16'bXXXXXXXXXXXXXXXX; endcase// for debuggingalways @(select_y or gr[1] or gr[2] or gr[3] or gr[4] or gr[5] or gr[6] or gr[7] or reg_A or reg_B or reg_C or reg_C1 or smdr or id_ir or dw or zf or nf or pc) begin case (select_y) 4'b0000 : y = {3'b000, dw, 2'b00, zf, nf, pc}; 4'b0001 : y = gr[1]; 4'b0010 : y = gr[2]; 4'b0011 : y = gr[3]; 4'b0100 : y = gr[4]; 4'b0101 : y = gr[5]; 4'b0110 : y = gr[6]; 4'b0111 : y = gr[7]; 4'b1000 : y = reg_A; 4'b1001 : y = reg_B; 4'b1011 : y = reg_C; 4'b1100 : y = reg_C1; 4'b1101 : y = smdr; 4'b1110 : y = id_ir; default : y = 16'bXXXXXXXXXXXXXXXX; endcase endendmodule
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -