67
1 ilding Verilog Models for the MIPS Processor

1 Building Verilog Models for the MIPS Processor

Embed Size (px)

Citation preview

Page 1: 1 Building Verilog Models for the MIPS Processor

1

Building Verilog Models for the MIPS Processor

Page 2: 1 Building Verilog Models for the MIPS Processor

2

The Multicycle Datapath with Control Signals

Address

Read Data(Instr. or Data)

Memory

PC

Write Data

Read Addr 1

Read Addr 2

Write Addr

Register

File

Read Data 1

Read Data 2

ALU

Write Data

IRM

DR

AB

AL

Uo

ut

SignExtend

Shiftleft 2 ALU

control

Shiftleft 2

ALUOpControl

IRWriteMemtoReg

MemWriteMemRead

IorD

PCWrite

PCWriteCond

RegDstRegWrite

ALUSrcAALUSrcB

zero

PCSource

1

1

1

1

1

10

0

0

0

0

0

2

2

3

4

Instr[5-0]

Instr[25-0]

PC[31-28]

Instr[15-0]

Instr[3

1-2

6]

32

28

Page 3: 1 Building Verilog Models for the MIPS Processor

3

AddrCtl

Outputs

PLA or ROM

State

Address select logic

Op[5

–0]

Adder

Instruction registeropcode field

1

Control unit

Input

PCWritePCWriteCondIorD

MemtoRegPCSourceALUOpALUSrcBALUSrcARegWriteRegDst

IRWrite

MemReadMemWrite

BWrite

State

Op

Adder

1

PLA or ROM

Mux3 2 1 0

Dispatch ROM 1Dispatch ROM 2

0

AddrCtl

Address select logic

Instruction registeropcode field

AddrCtl:0: go to state 01: dispatch ROM12: dispatch ROM23: go to CS + 1

Page 4: 1 Building Verilog Models for the MIPS Processor

4

Data Path Building Blocks

• Latch• Register• register with one output port : A_reg, B_reg • register with two output ports : temp_reg,

IAR_reg• register with three output ports: MDR_reg,

MAR_reg, PC_reg• register_file

Page 5: 1 Building Verilog Models for the MIPS Processor

5

Data Path Building Blocks

• mux• memory_32• ALU

Page 6: 1 Building Verilog Models for the MIPS Processor

6

Control Unit Building Blocks

• ROM : decode_1_ROM, decode_2_ROM, microcode_ROM

• source_decode• destination_decode• micro_addr_select• register : micro_PC_reg• mux : dest_mux

Page 7: 1 Building Verilog Models for the MIPS Processor

7

Verilog Modules for Building Blocks

module latch (data_out, data_in, clk);

parameter word_width = 32;

output data_out;

input data_in, clk;

reg [word_width - 1 : 0] contents;

wire [word_width - 1 : 0] data_in, data_out;

wire clk;

initial contents = 0;

assign

data_out = contents ;

always @(posedge clk) contents = data_in;

endmodule

Page 8: 1 Building Verilog Models for the MIPS Processor

8

Verilog Modules for Building Blocks

module register (data_out, data_in, latch, clk );

parameter word_width = 32;

output data_out;

input data_in,

latch, //control signal that causes the //input to be latched

clk;

reg [word_width - 1 : 0] contents;

wire [word_width - 1 : 0] data_in, data_out;

wire latch, clk;

initial contents = 0;

Page 9: 1 Building Verilog Models for the MIPS Processor

9

Verilog Modules for Building Blocks

assign

data_out = contents;

always @(posedge clk)

if (latch) contents = data_in;

endmodule

Page 10: 1 Building Verilog Models for the MIPS Processor

10

Verilog Modules for Building Blocks

module register_1_port (data_out, data_in, latch, enable, clk);

/*has one output port that is enabled by the enable signal */

parameter word_width = 32;output data_out;input data_in,

latch, //control signal to latch the inputenable, // enable the data_outclk;

wire [word_width - 1 : 0] data_in, data_out, reg_out;

Page 11: 1 Building Verilog Models for the MIPS Processor

