Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- //-------------------------------------------------------
- // mipsmulti.v
- // David_Harris@hmc.edu 8 November 2005
- // Update to SystemVerilog 17 Nov 2010 DMH
- // Multicycle MIPS processor
- //------------------------------------------------
- module mips(input logic clk, reset,
- output logic [31:0] adr, writedata,
- output logic memwrite,
- input logic [31:0] readdata);
- logic zero, pcen, irwrite, regwrite,
- alusrca, iord, memtoreg, regdst;
- logic [1:0] alusrcb, pcsrc;
- logic [2:0] alucontrol;
- logic [5:0] op, funct;
- controller c(clk, reset, op, funct, zero,
- pcen, memwrite, irwrite, regwrite,
- alusrca, iord, memtoreg, regdst,
- alusrcb, pcsrc, alucontrol);
- datapath dp(clk, reset,
- pcen, irwrite, regwrite,
- alusrca, iord, memtoreg, regdst,
- alusrcb, pcsrc, alucontrol,
- op, funct, zero,
- adr, writedata, readdata);
- endmodule
- module controller(input logic clk, reset,
- input logic [5:0] op, funct,
- input logic zero,
- output logic pcen, memwrite, irwrite, regwrite,
- output logic alusrca, iord, memtoreg, regdst,
- output logic [1:0] alusrcb, pcsrc,
- output logic [2:0] alucontrol);
- logic [1:0] aluop;
- logic branch, bne, pcwrite;
- // Main Decoder and ALU Decoder subunits.
- maindec md(clk, reset, op,
- pcwrite, memwrite, irwrite, regwrite,
- alusrca, branch, iord, memtoreg, regdst, bne,
- alusrcb, pcsrc, aluop);
- aludec ad(funct, aluop, alucontrol);
- assign pcen = pcwrite | branch & zero | bne & ~zero;
- endmodule
- module maindec(input logic clk, reset,
- input logic [5:0] op,
- output logic pcwrite, memwrite, irwrite, regwrite,
- output logic alusrca, branch, iord, memtoreg, regdst, bne,
- output logic [1:0] alusrcb, pcsrc,
- output logic [1:0] aluop);
- parameter FETCH = 4'b0000; // State 0
- parameter DECODE = 4'b0001; // State 1
- parameter MEMADR = 4'b0010; // State 2
- parameter MEMRD = 4'b0011; // State 3
- parameter MEMWB = 4'b0100; // State 4
- parameter MEMWR = 4'b0101; // State 5
- parameter RTYPEEX = 4'b0110; // State 6
- parameter RTYPEWB = 4'b0111; // State 7
- parameter BEQEX = 4'b1000; // State 8
- parameter ADDIEX = 4'b1001; // State 9
- parameter ADDIWB = 4'b1010; // state 10
- parameter JEX = 4'b1011; // State 11
- parameter BNEEX = 4'b1100; // State 12
- parameter LW = 6'b100011; // Opcode for lw
- parameter SW = 6'b101011; // Opcode for sw
- parameter RTYPE = 6'b000000; // Opcode for R-type
- parameter BEQ = 6'b000100; // Opcode for beq
- parameter ADDI = 6'b001000; // Opcode for addi
- parameter J = 6'b000010; // Opcode for j
- parameter BNE = 6'b000101; // Opcode for BNE
- logic [3:0] state, nextstate;
- logic [15:0] controls;
- // state register
- always_ff @(posedge clk or posedge reset)
- if(reset) state <= FETCH;
- else state <= nextstate;
- // next state logic
- always_comb
- case(state)
- FETCH: nextstate <= DECODE;
- DECODE: case(op)
- LW: nextstate <= MEMADR;
- SW: nextstate <= MEMADR;
- RTYPE: nextstate <= RTYPEEX;
- BEQ: nextstate <= BEQEX;
- ADDI: nextstate <= ADDIEX;
- J: nextstate <= JEX;
- BNE: nextstate <= BNEEX;
- default: nextstate <= 4'bx; // should never happen
- endcase
- MEMADR: case(op)
- LW: nextstate <= MEMRD;
- SW: nextstate <= MEMWR;
- default: nextstate <= 4'bx;
- endcase
- MEMRD: nextstate <= MEMWB;
- MEMWB: nextstate <= FETCH;
- MEMWR: nextstate <= FETCH;
- RTYPEEX: nextstate <= RTYPEWB;
- RTYPEWB: nextstate <= FETCH;
- BEQEX: nextstate <= FETCH;
- ADDIEX: nextstate <= ADDIWB;
- ADDIWB: nextstate <= FETCH;
- JEX: nextstate <= FETCH;
- BNEEX: nextstate <= FETCH;
- default: nextstate <= 4'bx; // should never happen
- endcase
- // output logic
- assign {bne, pcwrite, memwrite, irwrite, regwrite,
- alusrca, branch, iord, memtoreg, regdst,
- alusrcb, pcsrc, aluop} = controls;
- always_comb
- case(state)
- FETCH: controls <= 16'h5010;
- DECODE: controls <= 16'h0030;
- MEMADR: controls <= 16'h0420;
- MEMRD: controls <= 16'h0100;
- MEMWB: controls <= 16'h0880;
- MEMWR: controls <= 16'h2100;
- RTYPEEX: controls <= 16'h0402;
- RTYPEWB: controls <= 16'h0840;
- BEQEX: controls <= 16'h0605;
- ADDIEX: controls <= 16'h0420;
- ADDIWB: controls <= 16'h0800;
- JEX: controls <= 16'h4008;
- BNE: controls <= 16'h8505;
- default: controls <= 16'hxxxx; // should never happen
- endcase
- endmodule
- module aludec(input logic [5:0] funct,
- input logic [1:0] aluop,
- output logic [2:0] alucontrol);
- always @(*)
- case(aluop)
- 2'b00: alucontrol <= 3'b010; // add
- 2'b01: alucontrol <= 3'b110; // sub
- 2'b11: alucontrol <= 3'b001; // ori
- default: case(funct) // RTYPE
- 6'b100000: alucontrol <= 3'b010; // ADD
- 6'b100010: alucontrol <= 3'b110; // SUB
- 6'b100100: alucontrol <= 3'b000; // AND
- 6'b100101: alucontrol <= 3'b001; // OR
- 6'b101010: alucontrol <= 3'b111; // SLT
- default: alucontrol <= 3'bxxx; // ???
- endcase
- endcase
- endmodule
- module datapath(input logic clk, reset,
- input logic pcen, irwrite, regwrite,
- input logic alusrca, iord, memtoreg, regdst,
- input logic [1:0] alusrcb, pcsrc,
- input logic [2:0] alucontrol,
- output logic [5:0] op, funct,
- output logic zero,
- output logic [31:0] adr, writedata,
- input logic [31:0] readdata);
- // Below are the internal signals of the datapath module.
- logic [4:0] writereg;
- logic [31:0] pcnext, pc;
- logic [31:0] instr, data, srca, srcb;
- logic [31:0] a;
- logic [31:0] aluresult, aluout;
- logic [31:0] signimm; // the sign-extended immediate
- logic [31:0] signimmsh; // the sign-extended immediate shifted left by 2
- logic [31:0] wd3, rd1, rd2;
- // op and funct fields to controller
- assign op = instr[31:26];
- assign funct = instr[5:0];
- flopenr #(32) pcreg(clk, reset, pcen, pcnext, pc);
- mux2 #(32) adrmux(pc, aluout, iord, adr);
- flopenr #(32) instrreg(clk, reset, irwrite, readdata, instr);
- flopr #(32) datareg(clk, reset, readdata, data);
- mux2 #(5) regdstmux(instr[20:16], instr[15:11], regdst, writereg);
- mux2 #(32) wdmux(aluout, data, memtoreg, wd3);
- regfile rf(clk, regwrite, instr[25:21], instr[20:16], writereg, wd3, rd1, rd2);
- signext se(instr[15:0], signimm);
- sl2 immsh(signimm, signimmsh);
- flopr #(32) areg(clk, reset, rd1, a);
- flopr #(32) breg(clk, reset, rd2, writedata);
- mux2 #(32) srcamux(pc, a, alusrca, srca);
- mux4 #(32) srcbmux(writedata, 32'b100, signimm, signimmsh, alusrcb, srcb);
- alu alu(srca, srcb, alucontrol, aluresult, zero);
- flopr #(32) alureg(clk, reset, aluresult, aluout);
- mux3 #(32) pcmux(aluresult, aluout, {pc[31:28], instr[25:0], 2'b00}, pcsrc, pcnext);
- endmodule
- module mux3 #(parameter WIDTH = 8)
- (input logic [WIDTH-1:0] d0, d1, d2,
- input logic [1:0] s,
- output logic [WIDTH-1:0] y);
- assign #1 y = s[1] ? d2 : (s[0] ? d1 : d0);
- endmodule
- module mux4 #(parameter WIDTH = 8)
- (input logic [WIDTH-1:0] d0, d1, d2, d3,
- input logic [1:0] s,
- output logic [WIDTH-1:0] y);
- always_comb
- case(s)
- 2'b00: y <= d0;
- 2'b01: y <= d1;
- 2'b10: y <= d2;
- 2'b11: y <= d3;
- endcase
- endmodule
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement