/// LSU EE 3755 -- Fall 2001 -- Computer Organization // /// Strawman MIPS, As Seen in Class [tm] // // Time-stamp: <19 November 2001, 13:26:49 CST, koppel@sol> // // This file contains the Verilog code for the strawman MIPS // implementation being written in class. It is probably not complete // and might not be working, even considering its incomplete form. // Completed code will also be posted. // // $Date: 2001/11/20 14:18:56 $ // // $Log: mipsl.v,v $ // Revision 1.3 2001/11/20 14:18:56 koppel // Added j, lbu, sb, and other instructions. // // Revision 1.2 2001/11/16 20:58:46 koppel // Added sll, addi, andi, and bne instructions. // `define MIPS_PROG "ls.v" `define MEMBASE 'h400000 `define DATABASE 'h10010000 `define TEXTSIZE 'h100 `define MEMSIZE 'h200 `define MEMRANGE `MEMBASE:`MEMBASE+`MEMSIZE-1 `define A(addr) ((addr)-`DATABASE+`MEMBASE+`TEXTSIZE) `define MEM(addr) mem[((addr)-`DATABASE+`MEMBASE+`TEXTSIZE)] module proc(exc,clk); input clk; output exc; reg exc; reg [31:0] gpr [0:31]; reg [7:0] mem ['h400000:'h400200]; reg [31:0] pc, npc, nnpc; reg [31:0] ir; reg [4:0] rs, rt, rd, sa; reg [5:0] opcode, func; integer i; // Values for funct field. parameter f_sll = 6'h0; parameter f_srl = 6'h2; parameter f_add = 6'h20; parameter f_sub = 6'h22; parameter f_or = 6'h25; // Values for opcode field. parameter o_rfmt = 6'h0; parameter o_j = 6'h2; parameter o_beq = 6'h4; parameter o_bne = 6'h5; parameter o_addi = 6'h8; 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_sw = 6'h2b; parameter o_sb = 6'h28; initial begin exc = 0; i = 0; end reg [15:0] immed, highhalfofsignedimmed; reg [31:0] simmed, uimmed; reg [25:0] ii; 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]; highhalfofsignedimmed = immed[15] ? 16'hffff : 16'h0; simmed = { highhalfofsignedimmed, immed }; uimmed = { 16'h0, immed }; ii = ir[25:0]; nnpc = npc + 4; case( opcode ) o_rfmt: 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; default: exc = 1; endcase o_lbu: gpr[rt] = { 24'b0, mem[ `A( gpr[rs] + simmed ) ] }; o_sb: begin:A reg [31:0] rt_val; rt_val = gpr[rt]; mem[ `A( gpr[rs] + simmed ) ] = rt_val[7:0]; end o_lui: gpr[rt] = { immed, 16'b0 }; o_addi: gpr[rt] = gpr[rs] + simmed; o_andi: gpr[rt] = gpr[rs] & uimmed; o_bne: if( gpr[rt] != gpr[rs] ) nnpc = npc + ( simmed << 2 ) ; o_beq: if( gpr[rt] == gpr[rs] ) nnpc = npc + ( simmed << 2 ) ; o_j: nnpc = { pc[31:28], ii, 2'b0 }; default: exc = 1; endcase gpr[0] = 0; pc = npc; npc = nnpc; end endmodule // Include the testbench. `include "mipsi1tb.v"