11

Verilog Modules for Building Blocks

wire latch, enable, clk;

register r (reg_out, data_in, latch, clk);

assign

data_out = (enable) ? reg_out : 32'bz ;

endmodule

Page 12: 1 Building Verilog Models for the MIPS Processor

12

Verilog Modules for Building Blocks

module register_2_port (data_out_1, data_out_2, data_in, latch, enable_1, enable_2, clk);

/* has two output ports that are enabled with enable_1 enable_2 */

parameter word_width = 32 ;output data_out_1, //first output port.

data_out_2; //second output port.input data_in, latch, enable_1, enable_2, clk;wire [word_width - 1 : 0] data_in, data_out_1,

data_out_2, reg_out;wire latch, enable_1, enable_2, clk;

Page 13: 1 Building Verilog Models for the MIPS Processor

13

Verilog Modules for Building Blocks

register r (reg_out, data_in, latch, clk);

assign

data_out_1 = (enable_1) ? reg_out : 32'bz,

data_out_2 = (enable_2) ? reg_out : 32'bz;

endmodule

Page 14: 1 Building Verilog Models for the MIPS Processor

14

Verilog Modules for Building Blocks

module register_3_port (data_out_1, data_out_2, data_out_3, data_in, latch, enable_1, enable_2, clk);

/*has three output ports, the first two ports are enabled by enable_1, enable_2, the third port constantly outputs the value of the register*/

parameter word_width = 32;output data_out_1, data_out_2, data_out_3;input data_in, latch, enable_1, enable_2, clk;wire [word_width - 1 : 0 ] data_in, data_out_1,

data_out_2, data_out_3, reg_out;wire latch, enable_1, enable_2, clk;

Page 15: 1 Building Verilog Models for the MIPS Processor

15

Verilog Modules for Building Blocks

register r (reg_out, data_in, latch, clk);

assign data_out_1 = (enable_1) ? reg_out : 32'bz,

data_out_2 = (enable_2) ? reg_out : 32'bz,

data_out_3 = reg_out;

endmodule

Page 16: 1 Building Verilog Models for the MIPS Processor

16

Verilog Modules for Building Blocks

module register_file (data_out_1, data_out_2, source_1, source_2, data_in, dest, latch, latch_last_reg, clk);

parameter word_width = 32, file_addr_width = 5, reg_file_size = 32;

output data_out_1, data_out_2; // first and second // output port

input source_1, //address for source register 1

source_2, //address for source register 2

data_in, //input to the register

dest, //address for the dest. register

Page 17: 1 Building Verilog Models for the MIPS Processor

17

Verilog Modules for Building Blocks

latch, //control signal to latch input in dest. reg.

latch_last_reg, //cause input to be latched in the R[31].

clk; // global timing clock

reg [word_width - 1 : 0 ] registers [reg_file_size - 1 : 0];

wire [word_width - 1 : 0 ] data_in, data_out_1, data_out_2;

wire [file_addr_width - 1 : 0 ] source_1, source_2, dest;

wire latch, latch_last_reg, clk;

integer i;

initial

Page 18: 1 Building Verilog Models for the MIPS Processor

18

Verilog Modules for Building Blocks

begin

for (i=0; i<= (reg_file_size -1 ); i = i+1)

registers[i] = 0;

end

assign

data_out_1 = registers[source_1],

data_out_2 = registers[source_2];

Page 19: 1 Building Verilog Models for the MIPS Processor

19

Verilog Modules for Building Blocks

always @(posedge clk)

begin

if (latch && (dest != 0 ))

registers[dest] = data_in;

if (latch_last_reg)

registers[reg_file_size - 1] = data_in;

end

endmodule

Page 20: 1 Building Verilog Models for the MIPS Processor

20

Verilog Modules for Building Blocks

module mux ( data_out, input_1, input_2, select);

parameter word_width = 32;

output data_out;

input input_1, input_2, select;

wire [word_width -1 : 0] data_out, input_1, input_2;

wire select;

assign

data_out = (select) ? input_2 : input_1;

