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, jal;
- 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, jal,
- alusrcb, pcsrc, alucontrol);
- datapath dp(clk, reset,
- pcen, irwrite, regwrite,
- alusrca, iord, memtoreg, regdst, jal,
- 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, jal,
- output logic [1:0] aregdst, lusrcb, pcsrc,
- output logic [2:0] alucontrol);
- logic [1:0] aluop;
- logic branch, pcwrite;
- // Main Decoder and ALU Decoder subunits.
- maindec md(clk, reset, op,
- pcwrite, memwrite, irwrite, regwrite,
- alusrca, branch, iord, memtoreg, regdst, jal,
- alusrcb, pcsrc, aluop);
- aludec ad(funct, aluop, alucontrol);
- assign pcen = pcwrite | branch & 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, jal,
- 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 IWB = 4'b1010; // state 10
- parameter JEX = 4'b1011; // State 11
- parameter ORIEX = 4'b1100; // State 12
- parameter JALEX = 4'b1101; // state 14
- parameter JALWB = 4'b1110; // state 15
- 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 ORI = 6'b001100; // Opcode for ori
- parameter J = 6'b000010; // Opcode for j
- parameter JAL = 6'b000011; // Opcode for jal
- 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;
- ORI: nextstate <= ORIEX;
- J: nextstate <= JEX;
- JAL: nextstate <= JALEX;
- 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 <= IWB;
- ORIEX: nextstate <= IWB;
- IWB: nextstate <= FETCH;
- JEX: nextstate <= FETCH;
- JALEX: nextstate <= JALWB;
- default: nextstate <= 4'bx; // should never happen
- endcase
- // output logic
- assign {pcwrite, memwrite, irwrite, regwrite,
- alusrca, branch, iord, memtoreg, regdst, jal,
- alusrcb, pcsrc, aluop} = controls;
- always_comb
- case(state)
- FETCH: controls <= 16'b10100000_00_01_00_00; //pcwrite, irwrite
- DECODE: controls <= 16'b00000000_00_11_00_00;
- MEMADR: controls <= 16'b00001000_00_10_00_00; //alusrca
- MEMRD: controls <= 16'b00000010_00_00_00_00; //iord
- MEMWB: controls <= 16'b00010001_00_00_00_00; //regwrite, memtoreg
- MEMWR: controls <= 16'b01000010_00_00_00_00; //memwrite, iord
- RTYPEEX: controls <= 16'b00001000_00_00_00_10; //alusrca
- RTYPEWB: controls <= 16'b00010000_10_00_00_00; //regwrite
- BEQEX: controls <= 16'b00001100_00_00_01_01; //alusrca, regwrite
- ADDIEX: controls <= 16'b00001000_00_10_00_00; //alusrca
- IWB: controls <= 16'b00010000_00_00_00_00; //regwrite
- ORIEX: controls <= 16'b00001000_00_10_00_11; //alusrca
- JEX: controls <= 16'b10000000_00_00_10_00; //pcwrite
- JALEX: controls <= 16'b10000000_01_01_00_00; //pcwrite
- JALWB: controls <= 16'b10010000_01_01_10_00;
- 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; // or
- 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, jal,
- 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);
- mux3 #(5) regdstmux(instr[20:16], instr[15:11], 5'b11111, {regdst, jal}, 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