/// LSU EE 4720 -- Spring 2002 -- Computer Architecture
//
/// Pipelined Hardwired Control MIPS with Bypassing
//
// Implements a small subset of MIPS32 instructions and features.
//
// Time-stamp: <18 March 2002, 10:23:25 CST, koppel@sol>
//
/// 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 "uc.v"
/// Unexpected Macro
//
// Used in the default case item of case statements when the default
// item should not be executed. Used in case statements that assign
// the same register in each item. If the default item is executed
// (indicating a programming bug) simulation is stopped and hopefully
// the bug is fixed. For synthesis, the unexpected macro would assign
// the variable, avoiding the synthesis of a latch. Alas, Leonardo
// Spectrum does not recognize macros with parameters so a task is
// used to assign the variable. That task must be included in each
// module. (If Leonardo understood hierarchical references, the task
// could be put in a special utility module, but it can't.)
`ifdef exemplar
`define UNEXPECTED unexpected
`else
`define UNEXPECTED(var,ctrl) begin var = 0; if( ctrl[0] !== 1'bx ) $stop; end 0:
`endif
///
/// MIPS Processor
///
module cpu_p1(exc,data_out_2, addr_1,addr_2,size_2,we_2,
data_in_1,data_in_2, mem_error_in_1,mem_error_in_2,reset,clk);
input [31:0] data_in_1, data_in_2;
input [2:0] mem_error_in_1, mem_error_in_2;
input reset,clk;
output [7:0] exc;
output [31:0] data_out_2, addr_1, addr_2;
output [1:0] size_2;
output we_2;
task unexpected;
inout [31:0] var;
input [10:0] control;
var = 0;
endtask
///
/// MIPS CONSTANTS
///
//
// Defined by the ISA
/// "opcode" Field Values
//
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;
/// "function" Field Values
//
parameter F_sll = 6'h0;
parameter F_srl = 6'h2;
parameter F_sys = 6'hc;
parameter F_add = 6'h20;
parameter F_sub = 6'h22;
parameter F_and = 6'h24;
parameter F_or = 6'h25;
parameter F_xor = 6'h26;
///
/// IMPLEMENTATION CONSTANTS
///
//
// Defined for this implementation, not standardized. These codes
// are used by other modules in this implementation, so they should
// be changed consistently.
/// Processor Exception Codes
//
parameter EXC_none = 8'd0;
parameter EXC_if_bus = 8'd1; // Bus Error (Mis-aligned address.)
parameter EXC_if_seg = 8'd2; // Bad Address
parameter EXC_id_ins = 8'd3; // Illegal (Reserved) Instruction
parameter EXC_id_sys = 8'd5; // Syscall Instruction
parameter EXC_me_bus = 8'd6; // Bus Error (Mis-aligned address.)
parameter EXC_me_seg = 8'd7; // Bad Address
//
// The exception codes above are not MIPS codes, though they are
// similar. (For one thing, MIPS does not use the bus exception
// for a misaligned address.) For the real codes see Table 6-17 in
//http://www.ece.lsu.edu/ee4720/mips32v3.pdf
/// ALU Operations + Extra Bit
//
// The lower 5 bits of the codes below are used by the ALU, the
// sixth bit is used for special cases and is removed in the ID
// stage.
//
parameter OP_xxx = 6'h0; // Don't care.
parameter OP_add = 6'h0;
parameter OP_sll = 6'h1;
parameter OP_srl = 6'h2;
parameter OP_xor = 6'h3;
parameter OP_sub = 6'h4;
parameter OP_or = 6'h5;
parameter OP_and = 6'h6;
parameter OP_slt = 6'h7;
parameter OP_seq = 6'h8;
parameter OP_b = 6'h9;
parameter OP_ill = 6'h20; // Illegal Instruction
parameter OP_sys = 6'h21; // Syscall
/// Memory Exception Codes
//
parameter MEM_ERR_none = 0;
parameter MEM_ERR_bus = 1; // Bad alignment.
parameter MEM_ERR_seg = 2; // Bad address.
///
/// MODULE CONSTANTS
///
//
// Defined for this module, intended to improve readability of code.
/// PC Mux
//
parameter PC_npc = 2'd0;
parameter PC_dsp = 2'd1; // Displacement (Branches)
parameter PC_rgn = 2'd2; // Region (Jumps)
parameter PC_rs = 2'd3;
/// ALU Muxen
//
parameter SRC_xx = 3'd4; // Won't be used, avoids stalls on alu_a and alu_b.
parameter SRC_me = 3'd1;
parameter SRC_wb = 3'd2;
parameter SRC_rs = 3'd3;
parameter SRC_sa = 3'd4;
parameter SRC_rt = 3'd3;
parameter SRC_im = 3'd4;
parameter SRC_np = 3'd5;
/// Register Number to Write Back
//
parameter WB_00 = 3'd0;
parameter WB_rd = 3'd1;
parameter WB_rt = 3'd2;
/// Immediate Formatting
//
parameter IMM_x = 3'd0; // Don't care.
parameter IMM_s = 3'd0;
parameter IMM_u = 3'd1;
parameter IMM_l = 3'd2;
/// Memory Access Size
//
parameter ME_SIZE_0 = 2'd0;
parameter ME_SIZE_1 = 2'd1;
parameter ME_SIZE_2 = 2'd2;
parameter ME_SIZE_4 = 2'd3;
parameter ME_CONTROL_nop = { ME_SIZE_0, 1'd0 };
///
/// DECLARATIONS
///
/// Pipeline Latches and Some Pipeline-Latch Inputs
//
reg [31:0] if_pc, next_if_pc;
reg [31:0] if_id_ir;
reg [31:0] if_id_npc, if_id_pc;
reg [7:0] if_id_exc, next_if_id_exc;
reg if_id_occ;
reg [31:0] tb_if_din, tb_if_id_din;
reg [31:0] id_ex_npc, id_ex_pc;
reg [31:0] id_ex_rs_val;
reg [31:0] id_ex_rt_val;
reg [4:0] id_ex_sa, next_id_ex_sa;
reg [31:0] id_ex_imm, next_id_ex_imm;
reg [4:0] id_ex_dst, next_id_ex_dst;
reg [2:0] id_ex_alu_a_src, next_id_ex_alu_a_src;
reg [4:0] id_ex_alu_op, next_id_ex_alu_op;
reg [2:0] id_ex_alu_b_src, next_id_ex_alu_b_src;
reg [2:0] id_ex_me, next_id_ex_me;
reg [7:0] id_ex_exc, next_id_ex_exc;
reg id_ex_occ;
reg [31:0] tb_id_ex_din;
reg [31:0] ex_me_npc, ex_me_pc;
reg [31:0] ex_me_alu;
reg [31:0] ex_me_rt_val;
reg [1:0] ex_me_size;
reg ex_me_we;
reg [4:0] ex_me_dst;
reg [7:0] ex_me_exc;
wire [7:0] next_ex_me_exc;
reg ex_me_occ;
reg [31:0] tb_ex_me_din;
reg [31:0] me_wb_pc;
reg [31:0] me_wb_alu;
reg [31:0] me_wb_md;
reg [4:0] me_wb_dst;
reg me_wb_occ;
reg [31:0] tb_me_wb_din;
reg [7:0] me_wb_exc, next_me_wb_exc;
reg me_wb_from_mem;
/// Interstage Signals
//
reg hold_id;
wire squash_if_id, squash_id;
reg [1:0] pc_src;
wire load_in_ex;
/// Instruction Fields
//
reg [4:0] rs, rt, rd, sa;
reg [5:0] opcode, func;
reg [25:0] ii;
reg [15:0] immed;
/// Some ALU AND GPR Connections
//
wire [31:0] alu_out;
reg [31:0] alu_a, alu_b;
wire [31:0] gpr_rs_val, gpr_rt_val, gpr_write_val;
/// Some Memory Connections
//
assign addr_1 = if_pc;
assign addr_2 = ex_me_alu;
assign we_2 = ex_me_we;
assign size_2 = ex_me_size;
assign data_out_2 = ex_me_rt_val;
///
/// INSTANTIATIONS
///
alu our_alu(alu_out, alu_a, alu_b, id_ex_alu_op);
reg_file gpr(gpr_rs_val, gpr_rt_val, rs, rt, me_wb_dst, gpr_write_val, clk);
///
/// PIPELINE STARTS HERE
///
///
/// Instruction Fetch
///
always @( if_pc or pc_src or ex_me_alu or if_id_npc or immed
or gpr_rs_val or ii )
case( pc_src )
PC_npc : next_if_pc = if_pc + 4;
PC_dsp : next_if_pc = if_id_npc + {immed[15]?14'h3fff:14'h0,immed,2'b0};
PC_rgn : next_if_pc = { if_id_npc[31:28], ii, 2'b0 };
PC_rs : next_if_pc = gpr_rs_val;
default : `UNEXPECTED(next_if_pc,pc_src);
endcase
always @( mem_error_in_1 )
case( mem_error_in_1 )
MEM_ERR_none : next_if_id_exc = 0;
MEM_ERR_seg : next_if_id_exc = EXC_if_seg;
MEM_ERR_bus : next_if_id_exc = EXC_if_bus;
default : `UNEXPECTED(next_if_id_exc, mem_error_in_1);
endcase
always @( posedge clk )
if( reset )
begin
if_id_occ <= 0;
// The value below is the usual entry point for SPIM-compiled
// code. Real MIPS processors reset PC to 'hbfc00000.
if_pc <= 'h400000;
tb_if_din <= 1;
end
else if( ~hold_id || squash_if_id )
begin
if_id_pc <= if_pc;
if_pc <= next_if_pc;
if_id_ir <= data_in_1;
if_id_npc <= next_if_pc;
if_id_exc <= next_if_id_exc;
if_id_exc <= {5'b0, mem_error_in_1};
if_id_occ <= ~squash_if_id;
tb_if_id_din <= tb_if_din;
tb_if_din <= tb_if_din + 1;
end
///
/// Instruction Decode
///
// Stage-Local Declarations
//
reg [17:0] d_a_op_b; // Dest <- operand_a op operand_b, immed_fmt
reg [2:0] size_we; // Memory control bits.
reg [2:0] immed_fmt; // Formating to apply to immediate.
reg [2:0] dest_field;
reg extra_op_bit;
reg op_rs, op_rt;
reg cant_bypass;
reg branch_in_id;
reg [2:0] alu_a_src_maybe, alu_b_src_maybe;
always @( if_id_ir or id_ex_dst or ex_me_dst or me_wb_dst
or squash_id or if_id_occ or if_id_npc or load_in_ex )
begin
{opcode,rs,rt,rd,sa,func} = if_id_ir;
ii = if_id_ir[25:0];
immed = if_id_ir[15:0];
// Note: Case statements below could be synthesized as a memory
// which is why only constants appear on the RHS of the assignments.
case( opcode )
O_rfmt:
// R-Format Instructions
case( func )
F_sll : d_a_op_b = {WB_rd, SRC_sa, OP_sll, SRC_rt, IMM_x};
F_sys : d_a_op_b = {WB_00, SRC_xx, OP_sys, SRC_xx, IMM_x};
F_add : d_a_op_b = {WB_rd, SRC_rs, OP_add, SRC_rt, IMM_x};
F_sub : d_a_op_b = {WB_rd, SRC_rs, OP_sub, SRC_rt, IMM_x};
F_and : d_a_op_b = {WB_rd, SRC_rs, OP_and, SRC_rt, IMM_x};
F_or : d_a_op_b = {WB_rd, SRC_rs, OP_or, SRC_rt, IMM_x};
F_xor : d_a_op_b = {WB_rd, SRC_rs, OP_xor, SRC_rt, IMM_x};
default : d_a_op_b = {WB_00, SRC_rs, OP_ill, SRC_rt, IMM_x};
endcase
// I- and J-Format Instructions
O_lw, O_lbu
: d_a_op_b = {WB_rt, SRC_rs, OP_add, SRC_im, IMM_s};
O_sb : d_a_op_b = {WB_00, SRC_rs, OP_add, SRC_im, IMM_s};
O_lui : d_a_op_b = {WB_rt, SRC_rs, OP_or, SRC_im, IMM_l};
O_addi : d_a_op_b = {WB_rt, SRC_rs, OP_add, SRC_im, IMM_s};
O_andi : d_a_op_b = {WB_rt, SRC_rs, OP_and, SRC_im, IMM_u};
O_ori : d_a_op_b = {WB_rt, SRC_rs, OP_or, SRC_im, IMM_u};
O_slti : d_a_op_b = {WB_rt, SRC_rs, OP_slt, SRC_im, IMM_s};
O_j : d_a_op_b = {WB_00, SRC_xx, OP_xxx, SRC_xx, IMM_x};
O_bne, O_beq
: d_a_op_b = {WB_00, SRC_xx, OP_xxx, SRC_xx, IMM_x};
default : d_a_op_b = {WB_00, SRC_rs, OP_ill, SRC_im, IMM_s};
endcase
{ dest_field,
alu_a_src_maybe,
extra_op_bit,
next_id_ex_alu_op,
alu_b_src_maybe,
immed_fmt
} = d_a_op_b;
case( opcode )
O_lbu : size_we = {ME_SIZE_1, 1'b0};
O_lw : size_we = {ME_SIZE_4, 1'b0};
O_sb : size_we = {ME_SIZE_1, 1'b1};
default : size_we = {ME_SIZE_0, 1'b0};
endcase
case( {extra_op_bit,next_id_ex_alu_op} )
OP_sys : next_id_ex_exc = EXC_id_sys;
OP_ill : next_id_ex_exc = EXC_id_ins;
default : next_id_ex_exc = EXC_none;
endcase
case( opcode )
O_bne, O_beq: {op_rs, op_rt} = 2'd3;
O_sb: {op_rs, op_rt} = 2'd3;
default: {op_rs, op_rt} = {alu_a_src_maybe == SRC_rs,
alu_b_src_maybe == SRC_rt};
endcase
case( opcode )
O_bne, O_beq: branch_in_id = 1;
default: branch_in_id = 0;
endcase
case( 1 )
!rs || alu_a_src_maybe != SRC_rs
: next_id_ex_alu_a_src = alu_a_src_maybe;
rs == id_ex_dst : next_id_ex_alu_a_src = SRC_me;
rs == ex_me_dst : next_id_ex_alu_a_src = SRC_wb;
default : next_id_ex_alu_a_src = alu_a_src_maybe;
endcase
if( !rt || alu_b_src_maybe != SRC_rt )
next_id_ex_alu_b_src = alu_b_src_maybe;
else if( rt == id_ex_dst )
next_id_ex_alu_b_src = SRC_me;
else if( rt == ex_me_dst )
next_id_ex_alu_b_src = SRC_wb;
else
next_id_ex_alu_b_src = alu_b_src_maybe;
//Check for: Store Branch
cant_bypass = size_we & 1 || branch_in_id
// Load
|| load_in_ex && ( next_id_ex_alu_a_src == SRC_me
|| next_id_ex_alu_b_src == SRC_me );
hold_id = if_id_occ && ~squash_id && cant_bypass
&& ( ( op_rs && rs
&& ( rs == id_ex_dst || rs == ex_me_dst) )
||
( op_rt && rt
&& ( rt == id_ex_dst || rt == ex_me_dst) ) );
case( immed_fmt )
IMM_s: next_id_ex_imm = { immed[15] ? 16'hffff : 16'h0, immed };
IMM_l: next_id_ex_imm = { immed, 16'h0 };
IMM_u: next_id_ex_imm = { 16'h0, immed };
default: `UNEXPECTED(next_id_ex_imm,immed_fmt);
endcase
case ( dest_field )
WB_00: next_id_ex_dst = 0;
WB_rd: next_id_ex_dst = rd;
WB_rt: next_id_ex_dst = rt;
default: `UNEXPECTED(next_id_ex_dst,dest_field);
endcase
next_id_ex_me = size_we;
next_id_ex_sa = sa;
end
assign squash_id = squash_if_id && id_ex_occ;
wire id_live = if_id_occ && ~squash_id;
reg [1:0] pc_src_maybe;
always @( opcode or gpr_rs_val or gpr_rt_val or id_live ) begin
case( opcode )
O_bne : pc_src_maybe = gpr_rs_val != gpr_rt_val ? PC_dsp : PC_npc;
O_beq : pc_src_maybe = gpr_rs_val == gpr_rt_val ? PC_dsp : PC_npc;
O_j : pc_src_maybe = PC_rgn;
default : pc_src_maybe = PC_npc;
endcase
pc_src = id_live ? pc_src_maybe : PC_npc;
end
assign squash_if_id = 0;
always @( posedge clk )
if ( hold_id || reset ) begin
id_ex_dst <= 0;
id_ex_me <= ME_CONTROL_nop;
id_ex_occ <= 0;
end else begin
id_ex_npc <= if_id_npc;
id_ex_pc <= if_id_pc;
id_ex_rs_val <= gpr_rs_val;
id_ex_rt_val <= gpr_rt_val;
id_ex_sa <= next_id_ex_sa;
id_ex_alu_a_src <= next_id_ex_alu_a_src;
id_ex_alu_b_src <= next_id_ex_alu_b_src;
id_ex_alu_op <= next_id_ex_alu_op;
id_ex_imm <= next_id_ex_imm;
id_ex_me <= id_live ? next_id_ex_me : ME_CONTROL_nop;
id_ex_dst <= id_live ? next_id_ex_dst : 5'b0;
id_ex_exc <= if_id_exc ? if_id_exc : next_id_ex_exc;
id_ex_occ <= id_live;
tb_id_ex_din <= tb_if_id_din;
end
///
/// Execute
///
always @( id_ex_alu_a_src or id_ex_rs_val or id_ex_sa or id_ex_npc
or ex_me_alu or gpr_write_val )
case( id_ex_alu_a_src )
SRC_rs: alu_a = id_ex_rs_val;
SRC_np: alu_a = id_ex_npc;
SRC_sa: alu_a = {27'd0, id_ex_sa};
SRC_me: alu_a = ex_me_alu;
SRC_wb: alu_a = gpr_write_val;
default: `UNEXPECTED(alu_a,id_ex_alu_a_src);
endcase
always @( id_ex_alu_b_src or id_ex_rt_val or id_ex_imm
or ex_me_alu or gpr_write_val )
case( id_ex_alu_b_src )
SRC_rt: alu_b = id_ex_rt_val;
SRC_im: alu_b = id_ex_imm;
SRC_me: alu_b = ex_me_alu;
SRC_wb: alu_b = gpr_write_val;
default: `UNEXPECTED(alu_b,id_ex_alu_b_src);
endcase
wire [1:0] id_ex_size;
wire id_ex_we;
assign {id_ex_size,id_ex_we} = id_ex_me;
assign load_in_ex = id_ex_occ && !id_ex_we && id_ex_size;
assign next_ex_me_exc = 0;
always @( posedge clk ) begin
ex_me_npc <= id_ex_npc;
ex_me_pc <= id_ex_pc;
ex_me_alu <= alu_out;
ex_me_rt_val <= id_ex_rt_val;
{ ex_me_size,
ex_me_we } <= id_ex_exc || reset ? ME_CONTROL_nop : id_ex_me;
ex_me_dst <= reset ? 5'd0 : id_ex_dst;
ex_me_exc <= id_ex_exc ? id_ex_exc : next_ex_me_exc;
ex_me_occ <= ~reset & id_ex_occ;
tb_ex_me_din <= tb_id_ex_din;
end
/// Memory
always @( mem_error_in_2 )
case( mem_error_in_2 )
MEM_ERR_none : next_me_wb_exc = 0;
MEM_ERR_seg : next_me_wb_exc = EXC_me_seg;
MEM_ERR_bus : next_me_wb_exc = EXC_me_bus;
default : `UNEXPECTED(next_me_wb_exc, mem_error_in_2);
endcase
always @( posedge clk ) begin
me_wb_pc <= ex_me_pc;
me_wb_dst <= next_me_wb_exc || reset ? 5'd0 : ex_me_dst;
me_wb_from_mem <= ex_me_size != 0;
me_wb_alu <= ex_me_alu;
me_wb_md <= data_in_2;
me_wb_exc <= ex_me_exc ? ex_me_exc : next_me_wb_exc;
me_wb_occ <= ~reset & ex_me_occ;
tb_me_wb_din <= tb_ex_me_din;
end
/// Writeback
assign gpr_write_val = me_wb_from_mem ? me_wb_md : me_wb_alu;
assign exc = me_wb_occ ? {1'b0,me_wb_exc} : 8'd0;
///
/// END OF HARDWARE DESCRIPTION
///
///
/// TESTBENCH INTERFACE CODE
///
// exemplar translate_off
reg [31:0] tbi_done_pc;
reg tbi_inst_done;
always @( posedge clk ) tbi_inst_done <= me_wb_occ;
always @( posedge clk ) tbi_done_pc <= me_wb_pc;
task tbi_poke_gpr;
input [5:0] r;
input [31:0] val;
gpr.storage[r] = val;
endtask
function [31:0] tbi_peek_gpr;
input [5:0] r;
tbi_peek_gpr = gpr.storage[r];
endfunction
task tbi_iterate_pipeline_segments;
output valid;
output [15:0] name;
output [31:0] pc;
output [31:0] din;
output [7:0] exc;
output occ;
reg [88:0] info;
integer stage;
begin
if( stage === 32'bx ) stage = 0;
for(valid = 0; stage < 5 && !valid; valid = occ == 1 ) begin
case( stage )
0: info = {"IF",if_pc, tb_if_din, next_if_id_exc,1'd1};
1: info = {"ID",if_id_pc,tb_if_id_din,next_id_ex_exc,if_id_occ};
2: info = {"EX",id_ex_pc,tb_id_ex_din,next_ex_me_exc,id_ex_occ};
3: info = {"ME",ex_me_pc,tb_ex_me_din,next_me_wb_exc,ex_me_occ};
4: info = {"WB",me_wb_pc,tb_me_wb_din,8'b0, me_wb_occ};
default `UNEXPECTED(info,stage);
endcase
{name,pc,din,exc,occ} = info;
stage = stage + 1;
end
if( !valid ) stage = 0;
end
endtask
// exemplar translate_on
endmodule
module reg_file(data_out_1, data_out_2, addr_1, addr_2,
addr_3, data_in_3, clk);
input [4:0] addr_1, addr_2, addr_3;
input [31:0] data_in_3;
input clk;
output [31:0] data_out_1, data_out_2;
reg [31:0] storage [0:31];
assign data_out_1 = addr_1 && addr_1 == addr_3 ? data_in_3 : storage[addr_1];
assign data_out_2 = addr_2 && addr_2 == addr_3 ? data_in_3 : storage[addr_2];
always @( posedge clk ) if( addr_3 ) storage[addr_3] <= data_in_3;
endmodule
module alu(alu_out,alu_a,alu_b,alu_op);
output [31:0] alu_out;
input [31:0] alu_a, alu_b;
input [4:0] alu_op;
reg [31:0] alu_out;
task unexpected;
inout [31:0] var;
input [10:0] control;
var = 0;
endtask
// Control Signal Value Names
parameter OP_xxx = 5'h0; // Don't care.
parameter OP_add = 5'h0;
parameter OP_sll = 5'h1;
parameter OP_srl = 5'h2;
parameter OP_xor = 5'h3;
parameter OP_sub = 5'h4;
parameter OP_or = 5'h5;
parameter OP_and = 5'h6;
parameter OP_slt = 5'h7;
parameter OP_seq = 5'h8;
parameter OP_b = 5'h9;
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_xor : 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[4:0];
OP_srl : alu_out = alu_b >> alu_a[4:0];
OP_seq : alu_out = alu_a == alu_b;
OP_b : alu_out = alu_b;
default : `UNEXPECTED(alu_out,alu_op);
endcase
endmodule
// exemplar translate_off
module system_p1(exc,reset,clk);
input reset,clk;
output [7:0] exc;
wire [31:0] cpu_data_out_2, addr_1, addr_2, mem_data_out_1, mem_data_out_2;
wire [2:0] mem_err_out_1, mem_err_out_2;
wire [1:0] size_2;
wire we_2;
cpu_p1 cpu1(exc,
cpu_data_out_2, addr_1, addr_2, size_2, we_2,
mem_data_out_1, mem_data_out_2,
mem_err_out_1,mem_err_out_2,
reset,clk);
memory_2p m1( mem_data_out_1, mem_err_out_1, addr_1,
mem_data_out_2 ,mem_err_out_2, addr_2, size_2, we_2,
cpu_data_out_2,
clk);
endmodule
`include "mipspipetb.v"