/// LSU EE 3755 -- Spring 2002 -- Computer Architecture // /// MIPS Processor Functional Simulator // // Implements a small subset of MIPS32 instructions and features. // // Time-stamp: <29 April 2002, 15:30:56 CDT, koppel@neptune> // /// Dependencies /// To compile run this the following is also needed: // // mips_fs_tb.v The testbench. It is included in here for convenience. // mipsmemmacros.v Macros needed for memory access. // // An "assembled" program, for example tthird.v. The name of the // file is specified in the MIPS_PROG macro, the testbench uses the // macro to include the file. /// Limitations // // This code will probably never implement all of MIPS32. The intent // is to demonstrate basic MIPS simulation techniques as a first step // towards developing synthesizable and implementatble descriptions. // /// Specify Program to Load // // A quick-and-dirty method of loading a program is used. (For now.) // Therefore the description must be re-compiled each time the program // is changed. (The program is assembled by SPIM and some perl code.) // `define MIPS_PROG "tthird.v" `include "mipsmemmacros.v" module proc(exc,clk); input clk; output exc; // add $2, $3, $4 reg [31:0] pc, npc, nnpc; reg [31:0] ir; reg [5:0] opcode, func; reg [4:0] rs, rt, rd, sa; reg [15:0] immed; reg [25:0] ii; reg [7:0] mem ['h400000:'h400200]; reg [31:0] gpr [0:31]; reg [31:0] simmed, uimmed; reg [7:0] temp; parameter F_add = 6'h20; parameter F_sll = 6'h0; parameter F_srl = 6'h2; parameter F_sub = 6'h22; parameter F_or = 6'h25; parameter F_jr = 6'h8; parameter O_tyr = 6'h0; parameter O_addi = 6'h8; parameter O_j = 6'h2; parameter O_jal = 6'h3; parameter O_beq = 6'h4; parameter O_bne = 6'h5; parameter O_slti = 6'ha; parameter O_andi = 6'hc; parameter O_ori = 6'hd; parameter O_lui = 6'hf; parameter O_lw = 6'h23; parameter O_lbu = 6'h24; parameter O_lb = 6'h20; parameter O_sw = 6'h2b; parameter O_sb = 6'h28; always @( posedge clk ) begin ir = {mem[pc],mem[pc+1],mem[pc+2],mem[pc+3]}; {opcode, rs, rt, rd, sa, func} = ir; immed = ir[15:0]; ii = ir[25:0]; simmed = {immed[15] ? 16'hffff : 16'h0, immed}; uimmed = { 16'h0, immed }; nnpc = npc + 4; // Reassigned below. case( opcode ) O_tyr: case( func ) F_add: gpr[rd] = gpr[rs] + gpr[rt]; F_sub: gpr[rd] = gpr[rs] - gpr[rt]; F_sll: gpr[rd] = gpr[rt] << sa; F_jr: nnpc = gpr[rs]; default: $stop; endcase O_addi: gpr[rt] = gpr[rs] + simmed; O_andi: gpr[rt] = gpr[rs] & uimmed; O_ori: gpr[rt] = gpr[rs] | uimmed; O_lui: gpr[rt] = {immed,16'h0}; O_bne: if( gpr[rt] != gpr[rs] ) nnpc = npc + ( simmed << 2 ); O_j: nnpc = {npc[31:28],ii,2'd0}; O_jal: begin gpr[31] = nnpc; nnpc = {npc[31:28],ii,2'd0}; end O_lbu: gpr[rt] = {24'b0, mem[`A(gpr[rs]+simmed)]}; O_lb: begin temp = mem[`A(gpr[rs]+simmed)]; gpr[rt] = {temp[7] ? 24'hffffff : 24'h0, temp}; end O_sb: mem[`A(gpr[rs]+simmed)]= gpr[rt]; default: $stop; endcase gpr[0] = 0; pc = npc; npc = nnpc; end endmodule `include "mips_fs_tb.v"