/// LSU EE 3755 -- Fall 2001 -- Computer Organization // /// Hardwired Control MIPS, As Seen in Class [tm] // // Time-stamp: <3 December 2001, 13:32:51 CST, koppel@sol> // // This file contains the Verilog code for the hardwired control 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/12/03 20:59:19 $ // // $Log: mips3l.v,v $ // Revision 1.4 2001/12/03 20:59:19 koppel // Completed combinational logic for setting memory inputs. // // Revision 1.3 2001/11/30 21:06:13 koppel // Moved branch condition and target computation to ALU. // Started on combinational logic code for setting memory inputs, // this code currently incomplete and so it is ifdef'ed out. // // Revision 1.2 2001/11/30 16:14:02 koppel // Completed separation of ALU, used for arithmetic & logic and for // effective address computation. Not yet used for branches. // // Revision 1.1 2001/11/28 18:10:49 koppel // Initial revision // // // Hi-lock: (("st_[a-z_]+:" (0 (quote font-lock-note-face) t))) `define MIPS_PROG "prog1.v" 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); memory_3 m1(mem_data_out,mem_err_out,addr,size,we,cpu_data_out,clk); endmodule 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] gpr [0:31]; 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; // 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; initial begin exc = 0; i = 0; end reg [15:0] immed, highhalfofsignedimmed; reg [31:0] simmed, uimmed; reg [25:0] ii; reg [2:0] state; wire [31:0] alu_out; reg [31:0] alu_a, alu_b; reg [5:0] alu_op; wire alu_zero; alu our_alu(alu_zero, alu_out, alu_a, alu_b, alu_op); parameter st_if = 1; parameter st_id = 2; parameter st_ex = 3; parameter st_ex_addr = 5; parameter st_ex_cond = 6; parameter st_ex_targ = 7; parameter st_me = 4; reg [31:0] rs_val, rt_val; reg [4:0] wb_rd; reg me_we; reg [1:0] me_size; reg ex_cond_take; always @( state or pc or alu_out or me_we or me_size ) case( state ) st_if: begin addr = pc; we = 0; size = 3; end st_me: begin addr = alu_out; we = me_we; size = me_size; end default: begin addr = alu_out; we =0; size = 0; end endcase always @( posedge clk ) if( reset ) begin pc = 'h400000; npc = pc + 4; state = st_if; end else case ( state ) st_if: begin ir = data_in; state = st_id; end st_id: begin {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; rs_val = gpr[rs]; rt_val = gpr[rt]; case( opcode ) o_rfmt: case ( func ) f_add: begin alu_a = rs_val; alu_b = rt_val; alu_op = op_add; wb_rd = rd; end f_sub: begin alu_a = rs_val; alu_b = rt_val; alu_op = op_sub; wb_rd = rd; end f_sll: begin alu_a = rt_val; alu_b = sa; alu_op = op_sll; wb_rd = rd; end default: exc = 1; endcase o_lbu: begin alu_a = rs_val; alu_b = simmed; alu_op = op_add; wb_rd = rt; me_we = 0; me_size = 1; // addr = gpr[rs] + simmed; we = 0; size = 1; end o_sb: begin alu_a = rs_val; alu_b = simmed; alu_op = op_add; wb_rd = 0; me_we = 1; me_size = 1; end o_lui: begin alu_a = uimmed; alu_b = 16; alu_op = op_sll; wb_rd = rt; end o_addi: begin alu_a = rs_val; alu_b = simmed; alu_op = op_add; wb_rd = rt; end o_andi: begin alu_a = rs_val; alu_b = uimmed; alu_op = op_and; wb_rd = rt; end o_bne: begin alu_a = rs_val; alu_b = rt_val; alu_op = op_sub; wb_rd = 0; ex_cond_take = 0; end o_beq: begin alu_a = rs_val; alu_b = rt_val; alu_op = op_sub; wb_rd = 0; ex_cond_take = 1; end o_j: nnpc = { pc[31:28], ii, 2'b0 }; default: exc = 1; endcase data_out = rt_val; pc = npc; npc = nnpc; case( opcode ) o_bne, o_beq: state = st_ex_cond; o_lbu, o_sb: state = st_ex_addr; default: state = st_ex; endcase end st_ex: begin if( wb_rd ) gpr[ wb_rd ] = alu_out; state = st_if; end st_ex_addr: begin state = st_me; end st_ex_cond: begin if( ex_cond_take == alu_zero ) begin // Taken alu_a = pc; alu_b = simmed << 2; alu_op = op_add; wb_rd = 0; state = st_ex_targ; end else begin // Not Taken state = st_if; end end st_ex_targ: begin npc = alu_out; state = st_if; end st_me: begin if( !we ) gpr[wb_rd] = data_in; state = st_if; end default: begin $display("Unexpected state."); $stop; end endcase endmodule module alu(zero,alu_out,alu_a,alu_b,alu_op); output [31:0] alu_out; output zero; 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; assign zero = alu_out == 0; 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 < alu_b; op_sll : alu_out = alu_a << alu_b; op_srl : alu_out = alu_a >> alu_b; op_nop : alu_out = 0; default : begin alu_out = 0; $stop; end endcase endmodule `include "mipsi3tb.v"