06.npl Cpu 07
06.npl Cpu 07
Non-Pipelined CPU
06-2757575 X 62371 kjlee@mail.ncku.edu.tw
KJLEE
Non-Pipelined CPU
Instruction set model-Behavioral model
Verilog code for each module Verilog functions and tasks A complete Verilog code for non-pipelined CPU
Structural model
Verilog code for each building blocks Interconnection between building blocks Memory Controller design
Non-pipe-CPU.2
NCKUEE-KJLEE
Non-pipe-CPU.3
NCKUEE-KJLEE
Processor 12 32 PC IR
5 PSR
Register File
212
ALU
Non-pipe-CPU.4
NCKUEE-KJLEE
Instructions
Name NOP BRANCH LOAD STORE ADD MULTIPLY COMPLEMENT SHIFT ROTATE HALT
VLSI System Design
Mnemonic Opcode NOP BRA LD STR ADD MUL CMP SHF ROT HLT 0 1 2 3 4 5 6 7 8 9
Non-pipe-CPU.5
Format (inst dst, src) NOP BRA LD STR ADD MUL CMP SHF ROT HLT
NCKUEE-KJLEE
Operand addressing
Mem mem1 reg src cc cnt Memory address Memory address or immediate value Any register index Any register index, or immediate value Condition code Shift/rotate count, >0:right,<0:left,+/-32
Non-pipe-CPU.6
NCKUEE-KJLEE
Instruction Format
31 4 bits 28 27 4 bits 24 23 12 bits 12 11 12 bits 0
IR[11:0] : destination address IR[23:12]: source address or shift/rotate count IR[27:24]: condition code or IR[27]: source type 0=reg (mem), 1=imm IR[26]: destination type 0=reg (mem), 1=imm (Not valid)
IR[31:28]: Opcode
Max # of instructions = 24 = 16
VLSI System Design Non-pipe-CPU.7 NCKUEE-KJLEE
Condition codes
A C E P Z N Always Carry Even Parity Zero Negative 0 1 2 3 4 5 Processor register PSR [0] PSR [1] PSR [2] PSR [3] PSR [4] status Carry Even Parity Zero Negative
Non-pipe-CPU.8
NCKUEE-KJLEE
Instruction Examples
CC or SRC type OP 0 1 2 3 4 5 6 7 8 SRC DEST Mnemonic // LD R1,#0 // LD R0, Mem[9] // BRA addr[4], CCE // ADD R1, #1 // SHF R0, #1 // BRA addr[7], ZERO // BRA addr[2], ALW // STR Mem[10], R1 // HLT
Non-pipe-CPU.9
NCKUEE-KJLEE
Non-pipe-CPU.10
NCKUEE-KJLEE
// Register declarations reg [WIDTH-1:0] MEM[0:MEMSIZE-1], RFILE[0:MAXREGS-1], ir,src1,src2; reg [WIDTH:0] result ; reg [ADDRSIZE-1:0] pc ; reg [4:0] psr; reg dir; reg reset; integer
VLSI System Design
i;
Non-pipe-CPU.11 NCKUEE-KJLEE
Initialization process
task apply_reset ; begin reset = 1; #CYCLE reset = 0; pc = 0; end endtask initial begin : prog_load $readmemb(sisc.prog,MEM); $monitor(%d %d %h %h %h, $time, pc,RFILE[0],RFILE[1], RFILE[2]); apply_reset ; end $readmemb: load a test program into the memory array MEM. The initial state of the simulation model should be equivalent to the state of the real hardware at power-on. To initialize the system, the test program is loaded, a monitor is set up, and the reset sequence is applied to the initial block. The initial block is executed only once at the start of the simulation. It executes concurrently with the always block.
Non-pipe-CPU.13
NCKUEE-KJLEE
always begin : main_process if (!reset) begin #CYCLE fetch ; #CYCLE execute ; #CYCLE write_result ; end else #CYCLE ; end
Note: The else clause is needed as the always process becomes a zero delay infinite loop when reset is high.
Non-pipe-CPU.14
NCKUEE-KJLEE
task tsk; input i1, i2; output o1, o2; $disp(Task tsk, i1=%0b, i2=%0b,i1,i2); #1 o1 = i1 & i2; #1 o2 = i1 | i2; endtask
Non-pipe-CPU.15
NCKUEE-KJLEE
Timing Control
I/O
At least one input, no output. Result returned by function name In an expression e.g. , i = func (a, b, c) Combinational Yes
Non-pipe-CPU.16
NCKUEE-KJLEE
Fetch task
task fetch ; // fetch instruction and increment PC begin ir = MEM[pc]; pc = pc + 1; end
Non-pipe-CPU.17
NCKUEE-KJLEE
Execution task
task execute ; begin case( OPCODE) NOP : ; BRA : begin if (checkcond( CCODE)) pc = DST: end HLT : begin $display(Halt ...) ; $stop ; end LD : begin clearcondcode ; if (SRCTYPE) RFILE[DST] = SRC else RFILE[DST]= MEM[SRC] ; setcondcode({1b0,RFILE[DST]}); end // SRC ir[23:12], SRCTYPE ir[27]
Non-pipe-CPU.18
NCKUEE-KJLEE
STR : begin clearcondcode ; if (SRCTYPE) begin MEM[DST] =SRC; setcondcode({21b0,`SRC}); end else begin MEM[DST]=RFILE[SRC]; setcondcode({1b0,RFILE[SRC]}); end end ADD : begin clearcondcode ; src1 = getsrc(ir); src2 = getdst(ir); result = src1+src2; setcondcode(result); end ... // See full listing at the end of the chapter default: $display(Invalid Opcode found at,$time); endcase end endtask
VLSI System Design Non-pipe-CPU.19 NCKUEE-KJLEE
Non-pipe-CPU.20
NCKUEE-KJLEE
// Declare Registers and Memory reg [WIDTH-1:0] MEM[0:MEMSIZE-1], // MEMORY RFILE[0:MAXREGS-1], // Register File ir, // Instruction Register src1, src2 ; // Alu operation registers reg[WIDTH:0] result ; // ALU result register reg[SBITS-1:0] psr; // Processor Status Register reg[ADDRSIZE-1:0] pc ; // Program counter reg dir; // rotate direction reg reset; // System Reset integer i; // useful for interactive debugging // General definitions define TRUE 1 define FALSE 0 define DEBUG_ON debug = 1 define DEBUG_OFF debug = 0 // Define Instruction fields define OPCODE ir[31:28] define SRC ir[23:12]
VLSI System Design Non-pipe-CPU.21 NCKUEE-KJLEE
define DST ir[11:0] define SRCTYPE ir[27] // source type, 0=reg (mem for LD), 1=imm define DSTTYPE ir[26] // destination type, 0=reg, 1=imm define CCODE ir[27:24] define SRCNT ir[23:12] // Shift/rotate count -= left, +=right // Operand Types define REGTYPE 0 define IMMTYPE 1 // Define opcodes for each instruction define NOP define BRA define LD define STR define ADD define MUL define CMP define SHF define ROT define HLT 4b0000 4b0001 4b0010 4b0011 4b0100 4b0101 4b0110 4b0111 4b1000 4b1001
define CARRY psr[0] define EVEN psr[1] define PARITY psr[2] define ZERO psr[3] define NEG psr[4] // Define Condition Codes define CCC 1 // Result has carry define CCE 2 // Result is even define CCP 3 // Result is odd parity define CCZ 4 // Result is Zero define CCN 5 // Result is Negative define CCA 0 // Always define RIGHT 0 // Rotate/Shift Right define LEFT 1 // Rotate/Shift Left // Function for ALU operands and result === contains x, z compare. function [WIDTH-1:0] getsrc; input [WIDTH-1:0] in; begin if (SRCTYPE === REGTYPE) getsrc = RFILE[SRC] ; else getsrc = SRC ; // immediate type end endfunction
VLSI System Design Non-pipe-CPU.23 NCKUEE-KJLEE
function [WIDTH-1:0] getdst; input [WIDTH-1:0] in; begin if (DSTTYPE === REGTYPE) begin getdst = RFILE[DST]; end else begin // immediate type $display(Error:Immediate data cant be destination.); end end endfunction // Functions / tasks for Condition Codes function checkcond; //Returns 1 if condition code is set . input [4:0] ccode; begin case (ccode) CCC : checkcond = CARRY ; CCE : checkcond = EVEN ; CCP : checkcond = PARITY ; CCZ : checkcond = ZERO ; CCN : chedkcond = NEG ; CCA : checkcond = 1; endcase end endfunction
VLSI System Design Non-pipe-CPU.24 NCKUEE-KJLEE
task clearcondcode ; // Reset condition codes in PSR begin psr = 0; end endtask task setcondcode ; // Compute the condition codes and set PSR input [WIDTH:0] res; //33 bit result register begin CARRY = res[WIDTH]; EVEN = ~res[0]; PARITY = ^res ; ZERO = ~(|res) ; NEG = res[WIDTH-1]; end endtask // Main Tasks - fetch, execute, write_result task fetch ; // Fetch the instruction and increment PC. begin ir = MEM[pc] ; pc = pc + 1 ; end endtask
VLSI System Design Non-pipe-CPU.25 NCKUEE-KJLEE
task execute ; // Decode and execute the instruction. begin case(`OPCODE) NOP : ; BRA : if (checkcond( CCODE) == 1) pc = DST; LD : begin clearcondcode ; if (SRCTYPE) RFILE[DST] = SRC ; else RFILE[DST]=MEM[SRC] ; setcondcode({1bo,RFILE[DST]}) ; end STR : begin clearcondcode if (SRCTYPE) MEM[DST] = SRC; else MEM[DST] = RFILE[SRC] ; if (SRCTYPE) setcondcode({21b0,`SRC}) else setcondcode ({1b0,RFILE[SRC]}); end ADD : begin clearcondcode ; src1 = getsrc(ir); src2 = getdst(ir); result = src1 + src2; setcondcode(result); end
VLSI System Design Non-pipe-CPU.26 NCKUEE-KJLEE
MUL : begin clearcondcode ; src1 = getsrc(ir) ; src2 = getdst(ir) ; result = src1 * src2 ; setcondcode(result) ; end CMP : begin clearcondcode ; src1 = getsrc(ir) ; result = ~src1 ; setcondcode (result) ; end SHF : begin clearcondcode ; src1 = getsrc(ir) ; src2 = getdst(ir) ; i = src1[ADDRSIZE-1:0] ; result = (i>=0) ? (src2 >> i) : (src2 << -i) ; setcondcode(result); end
Non-pipe-CPU.27
NCKUEE-KJLEE
ROT : begin clearcondcode ; src1 = getsrc(ir) ; src2 = getdst(ir) ; dir = (src1[ADDRSIZE-1] >=0 ? RIGHT : LEFT ; i = ( src1[ADDRSIZE-1] >=0)? src1 : -src1[ADDRSIZE-1:0] ; while (i > 0) begin if (dir == RIGHT) begin result = src2 >> 1 ; result[WIDTH-1] = src2 [0] ; end else begin result = src2 << 1 ; result[0] =src2[WIDTH-1] ; end i= i - 1 ; src2 = result ; end //end of while setcondcode(result); end HLT : begin $display(Halt ... ); $stop ; end default : $display (Error : Illegal Opcode . ); endcase end endtask
Non-pipe-CPU.28
NCKUEE-KJLEE
// Write the result in register file or memory. task write_result ; begin if ((OPCODE >= ADD) && (OPCODE < HLT)) begin if(DSTTYPE == REGTYPE) RFILE[DST] = result ; else MEM[DST] = result ; end end endtask // Debugging help task apply_reset ; begin reset = 1; #CYCLE reset = 0; pc = 0; end endtask
Non-pipe-CPU.29
NCKUEE-KJLEE
task disprm ; input rm ; input [ADDRSIZE-1:0] adr1, adr2 ; begin if (rm == REGTYPE) begin while (adr2 >= adr1) begin $display(REGFILE[%d] = %d\n,adr1,RFILE[adr1]); adr1 = adr1 +1; end end else begin while (adr2 >= adr1) begin $display(MEM[%d]=%d\n,adr1,MEM[adr1]); adr1= adr1 + 1; end end end endtask
Non-pipe-CPU.30
NCKUEE-KJLEE
// Initial and always blocks initial begin : prog_load $readmemb(sisc.prog,MEM); $monitor(%d %d %h %h %h, $time,pc,RFILE[0], RFILE[1]; RFILE[2]) ; apply_reset ; end always begin : main_process if (!reset) begin #CYCLE fetch ; #CYCLE execute ; #CYCLE write_result ; end else #CYCLE ; end endmodule
Non-pipe-CPU.31
NCKUEE-KJLEE
A test program
Address OP
0000 0001 0010 0011 0100 0101 0110 0111 1000 1001 1010
SRC
DEST
Mnemonic
// LD R1,#0 // LD R0,NMBR // START:BRA L1,CCE // ADD R1,#1 // L1:SHF R0,#1 // BRA L2,ZERO // BRA START,ALW // L2:STR RSLT, R1 // HLT // NMBR:5555aaaa // RSLT:00000000
0010_1000_0000_0000_0000_0000_0000_0001 0010_0000_0000_0000_1001_0000_0000_0000 0001_0010_0000_0000_0000_0000_0000_0100 0100_1000_0000_0000_0001_0000_0000_0001 0111_1000_0000_0000_0001_0000_0000_0000 0001_0100_0000_0000_0000_0000_0000_0111 0001_0000_0000_0000_0000_0000_0000_0010 0011_0000_0000_0000_0001_0000_0000_1010 1001_1111_1111_1111_1111_1111_1111_1111 0101_0101_0101_0101_1010_1010_1010_1010 0000_0000_0000_0000_0000_0000_0000_0000
Non-pipe-CPU.33
NCKUEE-KJLEE
PC+logic
pc_dataout m_rw (1)_
IR+logic
ir_dataout rf_write rf_dataw rf_addrw rf_data1 rf_addr1 rf_data2 rf_addr2 alu_src2 alu_function
Register file
Controller
psr_dataout
2 4
alu_src1
PSR+logic
psr_cmd psr_datain
VLSI System Design
ALU
alu_result
Non-pipe-CPU.35 NCKUEE-KJLEE
contd
NCKUEE-KJLEE
rf_data1, rf_data2, alu_src1, alu_src2 ; wire [WIDTH:0] alu_result; // Instantiate predefined building blocks clock CLK (phase1,phase2); memory MEM (phase1,phase2,m_data,m_addr,m_rw_); regfile RFILE (phase1,phase2,rf_dataw,rf_addrw, rf_write,rf_data1,rf_addr1, rf_data2,rf_addr2); prog_cntr PC (phase1,phase2,pc_addrout, pc_addrin, pc_cmd,reset); ins_reg IR (phase1,phase2,ir_dataout,ir_datain, ir_cmd,reset); pro_status_reg PSR (phase1,phase2,psr_dataout, psr_datain, psr_cmd,reset); alu ALU (phase1,phase2,alu_result, alu_function,alu_src1,alu_src2); cntrl CONTROLLER (phase1,phare2,halt,reset, m_data,m_addr,m_rw_, rf_dataw,rf_addrw,rf_write, rf_data1,rf_addr1,rf_data2,rf_addr2, pc_addrout,pc_addrin,pc_cmd, ir_dataout,ir_datain,ir_cmd, psr_daataout,psr_datain,psr_cmd, alu_result,alu_function, alu_src1,alu_src2); endmodule
VLSI System Design Non-pipe-CPU.37 NCKUEE-KJLEE
Datapath
Instructions
Arithmetic functions: + , - , * , / , ... Logic functions: AND,OR,NOT,... Special functions: shift, rotate, comparison,etc.
input
Barrel Shifter
Adder
output
Non-pipe-CPU.38
NCKUEE-KJLEE
Incrementer
module increment (in,control,out, Nflag,Pflag,Eflag,Zflag,Cflag); input [31:0] in; // input operand input control; // increment or pass output [31:0] out; // result operand output Eflag,Zflag,Cflag,Nflag,Pflag; parameter LOAD = 0, INCR = 1, TRUE = 1, FALSE = 0; wire[31:0] out= (control == INCR) ? (in+1) : in; wire Cflag = (~(|out) && control == INCR) ? TRUE : FALSE; // The carry flag is set if the control increments // the input and if the output is zero // set condition codes -- remaining flags set_flags U1(out,Nflag,Pflag,Eflag, Zflag); endmodule
VLSI System Design Non-pipe-CPU.39 NCKUEE-KJLEE
Comments on Incrementes
Increment or bypass depending on the input control signal. If decrement is needed, then
wire [31:0] out= (control === INCR) ? (in+1): (control === DECR) ? (in-1) : in;
Non-pipe-CPU.40
NCKUEE-KJLEE
Nflag: negative flag, Pflag: parity flag, Eflag: even flag, Zflag: zero flag
Non-pipe-CPU.41
NCKUEE-KJLEE
Adder / Subtracter
module adder (operand1,operand2, result, control, Cflag,Pflag,Eflag,Zflag,Nflag); input [31:0] operand1,operand2; input control; output [31:0] result; output Cflag, Pflag, Eflag, Zflag, Zflag; parameter ADD = 0; SUB = 1; assign {Cflag, result} = (control == ADD) ? (operand1+operand2) : (operand1 - operand2) ; // set condition codes -- remaining flags set_flags U2(result, Nflag, Pflag, Eflag, Zflag); endmodule
Non-pipe-CPU.42
NCKUEE-KJLEE
Non-pipe-CPU.43
NCKUEE-KJLEE
begin:carry_generation integer I; carrychain[0] = g[0] +(p[0]&cin); for(I=1;I<=31;I=I+1) begin #0 // force evaluation carrychain[i] = g[i]+(p[i]&carrychain[i-1]); end end wire [32:0] shiftedcarry = { carrychain,cin}; // Compute the sum wire [31:0] result = p ^ shiftedcarry; // Carry out wire cout = shfitedcarry[32]; endmodule You may redesign this adder/substrator using a real CLA method!
VLSI System Design Non-pipe-CPU.44 NCKUEE-KJLEE
Barrel-shifter
module barrel_shifter (in,direction, type, count, result, Nflag, Pflag, Eflag, Zflag); input input input input output output in; // input operand direction; // left or right type // shift or rotate [4:0] count; // shift count [31:0] result; // result operand Nflag, Pflag, Eflag, Zflag; = = = = 0, 1, 0, 1; [31:0]
// Invoke the shift/rotate functions // to obtain the result. wire [31:0] result=(type==ROTATE)? (rotate(in,count,direction)) : (shift(in,count,direction)) ; // This function implements the SHF instruction
VLSI System Design Non-pipe-CPU.45
contd.
NCKUEE-KJLEE
function [31:0] shift; input [31:0] in; input [3:0] count; input direction; begin shift = (direction === RIGHT) ? (in >> count) : (in << count) ; end endfunction // This function implements the ROT instruction function [31:0] rotate; input [31:0] in; input [3:0] count; input direction; reg [31:0] reg_rotate; reg t; integer i;
Non-pipe-CPU.46
NCKUEE-KJLEE
begin reg_rotate=in[31:0]; if (direction === RIGHT) for(i=0;i<count; i=i+1) begin t=reg_rotate[0]; reg_rotate[30:0]= reg_rotate[31:1]; reg_rotate[31]=t; end else if(direction === LEFT) for(i=0;i<count;i=i+1) begin t=reg_rotate[31]; reg_rotate[31:1]= reg_rotate[30:0]; reg_rotate[0]=t; end rotate=reg_rotate; end endfunction // set cond. codes -- remaining flags set_flags U3(result,Nflag,Pflag, Eflag,Zflag); endmodule
VLSI System Design Non-pipe-CPU.47
Rotation is implemented by repeated shifts. The implementation here is also not efficient. See Westes textbook for better implementations.
NCKUEE-KJLEE
Multiplier
module multiplier (operand1, operand2, result, Cflag, Pflag, Eflag, Zflag, Nflag); input [15:0] operand1,operand2; output [31:0] result; output Cflag, Pflag, Eflag, Zflag, Nflag; assign {Cflag,result} = operand1 * operand2; set_flags U4 (result,Nflag,Pflag,Eflag,Zflag); endmodule The inputs to the multiplier are 16-bits. More input bits would greatly increase the complexity. Having 32-bit operands would require the processor either to have a 64bit data bus or to multiplex the data in two consecutive cycles.
VLSI System Design Non-pipe-CPU.48 NCKUEE-KJLEE
contd.
Generally, design and layout of RAMs and Register files are done manually or generated automatically through other special purpose tools.
VLSI System Design Non-pipe-CPU.49 NCKUEE-KJLEE
// Write cycle always @(posedge ph2 or addr or datain or wrenable) begin : do_write if(ph2 == 1 && wrenable == 1) ram_data[addr[11:0]] = datain; end specify specparam tSetup=0.75:1.0:1.25, tHold =0.25:0.5:0.75; $setup(datain,ph2,tSetup); $hold (ph2,datain,tHold); endspecify endmodule
result
mask The CAMs are frequently used to perform parallel search and comparison operation.
VLSI System Design Non-pipe-CPU.51 NCKUEE-KJLEE
Model of a CAM
module cam_ram (comparand, mask, cam_result,......); ......................................... output [WORDS:0] cam_result; input [31:0] comparand, mask; reg [31:0] comparand, mask; reg [31:0] ram_data[WORDS:0]; // CAM as a register array // associative operation wire [WORDS:0] cam_result = {((cam_data[WORDS] & mask)==comparand)? 1h1:1h0, ((cam_data[WORDS-1]&mask)==comparand)? 1h1:1h0, ............................. ............................. ((cam_data[0] &mask)==comparand)? 1h1:1h0}; endmodule
Non-pipe-CPU.52
NCKUEE-KJLEE
Register file
In this example, 2 read ports and one write port.
timescale 1ns / 1ps module reg_file (ph1,ph2,Aaddr,Baddr, wrenable, datain, Adataout, Bdataout); input input input input output reg reg ph1, ph2; // clock phase wrenable; // write-enable [3:0] Aaddr,Baddr; // address [31:0] datain; // input data [31:0] Adataout,Bdataout; // output data buses [31:0] Aregout, Bregout; // holds data values [31:0] ram_data[15:0];; // RAM register array
parameter ACCESS_TIME=5; // read cycle wire [31:0] #ACCESS_TIME Adataout=Aregout; wire [31:0] #ACCESS_TIME Bdataout=Bregout;
contd.
Non-pipe-CPU.53
NCKUEE-KJLEE
always @(posedge ph1 or Aaddr or Baddr or wrenable) if(ph1==1 && wrenable==0) begin Aregout=ram_data[Aaddr[3:0]]; Bregout=ram_data[Baddr[3:0]]; end // write cycle always @(posedge ph2 or Aaddr or datain or wrenable) if(ph2==1 && wrenable==1) ram_data[Aaddr[3:0]]=datain; specify specparam tSetup=1.0,tHold=0.5; $setup(datain,ph2,tSetup); $hold(ph2,datain,tHold); endspecify endmodule
Non-pipe-CPU.54
NCKUEE-KJLEE
initial masterclk=0; // oscillation at a given period always begin #MASTERCLK_PERIOD/2 masterclk=~masterclk; end endmodule
Non-pipe-CPU.55
NCKUEE-KJLEE
Two-phase clock
module phase_gen (masterclk,enable,ph1,ph2); parameter NON_OVERLAP=1; input masterclk,enable; output ph1,ph2; reg ph1,ph2; initial begin // reset all signals ph1=0; ph2=0; reset=0; end always @(posedge masterclk) begin: generate_phases if(enable==1) begin ph2=0; #NON_OVERLAP ph1=1; @(posedge masterclk) begin ph1=0; #NON_OVERLAP ph2=1; end end end contd.
VLSI System Design Non-pipe-CPU.56 NCKUEE-KJLEE
always @(posedge masterclk) begin if(enable==0) begin reset=1; @(posedge masterclk) begin if(enable==0 && reset==1) begin ph1=0; ph2=0; Reset only when disabled reset=0; end for 2 consecutive positive else reset=0; end edges. end end endmodule
(overlap = 0)
Non-pipe-CPU.58
NCKUEE-KJLEE
PC+logic
pc_dataout m_rw (1)_
IR+logic
ir_dataout rf_write rf_dataw rf_addrw rf_data1 rf_addr1 rf_data2 rf_addr2 alu_src2 alu_function
Register file
Controller
psr_dataout
alu_src1
PSR+logic
psr_cmd psr_datain
VLSI System Design
ALU
alu_result
Non-pipe-CPU.59 NCKUEE-KJLEE
NOP BRA LOAD STORE ADD MUL CMP SHF ROT HALT FETCH EXECUTE WRITE
4h0 4h1 4h2 4h3 4h4 4h5 4h6 4h7 4h8 4h9 2h1 2h2 2h3
Non-pipe-CPU.60
contd.
NCKUEE-KJLEE
input input input input input inout reg output output output output output output
pc_dataout; state; psr_dataout; ir_dataout, rf_data1, rf_data2; alu_result; m_data; m_data_reg; rf_write, m_rw_; [1:0] pc_cmd, ir_cmd, psr_cmd; [3:0] rf_addrw, rf_addr1, rf_addr2, alu_function; [4:0] psr_datain; [11:0] pc_datain, m_addr; [31:0] ir_datain, rf_dataw, alu_src1, alu_src2; CLEAR_REG HOLD_VAL LOAD_REG COUNTUP IR_OPCODE IR_SRC_TYP IR_DST_TYP IR_SRC IR_SRC_REG IR_DST 2h0 2h1 2h2 2h3 ir_dataout[31:28]; ir_dataout[27] ir_dataout[26] ir_dataout[23:12] ir_dataout[15:12] ir_dataout[11:0]
Non-pipe-CPU.61
define define define define define define define define define define
contd.
NCKUEE-KJLEE
ir_dataout[3:0] 1 1 0 0 1 ir_dataout[27:24]
wire m_rw_=(IR_OPCODE===STORE && state===WRITE) ? MEM_WRITE : MEM_READ; wire [11:0] maddr = (state===FETCH) ? pc_dataout : ((IR_OPCODE === STORE) ? IR_DST : IR_SRC); wire [31:0] m_data = m_data_reg; //m_data is an inout. always @ (state) begin if(state ===EXECUTE || state === WRITE) begin if (IR_OPCODE ===STORE && IR_SRC_TYP != IMMEDIATE) m_data_reg=rf_data1; else if(IR_OPCODE===STORE &&IR_SRC_TYP===IMMEDIATE) m_data_reg=IR_SRC; else m_data_reg= 32hz; end contd. else m_data_reg = 32hz; // m_data is a bidirectional bus end // which gets its value from m_data_reg.
VLSI System Design Non-pipe-CPU.62 NCKUEE-KJLEE
wire [3:0] alu_function= (IR_OPCODE>=ADD && IR_OPCODE<=ROT && state===EXECTUE) ? IR_OPCODE : NOP; wire [31:0] alu_src1=(IR_SRC_TYP != IMMEDIATE) ? ( (IR_OPCODE !=ROT && IR_OPCODE !=SHF) ? rf_data1 : IR_SRC ) : IR_SRC; wire wire wire wire [31:0] [3:0] [3:0] [3:0] alu_src2=rf_data2; rf_addr1=IR_SRC_REG; rf_addr2=IR_DST_REG; rf_addrw=IR_DST_REG;
wire rf_write=(IR_OPCODE != BRA && IR_OPCODE != STORE && IR_OPCODE != NOP && IR_OPCODE != HALT && state===WRITE) ? REG_WRITE : REG_READ; wire [31:0] rf_dataw=(rf_write && IR_OPCODE === LOAD && IR_SRC_TYP != IMMEDIATE)? m_data : ((rf_write && IR_OPCODE === LOAD && IR_SRC_TYP===IMMEDIATE) ? IR_SRC: alu_result);
VLSI System Design Non-pipe-CPU.63
contd.
NCKUEE-KJLEE
wire [1:0] ir_cmd=(state === FETCH) ? LOAD_REG : ((state ===EXECUTE)? HOLD_VAL : ((IR_OPCODE ===HALT)? CLEAR_REG: HOLD_VAL ) ); wire [31:0] ir_datain=(ir_cmd === LOAD_REG) ? m_data : ((ir_cmd === CLEAR_REG) ? 32h0 : ir_dataout); wire branch_taken = | (IR_CCODES & psr_dataout); wire [1:0] pc_cmd =(state === WRITE)? ((IR_OPCODE === HALT) ?CLEAR_REG : (branch_taken ? LOAD_REG : COUNTUP)) : HOLD_VAL ; wire [11:0] pc_datain=(state==WRITE)? ((IR_OPCODE == HALT) ? 12h0 : branch_taken ? IR_DST : (pc_dataout + 1))) : pc_dataout;
contd.
Non-pipe-CPU.64
NCKUEE-KJLEE
wire [1:0] psr_cmd=(IR_OPCODE >= ADD && IR_OPCODE <= ROT && state === WRITE) ? LAOD_REG: ((IR_OPCODE === HALT) ? CLEAR_REG : HOLD_VAL); wire zflag=~(|alu_result[31:0]); wire eflag=~(alu_result[0]); wire pflag=^(alu_result[31:0]); wire [4:0] psr_datain=(psr_cmd === CLEAR_REG) ? 5h0 : ((psr_cmd === LOAD_REG) ? {alu_result[31], zflag,pflag,eflag,alu_result[32]} : psr_dataout); endmodule
Non-pipe-CPU.65
NCKUEE-KJLEE