Verilog MIPS Implementation
Verilog MIPS Implementation
Verilog MIPS Implementation
Data Memory
module DM(MemRead, MemWrite, ABUS, DIN, DATABUS);
MemWrite: Nothing happens if 0. If 1, the memory at location ABUS will be written with DIN. ABUS: At any moment, the data at location ABUS will appear at DATABUS. MemRead: Not used.
Data Memory
Address bus: 8 bits. Data bus: 32 bits. Each memory location holds 32 bits.
Data Memory
Init the contents in data memory with any value you like:
initial begin for (i=0; i <= DM_ADDR_MAX_m1; i = i + 1) ram[i] = i*10 + 1; end
Instruction Memory
module IM(CSB,WRB,ABUS,DATABUS);
CSB: chip select. If 0, selected. If 1, not selected. WRB: Not used. ABUS: Address bus. At any moment, if chip is selected, the data at location ABUS will appear at DATABUS.
Instruction Memory
Address bus: 8 bits. Data bus: 32 bits. Each memory location holds 32 bits.
Instruction Memory
The most straightforward way of loading a program:
ram[0] ram[1] ram[2] ram[3] ram[4] ram[5] ram[6] ram[7] ram[8] ram[9] = = = = = = = = = = 32'b00100000000000000000000000000000; 32'b00100000001000010000000000000001; 32'b00100000010000100000000000000010; 32'b00100000011000110000000000000011; 32'b00000000000000000000000000000000; 32'b00000000000000000000000000000000; 32'b00000000000000000000000000000000; 32'b00000000000000000000000000000000; 32'b00000000000000000000000000000000; 32'b00000000000000000000000000000000; // // // // // // // // // // addi addi addi addi nop nop nop nop nop nop $0, $1, $2, $3, $0, $1, $2, $3, 0 1 2 3
PC
module MIPSPC(clk, newPC, PC); Just an 8-bit D-flip-flop.
Register File
module MIPSREG(clk, RegWrite, ReadAddr1, ReadAddr2, WriteAddr, ReadData1, ReadData2, WriteData); Just as what specified in the book. RegWrite: If 0, disabling write. If 1, register WriteAddr register WriteAddr will be overwritten with WriteData. At any time, ReadData1 is the content of reg ReadAddr1, and ReadData2 is the content of reg ReadAddr2.
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 0; goes anywhere always @(ALUctl, A, B) //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 nor default: ALUOut <= 0; //default to 0, should not happen; endcase endmodule
Sign Extension
module SignExtend (in, out); input [15:0] in; output [31:0] out; assign out[15:0] = in[15:0]; assign out[31:16] = in[15]; endmodule
Two-to-one Selector
module STwoToOne32 (sel, in0, in1, out); input sel; input [31:0] in0, in1; output reg [31:0] out;
always @(sel, in0, in1) if (sel == 0) out <= in0; else out <= in1; endmodule
Control
module MIPSCtrl (instr, RegDst, ALUSrc, MemToReg, RegWrite, MemWrite, MemRead, branch, ALUCtrl); Take the 32-bit instruction, generate the control signals.
Supported instructions
add, sub, addi, lw, sw, beq.