testbench.v 8.33 KB
module testbench;

wire clk;							// clock
reg[31:0] PC;							// program counter
reg[31:0] instr_address;
wire[31:0] addPC4, addPCbranch, tempPC_branch, tempPC_jump, nextPC;		

wire[31:0] instr;						// loaded instruction.

wire[4:0] reg_writereg1;					// register number for the write data.
wire[31:0] reg_writedata;					// data that will be written in the register.
wire[31:0] reg_readdata1, reg_readdata2;			// data from the requested register.

wire[31:0] alu_input2;						// input data of ALU.
wire[31:0] alu_result;						// result data of ALU.
wire alu_branch;						// indicator for branch operation.

wire[31:0] mem_readdata;					// data from the requested address.

wire ctrl_regdst, ctrl_regwrite, ctrl_alusrc, ctrl_memread, ctrl_memwrite, ctrl_memtoreg, ctrl_branch, ctrl_jump, ctrl_jumpreg;
wire[3:0] ctrl_aluctrl;						// control signals.

wire[31:0] extend_output;

wire[31:0] shiftBranch_output;
wire[31:0] shiftJump_output;

Clock clock(clk);
InstructionMemory instrmem(instr_address, instr);
Register register(clk, instr[25:21], instr[20:16], reg_writereg1, reg_writedata,  ctrl_regwrite,  reg_readdata1, reg_readdata2);
ALU alu(clk, reg_readdata1, alu_input2,  ctrl_aluctrl,  alu_result, alu_branch);
DataMemory datamem(clk, alu_result, reg_readdata2,  ctrl_memread, ctrl_memwrite,  mem_readdata);
Control ctrl(instr[31:26], instr[5:0], ctrl_regdst, ctrl_regwrite, ctrl_alusrc, ctrl_aluctrl, ctrl_memread, ctrl_memwrite, ctrl_memtoreg, ctrl_branch, ctrl_jump, ctrl_jumpreg);
Mux5bit mux_writereg(instr[20:16], instr[15:11],  ctrl_regdst,  reg_writereg1);
Mux32bit mux_alu(reg_readdata2, extend_output,  ctrl_alusrc,  alu_input2);
Mux32bit mux_writedata(alu_result, mem_readdata,  ctrl_memtoreg,  reg_writedata);
Mux32bit mux_branch(addPC4, addPCbranch,  {ctrl_branch&alu_branch} ,  tempPC_branch);
Mux32bit mux_jumpreg({addPC4[31:28], shiftJump_output[27:0]}, reg_readdata1,  ctrl_jumpreg,  tempPC_jump);
Mux32bit mux_jump(tempPC_branch, tempPC_jump,  ctrl_jump,  nextPC);
SignExtend extend(instr[15:0], extend_output);
Adder add_pc4(PC, 32'h00000004, addPC4);
Adder add_branch(addPC4, shiftBranch_output, addPCbranch);
ShiftLeft2 shiftBranch(extend_output, shiftBranch_output);
ShiftLeft2 shiftJump({6'b000000, instr[25:0]}, shiftJump_output);

initial begin
	PC = 32'h00000000;
end

always @(posedge clk) begin
	case(nextPC[31])					// if nextPC is available, PC = nextPC.
		1'b0: PC = nextPC;
		1'b1: PC = nextPC;
	endcase

	instr_address = PC;
end

/*
wire clk;							// clock
reg[31:0] PC, nextPC;						// program counter

// Instruction Memory (IM)
reg[31:0] address;						// instruction address.	input of IM.
wire[31:0] instr;						// loaded instruction.	output of IM

// Register
reg[4:0] reg_readreg1, reg_readreg2;				// register numbers of the read data.		input of register.
reg[4:0] reg_writereg1;						// register number for the write data.		input of register.
reg[31:0] reg_writedata;					// data that will be written in the register.	input of register.
reg reg_sig_regwrite;						// regwrite control signal.			input of register
wire[31:0] reg_readdata1, reg_readdata2;			// data from the requested register.		outputs of register.

// ALU
reg[31:0] alu_input1, alu_input2;				// input data of ALU.			inputs of ALU.
reg[3:0] alu_control;						// ALU control signal.			input of ALU.
wire[31:0] alu_result;						// result data of ALU.			output of ALU.
wire alu_branch;						// indicator for branch operation.	output of ALU.

//Data Memory (DM)
reg[31:0] mem_addr;						// address of the read data.			input of DM.
reg[31:0] mem_writedata;					// data that will be written in the memory.	input of DM.
reg mem_memread, mem_memwrite;					// control signals for DM.			input of DM.
wire[31:0] mem_readdata;					// data from the requested address.		output of DM.

// Control Unit
reg[5:0] ctrl_opcode;						// opcode of the instruction.	input of control unit.
wire ctrl_regdst, ctrl_regwrite, ctrl_alusrc, ctrl_memread;	// ??
wire ctrl_memwrite, ctrl_memtoreg, ctrl_branch, ctrl_jump;	// ??? control signals	outputs of control unit.
wire[1:0] ctrl_aluop;						// ??

// ALU Control Unit
reg[5:0] aluctrl_funct;						// function code of the R type instructions.	input of ALU control unit.
reg[1:0] aluctrl_aluop;						// aluop signal.				input of ALU control unit.
wire[3:0] aluctrl_sig;						// alu control signal.				output of ALU control unit.

// Multiplexer (Mux)
	// mux_writereg		Mux for Write Register.
reg[4:0] mux_writereg_input1, mux_writereg_input2;
reg mux_writereg_signal;
wire[4:0] mux_writereg_output;
	// mux_alu		Mux for ALU input 2.
reg[31:0] mux_alu_input1, mux_alu_input2;
reg mux_alu_signal;	
wire[31:0] mux_alu_output;
	// mux_writedata	Mux for Write Data of Register.
reg[31:0] mux_writedata_input1, mux_writedata_input2;
reg mux_writedata_signal;
wire[31:0] mux_writedata_output;
	// mux_branch		Mux for Branch
reg[31:0] mux_branch_input1, mux_branch_input2;
reg mux_branch_signal;
wire[31:0] mux_branch_output;
	// mux_jump		Mux for Jump
reg[31:0] mux_jump_input1, mux_jump_input2;
reg mux_jump_signal;
wire[31:0] mux_jump_output;

// Sign Extend
reg[15:0] extend_input;
wire[31:0] extend_output;

// Adder
	// add_pc4
reg[31:0] add_pc4_input;	// input2 is 4.
wire[31:0] add_pc4_output;
	// add_branch
reg[31:0] add_branch_input1, add_branch_input2;
wire[31:0] add_branch_output;

// Shift Left 2
	// shiftBranch		ShiftLeft2 which is used for Branch instructions.
reg[31:0] shiftBranch_input;
wire[31:0] shiftBranch_output;
	// shiftJump		ShiftLeft2 which is used for Jump instructions.
reg[31:0] shiftJump_input;
wire[31:0] shiftJump_output;


Clock clock(clk);
InstructionMemory instrmem(address, instr);
Register register(reg_readreg1, reg_readreg2, reg_writereg1, reg_writedata,  reg_sig_regwrite,  reg_readdata1, reg_readdata2);
ALU alu(alu_input1, alu_input2,  alu_control,  alu_result, alu_branch);
DataMemory datamem(mem_addr, mem_writedata,  mem_memread, mem_memwrite,  mem_readdata);
Control ctrl(ctrl_opcode, ctrl_regdst, ctrl_regwrite, ctrl_alusrc, ctrl_aluop, ctrl_memread, ctrl_memwrite, ctrl_memtoreg, ctrl_branch, ctrl_jump);
ALUControl aluctrl(aluctrl_funct, aluctrl_aluop, aluctrl_sig);
Mux5bit mux_writereg(mux_writereg_input1, mux_writereg_input2,  mux_writereg_signal,  mux_writereg_output);
Mux32bit mux_alu(mux_alu_input1, mux_alu_input2,  mux_alu_signal,  mux_alu_output);
Mux32bit mux_writedata(mux_writedata_input1, mux_writedata_input2,  mux_writedata_signal,  mux_writedata_output);
Mux32bit mux_branch(mux_branch_input1, mux_branch_input2,  mux_branch_signal,  mux_branch_output);
Mux32bit mux_jump(mux_jump_input1, mux_jump_input2,  mux_jump_signal,  mux_jump_output);
SignExtend extend(extend_input, extend_output);
Adder add_pc4(add_pc4_input, 32'h00000004, add_pc4_output);
Adder add_branch(add_branch_input1, add_branch_input2, add_branch_output);
ShiftLeft2 shiftBranch(shiftBranch_input, shiftBranch_output);
ShiftLeft2 shiftJump(shiftJump_input, shiftJump_output);

initial begin
	PC = 32'h00000000;
	nextPC = 32'h00000000;
end

always @(posedge clk) begin
// IF
	case(nextPC[0])
		1'b0: PC = nextPC;
		1'b1: PC = nextPC;
	endcase
#1;
	address = PC;
	add_pc4_input = PC;
#1;
// ID
	ctrl_opcode <= instr[31:26];
	reg_readreg1 <= instr[25:21];
	reg_readreg2 <= instr[20:16];
	mux_writereg_input1 <= instr[20:16];
	mux_writereg_input2 <= instr[15:11];
	extend_input <= instr[15:0];
	aluctrl_funct <= instr[5:0];
	shiftJump_input <= {6'b000000, instr[25:0]};
#1;
	mux_writereg_signal <= ctrl_regdst;
	aluctrl_aluop <= ctrl_aluop;

// EX
	mux_alu_input1 <= reg_readdata2;
	mux_alu_input2 <= extend_output;
	mux_alu_signal <= ctrl_alusrc;
	shiftBranch_input <= extend_output;
#1;
	alu_input1 <= reg_readdata1;
	alu_input2 <= mux_alu_output;
	alu_control <= aluctrl_sig;
	add_branch_input1 <= add_pc4_output;
	add_branch_input2 <= shiftBranch_output;
#1;
	mux_branch_input1 <= add_pc4_output;
	mux_branch_input2 <= add_branch_output;
	mux_branch_signal <= ctrl_branch & alu_branch;
#1;
	
// MEM
	mux_jump_input1 <= mux_branch_output;
	mux_jump_input2 <= {add_pc4_output[31:28], shiftJump_output[27:0]};
	mux_jump_signal <= ctrl_jump;
	mem_addr <= alu_result;
	mem_writedata <= reg_readdata2;
	mem_memread <= ctrl_memread;
	mem_memwrite <= ctrl_memwrite;
#1;
// WB
	mux_writedata_input1 <= alu_result;
	mux_writedata_input2 <= mem_readdata;
	mux_writedata_signal <= ctrl_memtoreg;
#1;
	reg_sig_regwrite <= ctrl_regwrite;
	reg_writereg1 <= mux_writereg_output;
	reg_writedata <= mux_writedata_output;
#1;
	nextPC <= mux_jump_output;
end
*/
endmodule