verilog - implementando processador
TRANSCRIPT
Verilog HDL
ECE 4680 Computer Architecture
Verilog Presentation 2
Outline
• Half Adder and Testbench• 4-to-1 Multiplexor• 2-to-4 Decoder• ALU• Register File• CPU
A Verilog module that defines a half-adder
1-bit adder: This adder is called a full adder; it is also called a (3,2) adder because it has 3 inputs and 2 outputs. An adder with only the a and b inputs is called a (2,2) adder or half adder.
1-bit Half Adder
module half_adder (A, B, Sum,Carry);
input A,B; //two 1-bit inputsoutput Sum, Carry; //two 1-bit outputsassign Sum = A ^ B; //sum is A xor Bassign Carry = A & B; //Carry is A and B
endmodule
Test bench module for half adder module
module half_adder_test();reg ia, ib;half_adder h1(ia,ib,S0,C0);Initialbegin
#0 ia=0; ib=0;#1 ia=0; ib=1;#1 ia=1; ib=0;#1 ia=1; ib=1;$finish
endendmodule
4-to-1 Multiplexor
Sel
In1
In2
In3
In4
OutMUX
4-to-1 Multiplexor with four 32-bit inputs
module Mult4to1 (In1,In2,In3,In4,Sel,Out);input [31:0] In1, In2, In3, In4; // four 32-bit inputsinput [1:0] Sel; // selector signaloutput reg [31:0] Out; // 32-bit outputalways @(In1, In2, In3, In4, Sel)
case (Sel) // a 4->1 multiplexor0: Out <= In1;1: Out <= In2;2: Out <= In3;default: Out <= In4;
endcaseendmodule
Decoderen
Decoder
Y3
Y2
Y1
Y0
A
B
Decodermodule decoder 2 to 4 (Y3, Y2, Y1, Y0, A, B, en);output Y3, Y2, Y1, Y0;input A, B;input en;reg Y3, Y2, Y1, Y0;
always @(A or B or en) beginif (en == 1)case ( {A,B} )2'b00: {Y3,Y2,Y1,Y0} = 4'b1110;2'b01: {Y3,Y2,Y1,Y0} = 4'b1101;2'b10: {Y3,Y2,Y1,Y0} = 4'b1011;2'b11: {Y3,Y2,Y1,Y0} = 4'b0111;default: {Y3,Y2,Y1,Y0} = 4'bxxxx;endcase
if (en == 0){Y3,Y2,Y1,Y0} = 4'b1111;endendmodule
MIPS ALU in Verilog
•The ALU has 7 ports. These ports are the two input ports a and b, the output result port, ALU Operation control, zero detect output, overflow detect output, and the carryout output.
A Verilog behavioral definition of a MIPS ALU
module MIPSALU (ALUctl, A, B, ALUOut, Zero);input [3:0] ALUctl;input [31:0] A,B;output reg [31:0] ALUOut;output Zero;assign Zero = (ALUOut==0); //Zero is true if ALUOut is 0always @(ALUctl, A, B) begin //reevaluate if these change
case (ALUctl)0: ALUOut <= A & B;1: ALUOut <= A | B;2: ALUOut <= A + B;6: ALUOut <= A - B;7: ALUOut <= A < B ? 1 : 0;12: ALUOut <= ~(A | B); //result is nordefault: ALUOut <= 0;
endcaseendendmodule
The MIPS ALU control•a piece of combinational control logic.module ALUControl (ALUOp, FuncCode, ALUCtl);input [1:0] ALUOp;input [5:0] FuncCode;output [3:0] reg ALUCtl;
always case (FuncCode)32: ALUCtl <=2; // add34: ALUCtl <=6; //subtract36: ALUCtl <=0; // and37: ALUCtl <=1; // or39: ALUCtl <=12; // nor42: ALUCtl <=7; // slt
default: ALUCtl <=15; // should not happenendcase
endmodule
A Register File
• A register file consists of a set of registers that can be read and written by supplying a register number to be accessed.• The read ports cab be implemented with a pair of multiplexors.• The write port can be implemented with a decoder
The implementation of two read ports for a register file with n registerscan be done with a pair of n-to-1 multiplexors each 32 bits wide.
The write port for a register file is implemented with a decoder that isused with the write signal to generate the C input to the registers.
A MIPS register file written in behavioral Verilog
•This register file writes on the rising clock edge.module registerfile (Read1,Read2,WriteReg,WriteData,
RegWrite,Data1,Data2,clock);input [5:0] Read1,Read2,WriteReg; // the registers numbers to read or writeinput [31:0] WriteData; // data to writeinput RegWrite, // The write controlclock; // the clock to trigger writeoutput [31:0] Data1, Data2; // the register values readreg [31:0] RF [31:0]; // 32 registers array each 32 bits longassign Data1 = RF[Read1];assign Data2 = RF[Read2];
always begin // write the register with new value if Regwrite is high@(posedge clock) if (RegWrite) RF[WriteReg] <= WriteData;end
endmodule
Using a Hardware Description Languageto Design and Simulate a Processor
The below Verilog example gives a behavioral specification of the multicycle implementation of the MIPS processor. This version does not use the structural datapath. Because of the use of behavioral operations, it would be difficult to synthesize a separate datapath and control unit with any reasonable efficiency.This version also demonstrates another approach to the control by using a Mealy finite state machine.The use of a Mealy machine, which allows the output to depend both on inputs and the current state, allow us to decrease the total number of states to 5.
A behavioral specification of themulticycle MIPS design
module CPU (clock);parameter LW = 6'b100011, SW = 6'b101011, BEQ=6'b000100, J=6’d2;input clock; //the clock is an external input// The architecturally visible registers and scratch registers for implementationreg [31:0] PC, Regs[0:31], Memory [0:1023], IR, ALUOut, MDR, A, B;reg [2:0] state; // processor statewire [5:0] opcode; //use to get opcode easilywire [31:0] SignExtend,PCOffset; //used to get sign extended offset fieldassign opcode = IR[31:26]; //opcode is upper 6 bits//sign extension of lower 16-bits of instructionassign SignExtend = {{16{IR[15]}},IR[15:0]}; assign PCOffset = SignExtend << 2; //PC offset is shifted
The state machine--triggered on a rising clock
// set the PC to 0 and start the control in state 0initial begin PC = 0; state = 1; endalways @(posedge clock) begin//make R0 0 //short-cut way to make sure R0 is always 0Regs[0] = 0; case (state) //action depends on the state
First step: fetch the instruction, increment PC, go to next state
1: begin IR <= Memory[PC>>2];PC <= PC + 4;state=2; //next stateend
Second step: Instruction decode, register fetch, also compute branch address
2: begin A <= Regs[IR[25:21]];B <= Regs[IR[20:16]];state= 3;// compute PC-relative branch targetALUOut <= PC + PCOffset; end
Third step: Load/store execution, ALU execution, Branch completion
3: begin state =4; // default next state
if ((opcode==LW) |(opcode==SW)) ALUOut <= A + SignExtend; //compute effective addresselse if (opcode==6'b0) case (IR[5:0]) //case for the various R-type instructions
32: ALUOut= A + B; //add operationdefault: ALUOut= A; //other R-type operations: subtract, SLT, etc.Endcase
else if (opcode == BEQ) beginif (A==B) PC <= ALUOut; // branch taken--update PCstate = 1;end
else if (opocde=J) beginPC = {PC[31:28], IR[25:0],2'b00}; // the jump target PCstate = 1;end //Jumps
else ; // other opcodes or exception for undefined instruction would go hereend
Four step: Write ALU result, Read/write the memory
4: begin
if (opcode==6'b0) begin //ALU OperationRegs[IR[15:11]] <= ALUOut; // write the resultstate =1;end //R-type finishes
else if (opcode == LW) begin // load instructionMDR <= Memory[ALUOut>>2]; // read the memorystate =5; // next state
endelse if (opcode == SW) beginMemory[ALUOut>>2] <= B; // write the memorystate = 1; // return to state 1end //store finisheselse ; // other instructions go here
end
Five step: LW is the only instruction still in execution
5: begin // write the MDR to the registerRegs[IR[20:16]] = MDR; state = 1;end //complete a LW instruction
endcaseend
endmodule
Questions?