// pipe2.v Verilog version using modules in this file // basic five stage pipeline of just Instruction Register // The 411 course pipeline has the same five stages // IF Instruction Fetch includes PC and instruction memory // ID Instruction Decode and registers // EX Execution including the ALU Arithmetic Logic Unit // MEM data Memory // WB Write Back into registers // // This self contained Verilog file defines: // // a 32 bit adder module using behavioral code // 32 and 5 bit register module with clock and clear inputs // an instruction memory module using behavioral code // a data memory module using behavioral code // a general register module using behavioral code // 32 and 5 bit multiplexor module using behavioral code // // a top level module, pipe2, test bench // the wires for interconnecting the entities // the modules instantiated to connect the wires // printout that shows the registers in the pipeline each clock // `timescale 1ps/1ps // times in pico seconds module add32(a, b, cin, sum, cout); parameter n=31; input [n:0] a; // a input input [n:0] b; // b input input cin; // carry-in output [n:0] sum; // sum output output cout; // carry-out assign #250 {cout, sum} = a + b + cin; endmodule // add32 module register_32(clk, clear, inp, out); input clk; // accept inp on posedge input clear; // clear when high input [31:0] inp; // input data output [31:0] out; // output of register wire [31:0] inp; wire [31:0] out; reg [31:0] stored; // temporary variable initial stored = 32'h00000000; assign out = stored; // set output wire always @(posedge clk) #200 stored <= inp; endmodule // register_32 module register_5(clk, clear, inp, out); input clk; // accept inp on posedge input clear; // clear when high input [4:0] inp; // input data output [4:0] out; // output of register wire [4:0] out; reg [4:0] stored; // temporary variable initial stored = 5'b00000; assign out = stored; // set output wire always @(posedge clk) #200 stored <= inp; endmodule // register_5 module instruction_memory(addr, inst); input [31:0] addr; output [31:0] inst; integer word_addr; reg [31:0] memory [0:15]; reg [31:0] inst_word; assign inst = inst_word; function [31:0] to_integer; input [31:0] argument; to_integer = argument; endfunction // to_integer initial begin memory[0] = 32'b10001100000000010000000000000100; // lw memory[1] = 32'b10001100000000100000000000001000; // lw memory[2] = 32'b00000000000000000000000000000000; // nop memory[3] = 32'b00000000000000000000000000000000; // nop memory[4] = 32'b00000000001000100001100000100000; // add memory[5] = 32'b00000000011000100010000000100010; // sub memory[6] = 32'b00000000000000010010101111000001; // sll memory[7] = 32'b00000000000000100011010000000010; // srl memory[8] = 32'b00000000000000110011100000000100; // cmpl memory[9] = 32'b10101100000000010000000000001000; // sw memory[10]= 32'b00000000000000000000000000000000; // nop memory[11]= 32'b00000000000000000000000000000000; // nop memory[12]= 32'b00000000000000000000000000000000; // nop memory[13]= 32'b00000000000000000000000000000000; // nop memory[14]= 32'b00000000000000000000000000000000; // nop memory[15]= 32'b00000000000000000000000000000000; // nop end always @(addr) begin // behavior word_addr = to_integer(addr)/4; #250 inst_word = memory[word_addr]; end endmodule // instruction_memory module data_memory(address, write_data, read_enable, write_enable, write_clk, read_data); input [31:0] address; input [31:0] write_data; input read_enable; input write_enable; input write_clk; output [31:0] read_data; wire [31:0] read_data; integer word_addr; integer write_addr; reg [31:0] memory [0:1000]; reg [31:0] data_word; assign read_data = data_word; function [31:0] to_integer; input [31:0] argument; to_integer = argument; endfunction // to_integer initial begin memory[0] = 32'b00010001000100010001000100010001; // h0 memory[1] = 32'b00100010001000100010001000100010; // h4 memory[2] = 32'b00110011001100110011001100110011; // h8 end // rest is XXXXXXXXXX always @(address or posedge read_enable) begin // behavior word_addr = to_integer(address)/4; if(read_enable==1) #250 data_word <= memory[word_addr]; end always @(negedge read_enable) #200 data_word = 32'b00000000000000000000000000000000; always @(posedge write_clk) begin if(write_enable==1) begin write_addr = to_integer(address)/4; memory[write_addr] = write_data; end end endmodule // data_memory module registers(read_reg_1, read_reg_2, write_reg, write_data, write_enable, write_clk, read_data_1, read_data_2); input [4:0] read_reg_1; // 5 bit register address to read data 1 input [4:0] read_reg_2; // 5 bit register address to read data 2 input [4:0] write_reg; // 5 bit register address to write input [31:0] write_data; // 32 bit word to write into register input write_enable; // rising clock and enable input write_clk; // required to write output [31:0] read_data_1; // register content of read_reg_1 output [31:0] read_data_2; // register content of read_reg_2 wire [31:0] read_data_1; wire [31:0] read_data_2; integer reg_addr_1; integer reg_addr_2; integer write_addr; integer i; reg [31:0] memory [0:31]; reg [31:0] reg_word_1; reg [31:0] reg_word_2; assign read_data_1 = reg_word_1; assign read_data_2 = reg_word_2; function [5:0] to_integer; input [5:0] argument; to_integer = argument; endfunction // to_integer initial begin for(i=0; i<32; i=i+1) memory[i] = 32'h00000000; reg_word_1 = 32'h00000000; reg_word_2 = 32'h00000000; end always @(read_reg_1) begin reg_addr_1 = to_integer(read_reg_1); #50 reg_word_1 <= memory[reg_addr_1]; end always @(read_reg_2) begin reg_addr_2 = to_integer(read_reg_2); #50 reg_word_2 <= memory[reg_addr_2]; end always @(posedge write_clk) begin // behavior write_addr = to_integer(write_reg); if(write_enable==1) begin #100 memory[write_addr] = write_data; if(write_reg==read_reg_1) reg_word_1 = write_data; if(write_reg==read_reg_2) reg_word_2 = write_data; end end endmodule // registers module mux_32(in0, in1, ctl, result); parameter n=31; input [n:0] in0; // 0 input input [n:0] in1; // 1 input input ctl; // control output [n:0] result; // output assign result = (ctl==0) ? in0 : in1; endmodule // mux_32 module mux_5(in0, in1, ctl, result); parameter n=4; input [n:0] in0; // 0 input input [n:0] in1; // 1 input input ctl; // control output [n:0] result; // output assign result = (ctl==0) ? in0 : in1; endmodule // mux_5 module alu_32(inA, inB, inst, result); input [31:0] inA; input [31:0] inB; input [31:0] inst; output [31:0] result; wire [31:0] result; reg cin; //=0 wire cout; initial cin=0; add32 adder(inA, inB, cin, result, cout); endmodule // alu_32 module pipe2; // test bench // signals used in test bench (the interconnections) reg [31:0] zero_32; // = 32'h00000000; // 32 bit zero reg zero; // = 0; // one bit zero reg [31:0] four_32; // = 32'h00000004; // four reg clear; // = 1; // one shot clear reg clk; // = 0; // master clock wire clk_bar; // split phase for mem write integer counter; // = 0; // master clock counter, raising edge wire nc1; // a No-Connection for unused output wire [31:0] PC_next; // next value of PC wire [31:0] PC; // Program Counter wire [31:0] inst; // instruction fetched wire [31:0] ID_IR; // ID Instruction Register wire [31:0] ID_read_data_1; // ID Register read data 1 wire [31:0] ID_read_data_2; // ID Register read data 2 wire [31:0] ID_sign_ext; // ID sign extension wire [4:0] ID_rd; // ID register destination wire [15:0] ID_addr; // ID_IR[15:0] address wire RegDst; //=0 // ID selects destination register wire S; // ID for sign extend wire [31:0] EX_IR; // EX Instruction Register wire [31:0] EX_A; // EX data A wire [31:0] EX_B; // EX data B wire [31:0] EX_C; // EX data C wire [4:0] EX_rd; // EX register destination wire [31:0] EX_aluB; // EX into ALU B wire ALUSrc; //=1 // EX ALU B side source control wire [31:0] EX_result; // EX ALU output wire [31:0] MEM_IR; // MEM Instruction Register wire [31:0] MEM_addr; // MEM address wire [31:0] MEM_data; // MEM write data wire [31:0] MEM_read_data; // MEM read data wire [4:0] MEM_rd; // MEM register destination wire MEMRead; // MEM enable read wire MEMWrite; //=0; // MEM enable write wire [31:0] WB_IR; // WB Instruction Register wire [31:0] WB_read; // WB read data wire [31:0] WB_pass; // WB pass data wire [4:0] WB_rd; // WB register destination wire MemtoReg; // WB mux control wire [31:0] WB_result; // WB mux output wire WB_write_enb; //=1 // WB enable register write function [31:0] to_integer; input [31:0] argument; to_integer = argument; endfunction // to_integer initial begin zero_32 = 32'h00000000; // 32 bit zero zero = 0; // one bit zero four_32 = 32'h00000004; // four clear = 1; // one shot clear clk = 0; // master clock counter = 0; // master clock counter, raising edge #200 clear = 0; // clear time finished forever #5000 clk = ~clk; // run clock 10ns period end initial #140000 $finish; // stop after 140 ns assign ALUSrc = 1; // change to correct expression assign RegDst = 0; // change to correct expression assign MEMWrite = 0; // change to correct expression assign WB_write_enb = 1; // change to correct expression // schematic of pipe2, behavior and test bench assign clk_bar = ~clk; // for split phase registers // IF, Instruction Fetch pipeline stage register_32 PC_reg(clk, clear, PC_next, PC); add32 PC_incr(PC, four_32, zero, PC_next, nc1); instruction_memory inst_mem(PC, inst); // ID, Instruction Decode and register stack pipeline stage register_32 ID_IR_reg(clk, clear, inst, ID_IR); registers ID_regs(.read_reg_1(ID_IR[25:21]), .read_reg_2(ID_IR[20:16]), .write_reg(WB_rd), .write_data(WB_result), .write_enable(WB_write_enb), .write_clk(clk_bar), .read_data_1(ID_read_data_1), .read_data_2(ID_read_data_2)); mux_5 ID_mux_rd(.in0(ID_IR[20:16]), .in1(ID_IR[15:11]), .ctl(RegDst), .result(ID_rd)); assign ID_sign_ext[15:0] = ID_IR[15:0]; // just wiring assign ID_sign_ext[31:16] = {S,S,S,S,S,S,S,S,S,S,S,S,S,S,S,S}; assign S = ID_IR[15]; // EX, Execute pipeline stage register_32 EX_IR_reg(clk, clear, ID_IR, EX_IR); register_32 EX_A_reg(clk, clear, ID_read_data_1, EX_A); register_32 EX_B_reg(clk, clear, ID_read_data_2, EX_B); register_32 EX_C_reg(clk, clear, ID_sign_ext, EX_C); register_5 EX_rd_reg(clk, clear, ID_rd, EX_rd); mux_32 EX_mux1(.in0(EX_B), .in1(EX_C), .ctl(ALUSrc), .result(EX_aluB)); alu_32 ALU(.inA(EX_A), .inB(EX_aluB), .inst(EX_IR), .result(EX_result)); // MEM Data Memory pipeline stage register_32 MEM_IR_reg(clk, clear, EX_IR, MEM_IR); register_32 MEM_addr_reg(clk, clear, EX_result, MEM_addr); register_32 MEM_data_reg(clk, clear, EX_B, MEM_data); register_5 MEM_rd_reg(clk, clear, EX_rd, MEM_rd); assign MEMRead = (MEM_IR[31:26] == 6'b100011 ); data_memory data_mem(.address(MEM_addr), .write_data(MEM_data), .read_enable(MEMRead), .write_enable(MEMWrite), .write_clk(clk_bar), .read_data(MEM_read_data)); // WB, Write Back pipeline stage register_32 WB_IR_reg(clk, clear, MEM_IR, WB_IR); register_32 WB_read_reg(clk, clear, MEM_read_data, WB_read); register_32 WB_pass_reg(clk, clear, MEM_addr, WB_pass); register_5 WB_rd_reg(clk, clear, MEM_rd, WB_rd); assign MemtoReg = (WB_IR[31:26] == 6'b100011 ); mux_32 WB_mux(.in0(WB_pass), .in1(WB_read), .ctl(MemtoReg), .result(WB_result)); always @(posedge clk) // to show state of registers in pipeline begin $write("clock %0d", counter); $write(" inst=%h", inst); $write(" PC =%h", PC); $write(" PCnext=%h", PC_next); $write("\n"); $write("ID stage IR=%h", ID_IR); if((WB_write_enb==1)&&(WB_rd!=5'b00000)) begin $write(" write=%h", WB_result); $write(" into =000000%h", {3'b000,WB_rd}); $write(" "); end else $write(" "); $write(" rd=%b", ID_rd); $write("\n"); $write("EX stage IR=%h", EX_IR); $write(" EX_A =%h", EX_A); $write(" EX_B =%h", EX_B); $write(" EX_C =%h", EX_C); $write(" rd=%b", EX_rd); $write("\n"); $write("EX stage "); $write("EX_aluB=%h", EX_aluB); $write(" EX_res=%h", EX_result); $write("\n"); $write("MEM stage IR=%h", MEM_IR); $write(" addr =%h", MEM_addr); $write(" data =%h", MEM_data); if(MEMRead==1) $write(" read =%h", MEM_read_data); else if(MEMWrite==1) $write(" wrote=%h", MEM_data); else $write(" "); $write(" rd=%b", MEM_rd); $write("\n"); $write("WB stage IR=%h", WB_IR); $write(" read =%h", WB_read); $write(" pass =%h", WB_pass); $write(" result=%h", WB_result); $write(" rd=%b", WB_rd); $write("\n"); $write("control RegDst=%b", RegDst); $write(" ALUSrc=%b", ALUSrc); $write(" MemtoReg=%b", MemtoReg); $write(" MEMRead=%b", MEMRead); $write(" MEMWrite=%b", MEMWrite); $write(" WB_write_enb=%b", WB_write_enb); $write("\n"); $write("\n"); // blank line counter = counter+1; end endmodule // pipe2 [ [ [ 'module', 'add32', '(', [['a'], ['b'], ['cin'], ['sum'], ['cout']], ')', ';'], [ ['parameter', ['n', '=', '31'], ';'], ['input', '[', ['n'], ':', '0', ']', 'a', ';'], ['input', '[', ['n'], ':', '0', ']', 'b', ';'], ['input', 'cin', ';'], ['output', '[', ['n'], ':', '0', ']', 'sum', ';'], ['output', 'cout', ';'], [ 'assign', ['#', '250'], [['{', ['cout'], ['sum'], '}'], '=', ['a'], '+', ['b'], '+', ['cin']], ';']], 'endmodule'], [ [ 'module', 'register_32', '(', [['clk'], ['clear'], ['inp'], ['out']], ')', ';'], [ ['input', 'clk', ';'], ['input', 'clear', ';'], ['input', '[', '31', ':', '0', ']', 'inp', ';'], ['output', '[', '31', ':', '0', ']', 'out', ';'], ['wire', '[', '31', ':', '0', ']', ['inp'], ';'], ['wire', '[', '31', ':', '0', ']', ['out'], ';'], ['reg', '[', '31', ':', '0', ']', ['stored'], ';'], ['initial', [[['stored'], '=', "32 'h 00000000"], ';']], ['assign', [['out'], '=', ['stored']], ';'], [ 'always', ['@', '(', ['posedge', ['clk']], ')'], [['#', '200'], [[['stored'], '<=', ['inp']], ';']]]], 'endmodule'], [ [ 'module', 'register_5', '(', [['clk'], ['clear'], ['inp'], ['out']], ')', ';'], [ ['input', 'clk', ';'], ['input', 'clear', ';'], ['input', '[', '4', ':', '0', ']', 'inp', ';'], ['output', '[', '4', ':', '0', ']', 'out', ';'], ['wire', '[', '4', ':', '0', ']', ['out'], ';'], ['reg', '[', '4', ':', '0', ']', ['stored'], ';'], ['initial', [[['stored'], '=', "5 'b 00000"], ';']], ['assign', [['out'], '=', ['stored']], ';'], [ 'always', ['@', '(', ['posedge', ['clk']], ')'], [['#', '200'], [[['stored'], '<=', ['inp']], ';']]]], 'endmodule'], [ ['module', 'instruction_memory', '(', [['addr'], ['inst']], ')', ';'], [ ['input', '[', '31', ':', '0', ']', 'addr', ';'], ['output', '[', '31', ':', '0', ']', 'inst', ';'], ['integer', ['word_addr'], ';'], [ 'reg', '[', '31', ':', '0', ']', ['memory', '[', '0', ':', '15', ']'], ';'], ['reg', '[', '31', ':', '0', ']', ['inst_word'], ';'], ['assign', [['inst'], '=', ['inst_word']], ';'], [ 'function', '[', '31', ':', '0', ']', 'to_integer', ';', [['input', '[', '31', ':', '0', ']', 'argument', ';']], [[[['to_integer'], '=', ['argument']], ';']], 'endfunction'], [ 'initial', [ 'begin', [ [ [ ['memory', ['[', '0', ']']], '=', "32 'b 10001100000000010000000000000100"], ';'], [ [ ['memory', ['[', '1', ']']], '=', "32 'b 10001100000000100000000000001000"], ';'], [ [ ['memory', ['[', '2', ']']], '=', "32 'b 00000000000000000000000000000000"], ';'], [ [ ['memory', ['[', '3', ']']], '=', "32 'b 00000000000000000000000000000000"], ';'], [ [ ['memory', ['[', '4', ']']], '=', "32 'b 00000000001000100001100000100000"], ';'], [ [ ['memory', ['[', '5', ']']], '=', "32 'b 00000000011000100010000000100010"], ';'], [ [ ['memory', ['[', '6', ']']], '=', "32 'b 00000000000000010010101111000001"], ';'], [ [ ['memory', ['[', '7', ']']], '=', "32 'b 00000000000000100011010000000010"], ';'], [ [ ['memory', ['[', '8', ']']], '=', "32 'b 00000000000000110011100000000100"], ';'], [ [ ['memory', ['[', '9', ']']], '=', "32 'b 10101100000000010000000000001000"], ';'], [ [ ['memory', ['[', '10', ']']], '=', "32 'b 00000000000000000000000000000000"], ';'], [ [ ['memory', ['[', '11', ']']], '=', "32 'b 00000000000000000000000000000000"], ';'], [ [ ['memory', ['[', '12', ']']], '=', "32 'b 00000000000000000000000000000000"], ';'], [ [ ['memory', ['[', '13', ']']], '=', "32 'b 00000000000000000000000000000000"], ';'], [ [ ['memory', ['[', '14', ']']], '=', "32 'b 00000000000000000000000000000000"], ';'], [ [ ['memory', ['[', '15', ']']], '=', "32 'b 00000000000000000000000000000000"], ';']], 'end']], [ 'always', ['@', '(', [['addr']], ')'], [ 'begin', [ [ [ ['word_addr'], '=', ['to_integer', '(', ['addr'], ')'], '/', '4'], ';'], [ ['#', '250'], [ [['inst_word'], '=', ['memory', ['[', ['word_addr'], ']']]], ';']]], 'end']]], 'endmodule'], [ [ 'module', 'data_memory', '(', [ ['address'], ['write_data'], ['read_enable'], ['write_enable'], ['write_clk'], ['read_data']], ')', ';'], [ ['input', '[', '31', ':', '0', ']', 'address', ';'], ['input', '[', '31', ':', '0', ']', 'write_data', ';'], ['input', 'read_enable', ';'], ['input', 'write_enable', ';'], ['input', 'write_clk', ';'], ['output', '[', '31', ':', '0', ']', 'read_data', ';'], ['wire', '[', '31', ':', '0', ']', ['read_data'], ';'], ['integer', ['word_addr'], ';'], ['integer', ['write_addr'], ';'], [ 'reg', '[', '31', ':', '0', ']', ['memory', '[', '0', ':', '1000', ']'], ';'], ['reg', '[', '31', ':', '0', ']', ['data_word'], ';'], ['assign', [['read_data'], '=', ['data_word']], ';'], [ 'function', '[', '31', ':', '0', ']', 'to_integer', ';', [['input', '[', '31', ':', '0', ']', 'argument', ';']], [[[['to_integer'], '=', ['argument']], ';']], 'endfunction'], [ 'initial', [ 'begin', [ [ [ ['memory', ['[', '0', ']']], '=', "32 'b 00010001000100010001000100010001"], ';'], [ [ ['memory', ['[', '1', ']']], '=', "32 'b 00100010001000100010001000100010"], ';'], [ [ ['memory', ['[', '2', ']']], '=', "32 'b 00110011001100110011001100110011"], ';']], 'end']], [ 'always', ['@', '(', [['address'], 'posedge', ['read_enable']], ')'], [ 'begin', [ [ [ ['word_addr'], '=', ['to_integer', '(', ['address'], ')'], '/', '4'], ';'], [ 'if', ['(', ['read_enable'], '==', '1', ')'], [ ['#', '250'], [ [['data_word'], '<=', ['memory', ['[', ['word_addr'], ']']]], ';']]]], 'end']], [ 'always', ['@', '(', ['negedge', ['read_enable']], ')'], [ ['#', '200'], [ [['data_word'], '=', "32 'b 00000000000000000000000000000000"], ';']]], [ 'always', ['@', '(', ['posedge', ['write_clk']], ')'], [ 'begin', [ [ 'if', ['(', ['write_enable'], '==', '1', ')'], [ 'begin', [ [ [ ['write_addr'], '=', ['to_integer', '(', ['address'], ')'], '/', '4'], ';'], [ [ ['memory', ['[', ['write_addr'], ']']], '=', ['write_data']], ';']], 'end']]], 'end']]], 'endmodule'], [ [ 'module', 'registers', '(', [ ['read_reg_1'], ['read_reg_2'], ['write_reg'], ['write_data'], ['write_enable'], ['write_clk'], ['read_data_1'], ['read_data_2']], ')', ';'], [ ['input', '[', '4', ':', '0', ']', 'read_reg_1', ';'], ['input', '[', '4', ':', '0', ']', 'read_reg_2', ';'], ['input', '[', '4', ':', '0', ']', 'write_reg', ';'], ['input', '[', '31', ':', '0', ']', 'write_data', ';'], ['input', 'write_enable', ';'], ['input', 'write_clk', ';'], ['output', '[', '31', ':', '0', ']', 'read_data_1', ';'], ['output', '[', '31', ':', '0', ']', 'read_data_2', ';'], ['wire', '[', '31', ':', '0', ']', ['read_data_1'], ';'], ['wire', '[', '31', ':', '0', ']', ['read_data_2'], ';'], ['integer', ['reg_addr_1'], ';'], ['integer', ['reg_addr_2'], ';'], ['integer', ['write_addr'], ';'], ['integer', ['i'], ';'], [ 'reg', '[', '31', ':', '0', ']', ['memory', '[', '0', ':', '31', ']'], ';'], ['reg', '[', '31', ':', '0', ']', ['reg_word_1'], ';'], ['reg', '[', '31', ':', '0', ']', ['reg_word_2'], ';'], ['assign', [['read_data_1'], '=', ['reg_word_1']], ';'], ['assign', [['read_data_2'], '=', ['reg_word_2']], ';'], [ 'function', '[', '5', ':', '0', ']', 'to_integer', ';', [['input', '[', '5', ':', '0', ']', 'argument', ';']], [[[['to_integer'], '=', ['argument']], ';']], 'endfunction'], [ 'initial', [ 'begin', [ [ 'for', '(', [['i'], '=', '0'], ';', [['i'], '<', '32'], ';', [['i'], '=', ['i'], '+', '1'], ')', [[['memory', ['[', ['i'], ']']], '=', "32 'h 00000000"], ';']], [[['reg_word_1'], '=', "32 'h 00000000"], ';'], [[['reg_word_2'], '=', "32 'h 00000000"], ';']], 'end']], [ 'always', ['@', '(', [['read_reg_1']], ')'], [ 'begin', [ [ [['reg_addr_1'], '=', ['to_integer', '(', ['read_reg_1'], ')']], ';'], [ ['#', '50'], [ [['reg_word_1'], '<=', ['memory', ['[', ['reg_addr_1'], ']']]], ';']]], 'end']], [ 'always', ['@', '(', [['read_reg_2']], ')'], [ 'begin', [ [ [['reg_addr_2'], '=', ['to_integer', '(', ['read_reg_2'], ')']], ';'], [ ['#', '50'], [ [['reg_word_2'], '<=', ['memory', ['[', ['reg_addr_2'], ']']]], ';']]], 'end']], [ 'always', ['@', '(', ['posedge', ['write_clk']], ')'], [ 'begin', [ [ [['write_addr'], '=', ['to_integer', '(', ['write_reg'], ')']], ';'], [ 'if', ['(', ['write_enable'], '==', '1', ')'], [ 'begin', [ [ ['#', '100'], [ [ ['memory', ['[', ['write_addr'], ']']], '=', ['write_data']], ';']], [ 'if', ['(', ['write_reg'], '==', ['read_reg_1'], ')'], [[['reg_word_1'], '=', ['write_data']], ';']], [ 'if', ['(', ['write_reg'], '==', ['read_reg_2'], ')'], [[['reg_word_2'], '=', ['write_data']], ';']]], 'end']]], 'end']]], 'endmodule'], [ [ 'module', 'mux_32', '(', [['in0'], ['in1'], ['ctl'], ['result']], ')', ';'], [ ['parameter', ['n', '=', '31'], ';'], ['input', '[', ['n'], ':', '0', ']', 'in0', ';'], ['input', '[', ['n'], ':', '0', ']', 'in1', ';'], ['input', 'ctl', ';'], ['output', '[', ['n'], ':', '0', ']', 'result', ';'], [ 'assign', [ ['result'], '=', '(', [['ctl'], '==', '0'], ')', '?', ['in0'], ':', ['in1']], ';']], 'endmodule'], [ ['module', 'mux_5', '(', [['in0'], ['in1'], ['ctl'], ['result']], ')', ';'], [ ['parameter', ['n', '=', '4'], ';'], ['input', '[', ['n'], ':', '0', ']', 'in0', ';'], ['input', '[', ['n'], ':', '0', ']', 'in1', ';'], ['input', 'ctl', ';'], ['output', '[', ['n'], ':', '0', ']', 'result', ';'], [ 'assign', [ ['result'], '=', '(', [['ctl'], '==', '0'], ')', '?', ['in0'], ':', ['in1']], ';']], 'endmodule'], [ [ 'module', 'alu_32', '(', [['inA'], ['inB'], ['inst'], ['result']], ')', ';'], [ ['input', '[', '31', ':', '0', ']', 'inA', ';'], ['input', '[', '31', ':', '0', ']', 'inB', ';'], ['input', '[', '31', ':', '0', ']', 'inst', ';'], ['output', '[', '31', ':', '0', ']', 'result', ';'], ['wire', '[', '31', ':', '0', ']', ['result'], ';'], ['reg', ['cin'], ';'], ['wire', ['cout'], ';'], ['initial', [[['cin'], '=', '0'], ';']], [ 'add32', [ ['adder'], ['(', ['inA'], ['inB'], ['cin'], ['result'], ['cout'], ')']], ';']], 'endmodule'], [ ['module', 'pipe2', ';'], [ ['reg', '[', '31', ':', '0', ']', ['zero_32'], ';'], ['reg', ['zero'], ';'], ['reg', '[', '31', ':', '0', ']', ['four_32'], ';'], ['reg', ['clear'], ';'], ['reg', ['clk'], ';'], ['wire', ['clk_bar'], ';'], ['integer', ['counter'], ';'], ['wire', ['nc1'], ';'], ['wire', '[', '31', ':', '0', ']', ['PC_next'], ';'], ['wire', '[', '31', ':', '0', ']', ['PC'], ';'], ['wire', '[', '31', ':', '0', ']', ['inst'], ';'], ['wire', '[', '31', ':', '0', ']', ['ID_IR'], ';'], ['wire', '[', '31', ':', '0', ']', ['ID_read_data_1'], ';'], ['wire', '[', '31', ':', '0', ']', ['ID_read_data_2'], ';'], ['wire', '[', '31', ':', '0', ']', ['ID_sign_ext'], ';'], ['wire', '[', '4', ':', '0', ']', ['ID_rd'], ';'], ['wire', '[', '15', ':', '0', ']', ['ID_addr'], ';'], ['wire', ['RegDst'], ';'], ['wire', ['S'], ';'], ['wire', '[', '31', ':', '0', ']', ['EX_IR'], ';'], ['wire', '[', '31', ':', '0', ']', ['EX_A'], ';'], ['wire', '[', '31', ':', '0', ']', ['EX_B'], ';'], ['wire', '[', '31', ':', '0', ']', ['EX_C'], ';'], ['wire', '[', '4', ':', '0', ']', ['EX_rd'], ';'], ['wire', '[', '31', ':', '0', ']', ['EX_aluB'], ';'], ['wire', ['ALUSrc'], ';'], ['wire', '[', '31', ':', '0', ']', ['EX_result'], ';'], ['wire', '[', '31', ':', '0', ']', ['MEM_IR'], ';'], ['wire', '[', '31', ':', '0', ']', ['MEM_addr'], ';'], ['wire', '[', '31', ':', '0', ']', ['MEM_data'], ';'], ['wire', '[', '31', ':', '0', ']', ['MEM_read_data'], ';'], ['wire', '[', '4', ':', '0', ']', ['MEM_rd'], ';'], ['wire', ['MEMRead'], ';'], ['wire', ['MEMWrite'], ';'], ['wire', '[', '31', ':', '0', ']', ['WB_IR'], ';'], ['wire', '[', '31', ':', '0', ']', ['WB_read'], ';'], ['wire', '[', '31', ':', '0', ']', ['WB_pass'], ';'], ['wire', '[', '4', ':', '0', ']', ['WB_rd'], ';'], ['wire', ['MemtoReg'], ';'], ['wire', '[', '31', ':', '0', ']', ['WB_result'], ';'], ['wire', ['WB_write_enb'], ';'], [ 'function', '[', '31', ':', '0', ']', 'to_integer', ';', [['input', '[', '31', ':', '0', ']', 'argument', ';']], [[[['to_integer'], '=', ['argument']], ';']], 'endfunction'], [ 'initial', [ 'begin', [ [[['zero_32'], '=', "32 'h 00000000"], ';'], [[['zero'], '=', '0'], ';'], [[['four_32'], '=', "32 'h 00000004"], ';'], [[['clear'], '=', '1'], ';'], [[['clk'], '=', '0'], ';'], [[['counter'], '=', '0'], ';'], [['#', '200'], [[['clear'], '=', '0'], ';']], ['forever', [['#', '5000'], [[['clk'], '=', '~', ['clk']], ';']]]], 'end']], ['initial', [['#', '140000'], ['$finish', ';']]], ['assign', [['ALUSrc'], '=', '1'], ';'], ['assign', [['RegDst'], '=', '0'], ';'], ['assign', [['MEMWrite'], '=', '0'], ';'], ['assign', [['WB_write_enb'], '=', '1'], ';'], ['assign', [['clk_bar'], '=', '~', ['clk']], ';'], [ 'register_32', [['PC_reg'], ['(', ['clk'], ['clear'], ['PC_next'], ['PC'], ')']], ';'], [ 'add32', [ ['PC_incr'], ['(', ['PC'], ['four_32'], ['zero'], ['PC_next'], ['nc1'], ')']], ';'], ['instruction_memory', [['inst_mem'], ['(', ['PC'], ['inst'], ')']], ';'], [ 'register_32', [['ID_IR_reg'], ['(', ['clk'], ['clear'], ['inst'], ['ID_IR'], ')']], ';'], [ 'registers', [ ['ID_regs'], [ '(', ['.', 'read_reg_1', '(', ['ID_IR', ['[', '25', '21', ']']], ')'], ['.', 'read_reg_2', '(', ['ID_IR', ['[', '20', '16', ']']], ')'], ['.', 'write_reg', '(', ['WB_rd'], ')'], ['.', 'write_data', '(', ['WB_result'], ')'], ['.', 'write_enable', '(', ['WB_write_enb'], ')'], ['.', 'write_clk', '(', ['clk_bar'], ')'], ['.', 'read_data_1', '(', ['ID_read_data_1'], ')'], ['.', 'read_data_2', '(', ['ID_read_data_2'], ')'], ')']], ';'], [ 'mux_5', [ ['ID_mux_rd'], [ '(', ['.', 'in0', '(', ['ID_IR', ['[', '20', '16', ']']], ')'], ['.', 'in1', '(', ['ID_IR', ['[', '15', '11', ']']], ')'], ['.', 'ctl', '(', ['RegDst'], ')'], ['.', 'result', '(', ['ID_rd'], ')'], ')']], ';'], [ 'assign', [ ['ID_sign_ext', ['[', '15', '0', ']']], '=', ['ID_IR', ['[', '15', '0', ']']]], ';'], [ 'assign', [ ['ID_sign_ext', ['[', '31', '16', ']']], '=', [ '{', ['S'], ['S'], ['S'], ['S'], ['S'], ['S'], ['S'], ['S'], ['S'], ['S'], ['S'], ['S'], ['S'], ['S'], ['S'], ['S'], '}']], ';'], ['assign', [['S'], '=', ['ID_IR', ['[', '15', ']']]], ';'], [ 'register_32', [['EX_IR_reg'], ['(', ['clk'], ['clear'], ['ID_IR'], ['EX_IR'], ')']], ';'], [ 'register_32', [ ['EX_A_reg'], ['(', ['clk'], ['clear'], ['ID_read_data_1'], ['EX_A'], ')']], ';'], [ 'register_32', [ ['EX_B_reg'], ['(', ['clk'], ['clear'], ['ID_read_data_2'], ['EX_B'], ')']], ';'], [ 'register_32', [ ['EX_C_reg'], ['(', ['clk'], ['clear'], ['ID_sign_ext'], ['EX_C'], ')']], ';'], [ 'register_5', [['EX_rd_reg'], ['(', ['clk'], ['clear'], ['ID_rd'], ['EX_rd'], ')']], ';'], [ 'mux_32', [ ['EX_mux1'], [ '(', ['.', 'in0', '(', ['EX_B'], ')'], ['.', 'in1', '(', ['EX_C'], ')'], ['.', 'ctl', '(', ['ALUSrc'], ')'], ['.', 'result', '(', ['EX_aluB'], ')'], ')']], ';'], [ 'alu_32', [ ['ALU'], [ '(', ['.', 'inA', '(', ['EX_A'], ')'], ['.', 'inB', '(', ['EX_aluB'], ')'], ['.', 'inst', '(', ['EX_IR'], ')'], ['.', 'result', '(', ['EX_result'], ')'], ')']], ';'], [ 'register_32', [['MEM_IR_reg'], ['(', ['clk'], ['clear'], ['EX_IR'], ['MEM_IR'], ')']], ';'], [ 'register_32', [ ['MEM_addr_reg'], ['(', ['clk'], ['clear'], ['EX_result'], ['MEM_addr'], ')']], ';'], [ 'register_32', [ ['MEM_data_reg'], ['(', ['clk'], ['clear'], ['EX_B'], ['MEM_data'], ')']], ';'], [ 'register_5', [['MEM_rd_reg'], ['(', ['clk'], ['clear'], ['EX_rd'], ['MEM_rd'], ')']], ';'], [ 'assign', [ ['MEMRead'], '=', '(', [['MEM_IR', ['[', '31', '26', ']']], '==', "6 'b 100011"], ')'], ';'], [ 'data_memory', [ ['data_mem'], [ '(', ['.', 'address', '(', ['MEM_addr'], ')'], ['.', 'write_data', '(', ['MEM_data'], ')'], ['.', 'read_enable', '(', ['MEMRead'], ')'], ['.', 'write_enable', '(', ['MEMWrite'], ')'], ['.', 'write_clk', '(', ['clk_bar'], ')'], ['.', 'read_data', '(', ['MEM_read_data'], ')'], ')']], ';'], [ 'register_32', [['WB_IR_reg'], ['(', ['clk'], ['clear'], ['MEM_IR'], ['WB_IR'], ')']], ';'], [ 'register_32', [ ['WB_read_reg'], ['(', ['clk'], ['clear'], ['MEM_read_data'], ['WB_read'], ')']], ';'], [ 'register_32', [ ['WB_pass_reg'], ['(', ['clk'], ['clear'], ['MEM_addr'], ['WB_pass'], ')']], ';'], [ 'register_5', [['WB_rd_reg'], ['(', ['clk'], ['clear'], ['MEM_rd'], ['WB_rd'], ')']], ';'], [ 'assign', [ ['MemtoReg'], '=', '(', [['WB_IR', ['[', '31', '26', ']']], '==', "6 'b 100011"], ')'], ';'], [ 'mux_32', [ ['WB_mux'], [ '(', ['.', 'in0', '(', ['WB_pass'], ')'], ['.', 'in1', '(', ['WB_read'], ')'], ['.', 'ctl', '(', ['MemtoReg'], ')'], ['.', 'result', '(', ['WB_result'], ')'], ')']], ';'], [ 'always', ['@', '(', ['posedge', ['clk']], ')'], [ 'begin', [ ['$write', '(', '"clock %0d"', ['counter'], ')', ';'], ['$write', '(', '" inst=%h"', ['inst'], ')', ';'], ['$write', '(', '" PC =%h"', ['PC'], ')', ';'], ['$write', '(', '" PCnext=%h"', ['PC_next'], ')', ';'], ['$write', '(', '"\\n"', ')', ';'], ['$write', '(', '"ID stage IR=%h"', ['ID_IR'], ')', ';'], [ 'if', [ '(', '(', [['WB_write_enb'], '==', '1'], ')', '&&', '(', [['WB_rd'], '!=', "5 'b 00000"], ')', ')'], [ 'begin', [ ['$write', '(', '" write=%h"', ['WB_result'], ')', ';'], [ '$write', '(', '" into =000000%h"', ['{', "3 'b 000", ['WB_rd'], '}'], ')', ';'], ['$write', '(', '" "', ')', ';']], 'end'], 'else', [ '$write', '(', '" "', ')', ';']], ['$write', '(', '" rd=%b"', ['ID_rd'], ')', ';'], ['$write', '(', '"\\n"', ')', ';'], ['$write', '(', '"EX stage IR=%h"', ['EX_IR'], ')', ';'], ['$write', '(', '" EX_A =%h"', ['EX_A'], ')', ';'], ['$write', '(', '" EX_B =%h"', ['EX_B'], ')', ';'], ['$write', '(', '" EX_C =%h"', ['EX_C'], ')', ';'], ['$write', '(', '" rd=%b"', ['EX_rd'], ')', ';'], ['$write', '(', '"\\n"', ')', ';'], ['$write', '(', '"EX stage "', ')', ';'], ['$write', '(', '"EX_aluB=%h"', ['EX_aluB'], ')', ';'], ['$write', '(', '" EX_res=%h"', ['EX_result'], ')', ';'], ['$write', '(', '"\\n"', ')', ';'], ['$write', '(', '"MEM stage IR=%h"', ['MEM_IR'], ')', ';'], ['$write', '(', '" addr =%h"', ['MEM_addr'], ')', ';'], ['$write', '(', '" data =%h"', ['MEM_data'], ')', ';'], [ 'if', ['(', ['MEMRead'], '==', '1', ')'], ['$write', '(', '" read =%h"', ['MEM_read_data'], ')', ';'], 'else', [ 'if', ['(', ['MEMWrite'], '==', '1', ')'], ['$write', '(', '" wrote=%h"', ['MEM_data'], ')', ';'], 'else', ['$write', '(', '" "', ')', ';']]], ['$write', '(', '" rd=%b"', ['MEM_rd'], ')', ';'], ['$write', '(', '"\\n"', ')', ';'], ['$write', '(', '"WB stage IR=%h"', ['WB_IR'], ')', ';'], ['$write', '(', '" read =%h"', ['WB_read'], ')', ';'], ['$write', '(', '" pass =%h"', ['WB_pass'], ')', ';'], ['$write', '(', '" result=%h"', ['WB_result'], ')', ';'], ['$write', '(', '" rd=%b"', ['WB_rd'], ')', ';'], ['$write', '(', '"\\n"', ')', ';'], ['$write', '(', '"control RegDst=%b"', ['RegDst'], ')', ';'], ['$write', '(', '" ALUSrc=%b"', ['ALUSrc'], ')', ';'], ['$write', '(', '" MemtoReg=%b"', ['MemtoReg'], ')', ';'], ['$write', '(', '" MEMRead=%b"', ['MEMRead'], ')', ';'], ['$write', '(', '" MEMWrite=%b"', ['MEMWrite'], ')', ';'], ['$write', '(', '" WB_write_enb=%b"', ['WB_write_enb'], ')', ';'], ['$write', '(', '"\\n"', ')', ';'], ['$write', '(', '"\\n"', ')', ';'], [[['counter'], '=', ['counter'], '+', '1'], ';']], 'end']]], 'endmodule']]