/// LSU EE 3755 -- Spring 2002 -- Computer Organization // /// Example used in class 1 May 2002 // /// Hardwired Control, Multicycle MIPS, Day 2 // // // Will be added to each day. // /// Day 1: 29 April 2002 // // Started moving memory out of the processor by adding ports for an // external memory. The module system (at the end of this file) // connects cpu to the memory. Not in a working state. // // Copied functional simulator code. // Added system module that instantiates cpu and memory. // Added new ports. // /// Day 2: 1 May 2002 // // Removed old mem code. // Added states for instruction fetch, decode, and execute. // Was working during class, but by the end of class was in a // non-working state. `define MIPS_PROG "tfirst.v" module cpu(exc,data_out,addr,size,we,data_in,mem_error_in,reset,clk); input [31:0] data_in; input [2:0] mem_error_in; input reset,clk; output [7:0] exc; output [31:0] data_out, addr; output [1:0] size; output we; reg [31:0] data_out, addr; reg [1:0] size; reg we; reg [7:0] exc; 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 [31:0] gpr [0:31]; reg [31:0] simmed, uimmed; reg [7:0] temp; reg [2:0] state; 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; parameter ST_if = 1; // Instruction Fetch parameter ST_id = 2; // Instruction Decode parameter ST_ex = 3; // Executing alu our_alu(alu_out, alu_a, alu_b, alu_op); always @( state or pc ) case( state ) ST_if: begin addr = pc; size = 3; we = 0; end default: begin size = 0; end endcase always @( posedge clk ) if( reset ) begin state = ST_if; pc = 'h400000; npc = pc + 4; exc = 0; end else case( state ) /// IF: Instruction Fetch ST_if: begin // ir = {mem[pc],mem[pc+1],mem[pc+2],mem[pc+3]}; // Provide address to the memory, and other info. ir = data_in; state = ST_id; // Next state end /// Instruction Decode ST_id: begin // Read data from memory. {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: begin alu_op = OP_add; alu_a = gpr[rs]; alu_b = gpr[rt]; dst = rd; end F_sub: gpr[rd] = gpr[rs] - gpr[rt]; F_sll: gpr[rd] = gpr[rt] << sa; F_jr: nnpc = gpr[rs]; default: exc = 1; 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: exc = 1; endcase pc = npc; npc = nnpc; state = ST_ex; end /// EX: Execute ST_ex: begin if( dst ) gpr[dst] = alu_out; end endcase endmodule module alu(alu_out, alu_a, alu_b, alu_op); output [31:0] alu_out; input [31:0] alu_a, alu_b; input [5:0] alu_op; reg [31:0] alu_out; // Control Signal Value Names parameter OP_nop = 0; parameter OP_sll = 1; parameter OP_srl = 2; parameter OP_add = 3; parameter OP_sub = 4; parameter OP_or = 5; parameter OP_and = 6; parameter OP_slt = 7; parameter OP_seq = 8; always @( alu_a or alu_b or alu_op ) case( alu_op ) OP_add : alu_out = alu_a + alu_b; OP_and : alu_out = alu_a & alu_b; OP_or : alu_out = alu_a | alu_b; OP_sub : alu_out = alu_a - alu_b; OP_slt : alu_out = {alu_a[31],alu_a} < {alu_b[31],alu_b}; OP_sll : alu_out = alu_b << alu_a; OP_srl : alu_out = alu_b >> alu_a; OP_seq : alu_out = alu_a == alu_b; OP_nop : alu_out = 0; default : begin alu_out = 0; $stop; end endcase endmodule module system(exc,reset,clk); input reset, clk; output [7:0] exc; wire [31:0] cpu_data_out, addr, mem_data_out; wire [2:0] mem_err_out; wire [1:0] size; wire we; cpu cpu1(exc,cpu_data_out,addr,size,we,mem_data_out,mem_err_out,reset,clk); mips_memory_1p m1(mem_data_out,mem_err_out,addr,size,we,cpu_data_out,clk); endmodule `include "mips_hc_tb.v"