endmodule

Page 21: 1 Building Verilog Models for the MIPS Processor

21

Verilog Modules for Building Blocksmodule memory_32 (data_out, alignment_error, mem_wait, address,

data_in, read, write, byte, half_word);

// mem_wait indicates memory access (fetch) not yet valid

parameter bits_per_byte = 8,

word_width = 32, num_bytes = 4096;

parameter address_width = 32;

output data_out, alignment_error, mem_wait;

input address, data_in, read, write, byte, half_word;

reg [bits_per_byte - 1 : 0] memory[num_bytes - 1 : 0] ;

reg mem_wait, alignment_error;

wire [word_width - 1 : 0 ] data_in, data_out;

wire [address_width - 1 : 0 ] address;

wire read, write, byte, half_word;

Page 22: 1 Building Verilog Models for the MIPS Processor

22

Verilog Modules for Building Blocksinteger i;

initial

begin

mem_wait = 0;

alignment_error = 0;

for (i=0; i<= (num_bytes - 1) ; i = i+1) memory[i] = 0;

end

assign

data_out = (byte) ? {24 'b0, memory[address]} : 32'bz,

data_out = (half_word) ? {16 'b0, memory[address],

memory[address+1]}: 32'bz,

Page 23: 1 Building Verilog Models for the MIPS Processor

23

Verilog Modules for Building Blocksdata_out = (!byte && !half_word) ? {memory[address],

memory[address+1], memory[address+2],

memory[address+3]} : 32'bz;

always @(posedge read)

begin

mem_wait = 1;

mem_wait = 0;

end

always @(posedge write)

begin

mem_wait= 1;

if (byte == 1)memory[address] = data_in[7:0];

Page 24: 1 Building Verilog Models for the MIPS Processor

24

Verilog Modules for Building Blocks

if (half_word == 1)

begin

if (address[0] != 0)

alignment_error = 1;

else

begin

alignment_error = 0;

memory[address + 1] = data_in[7:0];

memory[address] = data_in[15:8];

end

end

Page 25: 1 Building Verilog Models for the MIPS Processor

25

Verilog Modules for Building Blocks

else

begin

if (address[1:0] != 0 ) alignment_error = 1;

else

begin

alignment_error = 0;

memory[address+3] = data_in[7:0];

memory[address+2] = data_in[15:8];

memory[address+1] = data_in[23:16];

memory[address] = data_in[31:24];

Page 26: 1 Building Verilog Models for the MIPS Processor

26

Verilog Modules for Building Blocks

end

end

mem_wait = 0;

end

endmodule //end of memory module

Page 27: 1 Building Verilog Models for the MIPS Processor

27

Verilog Modules for Building Blocks

module ALU(data_out, zero, negative, divide_by_zero, s1, s2, alu_op, enable);

parameter word_width = 32, alu_op_width = 5;

output

data_out, zero, negative, divide_by_zero;

input

s1, s2, alu_op, enable;

wire [word_width - 1 : 0] temp, data_out, s1, s2;

wire [alu_op_width - 1 : 0] alu_op;

wire zero, negative, enable, divide_by_zero;

Page 28: 1 Building Verilog Models for the MIPS Processor

28

Verilog Modules for Building Blocks

assign

temp = (alu_op == 0) ? (s1+ s2) : 32'bz,

temp = (alu_op == 1) ? (s1- s2) : 32'bz,

temp = (alu_op == 2) ? (s2 - s1) : 32'bz,

temp = (alu_op == 3) ? (s1 & s2) : 32'bz,

temp = (alu_op == 4) ? (s1 | s2 ) : 32'bz,

temp = (alu_op == 5) ? (s1 ^ s2 ) : 32'bz,

temp = (alu_op == 6) ? (s1 << s2 ) : 32'bz,

temp = (alu_op == 7) ? (s1 >> s2 ) : 32'bz,

Page 29: 1 Building Verilog Models for the MIPS Processor

29

Verilog Modules for Building Blocks

temp = (alu_op == 8) ? ((s1[word_width -1] == 0) ?

(s1 >> s2 ) : ((s1 >> s2 ) |

(~(32'b0) << (word_width - s2 )))) : 32'bz, //shift s1 right by s2 with sign extension

temp = (alu_op == 9) ? s1 : 32'bz, //pass s1

temp = (alu_op == 10 ) ? s2 : 32'bz, //pass s2

temp = (alu_op == 11) ? 0 : 32'bz, //pass 0

temp = (alu_op == 12) ? 1 : 32'bz, //pass 1

temp = (alu_op == 13) ? (s1 * s2) : 32'bz,

temp = (alu_op ==14) ? (s1 / s2) : 32'bz,

Page 30: 1 Building Verilog Models for the MIPS Processor

30

Verilog Modules for Building Blocks

temp = (alu_op >= 15) ? 32'bz : 32'bz,

data_out = (enable) ? temp : 32'bz,

zero = (temp == 0) ? 1: 0,

negative = (temp[word_width -1] == 1) ? 1 : 0,

divide_by_zero = ((alu_op == 14) && (s2 == 0)) ? 1 : 0;

endmodule

Page 31: 1 Building Verilog Models for the MIPS Processor

31

Verilog Modules for Building Blocks

module FPU( data_out, zero, negative, divide_by_zero, FP_wait,

s1, s2, alu_op, enable, clk);

parameter word_width = 32, alu_op_width = 5;

output data_out, zero, negative, divide_by_zero,

FP_wait; /* FP_wait indicating that operation is not done yet. */

input s1, s2, alu_op, enable, clk;

wire [word_width - 1 : 0] temp, data_out, s1, s2;

wire [alu_op_width - 1 : 0] alu_op;

wire zero, negative, divide_by_zero, clk;

Page 32: 1 Building Verilog Models for the MIPS Processor

32

Verilog Modules for Building Blocks

reg FP_wait;

initial FP_wait = 0;

always @(posedge clk)

begin

if (enable == 1)

begin

if (alu_op == 0)

begin

FP_wait = 1;

#20 FP_wait = 0;

end

Page 33: 1 Building Verilog Models for the MIPS Processor

33

Verilog Modules for Building Blocks

else if (alu_op == 1)

begin

FP_wait = 1;

#40 FP_wait = 0;

end

end

end

assign

temp = (alu_op == 0) ? (s1 * s2) : 32'bz,

temp = ((alu_op == 1) && (s2 != 0)) ? (s1/s2) : 32'bz,

Page 34: 1 Building Verilog Models for the MIPS Processor

34

Verilog Modules for Building Blocks

data_out = (enable) ? temp : 32'bz,

zero = (temp == 0) ? 1 : 32'bz,

divide_by_zero = ((alu_op ==1) && (s2 == 0) ) ? 1 : 0,

negative = (temp[word_width - 1] == 1) ? 1 : 0;

endmodule

Page 35: 1 Building Verilog Models for the MIPS Processor

35

Verilog Modules for Building Blocks

module ROM(data_out, address);

parameter word_width = 32, addr_width = 6, num_words = 64;

integer i;

output

data_out;

input

address;

reg [word_width - 1 : 0] mem[num_words -1 : 0];

wire [word_width - 1 : 0] data_out;

Page 36: 1 Building Verilog Models for the MIPS Processor

36

Verilog Modules for Building Blocks

wire [word_width - 1 : 0] address;

initial

begin

for (i=0; i < num_words; i = i +1)

mem[i] = 0;

end

assign

data_out = mem[address];

endmodule

Page 37: 1 Building Verilog Models for the MIPS Processor

37

Verilog Modules for Building Blocks

module source_decode (sA, sB, sTemp1, sTemp2, sPC1, sPC2, sIAR1, sIAR2, sMAR1, sMAR2, sMDR1, sMDR2, data_out_1, data_out_2, src_1, src_2, jump_addr, micro_const);

parameter word_width = 32, micro_const_width = 5, source_width = 4;

parameter jump_addr_width = 26;

output

sA, //select register A.

sB, //select register B.

Page 38: 1 Building Verilog Models for the MIPS Processor

38

Verilog Modules for Building Blocks

sTemp1, //select register temp port 1.

sTemp2, //select register temp port 2

sPC1, //select register PC port 1.

sPC2, //select register PC port 2.

sIAR1, //select register IAR port 1.

sIAR2, //select register IAR port 2.

sMAR1, //select register MAR port 1.

sMAR2, //select register MAR port 2.

sMDR1, //select register MDR port 1.

sMDR2, //select register MDR port 2.

Page 39: 1 Building Verilog Models for the MIPS Processor

39

Verilog Modules for Building Blocks

data_out_1, // data connection to bus s1. (to CPU)

data_out_2; // data connection to bus s2. (to CPU)

input

src_1,//source for bus s1

src_2,//source for bus s2

jump_addr, //macro code jump addr from IR

micro_const; // micro_const from micro instruction

wire [word_width - 1 : 0] data_out_1, data_out_2;

wire [jump_addr_width - 1 : 0] jump_addr;

wire [micro_const_width - 1 : 0] micro_const;

wire [source_width - 1 : 0] src_1, src_2;

Page 40: 1 Building Verilog Models for the MIPS Processor

40

Verilog Modules for Building Blocks

assign

sA = ((src_1 == 0) || (src_1 == 15)) ? 1 : 0,

sTemp1 = (src_1 == 1) ? 1 : 0,

sPC1 = (src_1 == 2) ? 1 : 0,

sIAR1 = (src_1 == 3) ? 1 : 0,

sMAR1 = (src_1 == 4) ? 1 : 0,

sMDR1 = (src_1 == 5) ? 1 : 0,

data_out_1 = (src_1 == 6) ? ((jump_addr[15] == 0) ?

(32'b0 | jump_addr[15:0] ) : {16'hFFFF, jump_addr[15:0]}) : 32'bz,

Page 41: 1 Building Verilog Models for the MIPS Processor

41

Verilog Modules for Building Blocks

data_out_1 = (src_1 == 7) ? ((jump_addr[25] == 0) ? (32'b0 | jump_addr[25:0] ) : {6'b111111, jump_addr[25:0]}) : 32'bz,

data_out_1 = (src_1 == 8) ? (32'b0 | micro_const ) : 32'bz,

sB = ((src_2 == 0) || (src_2 == 15)) ? 1 : 0,

sTemp2 = (src_2 == 1) ? 1 : 0,

sPC2 = (src_2 == 2) ? 1 : 0,

sIAR2 = (src_2 == 3) ? 1 : 0,

sMAR2 = (src_2 == 4) ? 1 : 0,

sMDR2 = (src_2 == 5) ? 1 : 0,

Page 42: 1 Building Verilog Models for the MIPS Processor

42

Verilog Modules for Building Blocks

data_out_2 = (src_2 == 6) ? ((jump_addr[15] == 0) ?

(32'b0 | jump_addr[15:0] ) : {16'hFFFF, jump_addr[15:0]}) : 32'bz,

data_out_2= (src_2 == 7) ? ((jump_addr[25] == 0) ?

(32'b0 | jump_addr[25:0] ) : {6'b111111, jump_addr[25:0]}) : 32'bz,

data_out_2= (src_2 == 8) ? (32'b0 | micro_const ) : 32'bz ;

endmodule

Page 43: 1 Building Verilog Models for the MIPS Processor

43

Verilog Modules for Building Blocks

module destination_decode (lA, lB, lC, lTemp, lPC, lIAR, lGPR, lIR, lMAR, lMDR,

mux_MDR_select, read_mem, write_mem, mux_addr_select, lR31, dest, misc);

parameter misc_width = 3, dest_width = 3;

output

lA, //latch register A

lB, //latch register B

lC, //latch register C

lTemp, //latch register Temp.

lPC, //latch register PC

Page 44: 1 Building Verilog Models for the MIPS Processor

44

Verilog Modules for Building Blocks

lIAR, //latch register IAR

lGPR, //latch register GPR

lIR, //latch register IR

lMAR, //latch register MAR

lMDR, //latch register MDR

mux_MDR_select, //select memory source for MDR.

read_mem, //read memory signal

write_mem, //write memory signal

mux_addr_select, //select PC as memory address

lR31; //latch R[31].

Page 45: 1 Building Verilog Models for the MIPS Processor

45

Verilog Modules for Building Blocks

input

dest, //coded destination addr.

misc; //coded misc operation.

wire [misc_width - 1 : 0] misc;

wire [dest_width - 1 : 0 ] dest;

wire lA, lB, lC, lTemp, lPC, lIAR, lGPR, lIR, lMAR, lMDR, mux_MDR_select,

read_mem, write_mem, mux_addr_select, lR31;

assign

lA = (misc == 3) ? 1 : 0,

Page 46: 1 Building Verilog Models for the MIPS Processor

46

Verilog Modules for Building Blocks

lB = (misc == 3) ? 1 : 0,

lC = (dest == 1) ? 1 : 0,

lTemp = (dest == 2) ? 1 : 0,

lPC = (dest == 3 ) ? 1 : 0,

lIAR = (dest == 4 ) ? 1 : 0,

lGPR = (misc == 4 ) ? 1 : 0,

lIR = (misc == 0 ) ? 1 : 0,

lMAR = (dest == 5 ) ? 1 : 0,

Page 47: 1 Building Verilog Models for the MIPS Processor

47

Verilog Modules for Building Blocks

lMDR = ((dest == 6) || (misc == 1)) ? 1 : 0,

read_mem = ((misc == 0) || (misc == 1)) ? 1 : 0,

write_mem = (misc == 2) ? 1 : 0,

mux_MDR_select = (misc == 1) ? 1 : 0,

//fetch word form memoryM[MAR]

mux_addr_select = (misc == 0) ? 1 : 0,

//fetch next instr. at M[PC]

lR31 = (misc == 5) ? 1 : 0;

endmodule

Page 48: 1 Building Verilog Models for the MIPS Processor

48

Verilog Modules for Building Blocks

module microcode_addr_select (micro_addr, byte, half_word, select_I, op_code,

decode_1, decode_2, cond, jump, next_PC, interrupt, mem_wait, alignment_error,

ALU_zero, ALU_negative, ALU_divide_by_zero);

parameter micro_addr_width = 6, op_code_width = 6, cond_width = 4;

Page 49: 1 Building Verilog Models for the MIPS Processor

49

Verilog Modules for Building Blocks

output

micro_addr, //micro inst. ROM address

byte, //memory byte access

half_word, //memory half word access

select_I; //select the immediate GPR dest.

input

op_code, //opcode from IR register

decode_1, //decode_1 indexed addressed

decode_2, //decode_2 indexed addressed

cond, //cond for jump from micro instr.

Page 50: 1 Building Verilog Models for the MIPS Processor

50

Verilog Modules for Building Blocks

jump, //micro instr. jump address

next_PC, //the current micro PC + 1

interrupt, //pending interrupt ignal.

mem_wait, //memory wait signal

alignment_error,

ALU_zero, ALU_negative, ALU_divide_by_zero;

wire [op_code_width - 1 : 0] op_code;

wire [micro_addr_width - 1 : 0] micro_addr, decode_1, decode_2;

wire [micro_addr_width - 1 : 0] jump, next_PC;

Page 51: 1 Building Verilog Models for the MIPS Processor

51

Verilog Modules for Building Blocks

wire interrupt, mem_wait, alignment_error, ALU_zero, ALU_negative;

wire ALU_divide_by_zero;assign

micro_addr = (cond == 0) ? next_PC : 6'bz,micro_addr = (cond == 1) ? jump : 6'bz,micro_addr = ((cond == 2) && (interrupt)) ? jump : 6'bz,micro_addr = ((cond == 2) && (~interrupt)) ? next_PC : 6'bz,micro_addr = ((cond == 3) && (mem_wait)) ? jump : 6'bz,

Page 52: 1 Building Verilog Models for the MIPS Processor

52

Verilog Modules for Building Blocks

micro_addr = ((cond == 3) && (~mem_wait)) ? next_PC : 6'bz,

micro_addr = ((cond == 4) && (ALU_zero )) ? jump : 6'bz,

micro_addr = (( cond == 4) && (~ALU_zero)) ? next_PC : 6'bz,

micro_addr = (( cond == 5) && (ALU_negative)) ? jump : 6'bz,

micro_addr = (( cond == 5) && (~ALU_negative)) ? next_PC : 6'bz,

micro_addr = (( cond == 6) && (op_code < 5)) ? jump : 6'bz,

Page 53: 1 Building Verilog Models for the MIPS Processor

53

Verilog Modules for Building Blocks

micro_addr = (( cond == 6) && ~(op_code < 5 )) ? next_PC : 6'bz,

micro_addr = ( cond == 7) ? decode_1 : 6'bz,

micro_addr = (cond == 8) ? decode_2 : 6'bz,

micro_addr = (cond == 9) ? decode_2 : 6'bz,

micro_addr = ( cond >= 10) ? 0 : 6'bz,

byte = (( op_code == 4) || (op_code == 1) || (op_code == 8)) ? 1 : 0,

half_word = (( op_code == 3) || (op_code == 4) || (op_code == 9) ) ? 1 : 0,

Page 54: 1 Building Verilog Models for the MIPS Processor

54

Verilog Modules for Building Blocks

select_I = ((op_code < 8) || (op_code ==11) || (op_code == 13) || (op_code == 15) ||

(op_code == 17) || (op_code == 19) || (op_code == 20) || (op_code == 22) || (op_code == 24) || (op_code == 26 ) || (op_code == 28) || (op_code == 30) || (op_code == 32) || (op_code == 34) || (op_code == 36) || (op_code == 38 ) || (op_code == 42) || (op_code == 44) || (op_code == 47) || (op_code == 49 )) ? 1 : 0;

endmodule

Page 55: 1 Building Verilog Models for the MIPS Processor

55

Processor Module

module MIPS();

// declare parameters

`define HC #100 //clock half cycle

`define CP #200 //clock period

// define instruction fields

`define OP_CODE IR[31:26]

`define RS1 IR[25:21] //R type instruction

`define RS2 IR[20:16] //R type instruction

`define RD IR[15:11] //R type instruction

`define RDI IR[20:16] // I type instruction

Page 56: 1 Building Verilog Models for the MIPS Processor

56

Processor Module

`define FUNC IR[5:0] //R type instruction

`define IMMEDIATE IR[15:0]

`define JUMP_OFFSET IR[25:0]

//define microinstructions fields

`define DEST MI[33:31]

`define ALU_OP MI[30:26]

`define SELECT_ALU ~MI[30]

`define SELECT_FPUMI[30]

`define SOURCE_1 MI[25:22]

`define SOURCE_2 MI[21:18]

Page 57: 1 Building Verilog Models for the MIPS Processor

57

Processor Module

`define CONST MI[17:13]

`define MISC MI[12:10]

`define COND MI[9:6]

`define MICRO_JUMP MI[5:0]

parameter word_width = 32, alu_op_width = 6, RF_addr_width = 5,

microcode_ROM_size = 64, RF_size = 32, micro_addr_width = 6,

microcode_word_width = 34;

Page 58: 1 Building Verilog Models for the MIPS Processor

58

Processor Modulewire [microcode_word_width - 1 : 0] MI;

wire [word_width - 1 : 0] A, B, C, dest, S1, S2, MDR, mem_addr, MAR_addr, PC_addr, mem_data_in, mem_data_out, IR;

wire [micro_addr_width - 1 : 0] micro_addr, decode_1, decode_2, next_PC, micro_PC;

wire [RF_addr_width - 1 : 0 ] GPR_dest;

reg clk, interrupt;

assign next_PC = micro_addr + 1;

latch #(6) micro_PC_reg(micro_addr, micro_PC, clk);

register C_reg (C, dest, latch_C, clk),

IR_reg (IR, mem_data_out, latch_IR, clk);

Page 59: 1 Building Verilog Models for the MIPS Processor

59

Processor Module

register_1_port A_reg(S1, A, latch_A, select_A, clk),

B_reg(S2, B, latch_B, select_B, clk);

register_2_port temp_reg (S1, S2, dest, latch_temp, select_Temp_1, select_Temp_2,

clk),

IAR_reg (S1, S2, dest, latch_IAR, select_IAR_1, select_IAR_2, clk);

Page 60: 1 Building Verilog Models for the MIPS Processor

60

Processor Moduleregister_3_port MDR_reg (S1, S2, mem_data_in,

MDR, latch_MDR, select_MDR_1,

select_MDR_2, clk),

MAR_reg (S1, S2, MAR_addr, dest, latch_MAR, select_MAR_1,

select_MAR_2, clk),

PC_reg ( S1, S2, PC_addr, dest, latch_PC, select_PC_1, select_PC_2, clk);

mux MDR_mux (MDR, dest, mem_data_out, mux_MDR_select),

addr_mux (mem_addr, MAR_addr, PC_addr, mux_addr_select);

Page 61: 1 Building Verilog Models for the MIPS Processor

61

Processor Module

mux #(5) dest_mux (GPR_dest, `RD, `RS2, select_I);

register_file GPR_file (A, B, `RS1, `RS2, C, GPR_dest, latch_GPR, latch_R31, clk);

memory_32 memory (mem_data_out, alignment_error, mem_wait, mem_addr,

mem_data_in, read_mem, write_mem, byte, half_word);

ALU integer_ALU (dest, ALU_zero, ALU_negative, ALU_divide_by_zero, S1, S2, `ALU_OP, `SELECT_ALU);

ROM #(6, 6, microcode_ROM_size)

decode_1_ROM (decode_1, `OP_CODE),decode_2_ROM (decode_2, `OP_CODE);

Page 62: 1 Building Verilog Models for the MIPS Processor

62

Processor Module

ROM #(34, 6, microcode_ROM_size)microcode_ROM(MI, micro_addr);

microcode_addr_select micro_select (micro_PC, byte, half_word, select_I, `OP_CODE, decode_1, decode_2, `COND, `MICRO_JUMP, next_PC, interrupt, mem_wait, alignment_error, ALU_zero, ALU_negative, ALU_divide_by_zero);

source_decode src_decode (select_A, select_B, select_Temp_1, select_Temp_2, select_PC_1,

select_PC_2, select_IAR_1, select_IAR_2, select_MAR_1, select_MAR_2, select_MDR_1, select_MDR_2, S1, S2, `SOURCE_1, `SOURCE_2, `JUMP_OFFSET, `CONST);

Page 63: 1 Building Verilog Models for the MIPS Processor

63

Processor Module

destination_decode dest_decode (latch_A, latch_B, latch_C, latch_temp, latch_PC, latch_IAR,

latch_GPR, latch_IR, latch_MAR, latch_MDR, mux_MDR_select, read_mem,

write_mem, mux_addr_select, latch_R31, `DEST, `MISC);

Page 64: 1 Building Verilog Models for the MIPS Processor

64

Processor Moduleinitial

begin

clk = 0;

interrupt = 0;

load_decode_1;

load_decode_2;

load_micro_instructions;

end

always

begin

`HC clk = ~clk;

end

Page 65: 1 Building Verilog Models for the MIPS Processor

65

Processor Module

task lp; // load program into memory

begin

$readmemb ("program_file" , memory.memory);

$stop;

end

endtask

Page 66: 1 Building Verilog Models for the MIPS Processor

66

Processor Module

task load_decode_1;

begin

$readmemb("decode_1.b", decode_1_ROM.mem);

end

endtask

task load_decode_2;

begin

$readmemb("decode_2.b", decode_2_ROM.mem);

end

endtask

Page 67: 1 Building Verilog Models for the MIPS Processor

67

Processor Module

task load_micro_instructions;

begin

$readmemb("micro.b", microcode_ROM.mem);

end

endtask

endmodule