OpenCores
URL https://opencores.org/ocsvn/mips32r1/mips32r1/trunk

Subversion Repositories mips32r1

Compare Revisions

  • This comparison shows the changes necessary to convert path
    /mips32r1/trunk/Hardware
    from Rev 2 to Rev 3
    Reverse comparison

Rev 2 → Rev 3

/XUPV5-LX110T_SoC/MIPS32-Pipelined-Hw/src/BRAM/BRAM_592KB_Wrapper.v
16,8 → 16,6
* which allows for multi-cycle and variably-timed operations on the
* data bus.
*/
 
 
module BRAM_592KB_Wrapper(
input clock,
input reset,
78,3 → 76,4
);
 
endmodule
 
/XUPV5-LX110T_SoC/MIPS32-Pipelined-Hw/src/LCD/LCD.v
1,203 → 1,204
`timescale 1ns / 1ps
/*
* File : LCD.v
* Project : University of Utah, XUM Project MIPS32 core
* Creator(s) : Grant Ayers (ayers@cs.utah.edu)
*
* Modification History:
* Rev Date Initials Description of Change
* 1.0 16-Jun-2012 GEA Initial design.
*
* Standards/Formatting:
* Verilog 2001, 4 soft tab, wide column.
*
* Description:
* The top-level LCD controller. This module bridges the underlying 16x2 LCD
* hardware controller and the data memory bus. It caches 32 bytes of data which
* each correspond to a location on the LCD screen. The LCD screen is continuously
* updated with these 32 bytes as quickly as possible.
*/
module LCD(
input clock_100MHz,
input clock_Mem,
input reset,
input [2:0] address,
input [31:0] data,
input [3:0] writeEnable,
output reg ack,
output [6:0] LCD
);
 
localparam [5:0] INIT_1=1, INIT_2=2, INIT_3=3, INIT_4=4, LOC_0=5, LOC_1=6, LOC_2=7,
LOC_3=8, LOC_4=9, LOC_5=10, LOC_6=11, LOC_7=12, LOC_8=13, LOC_9=14, LOC_10=15,
LOC_11=16, LOC_12=17, LOC_13=18, LOC_14=19, LOC_15=20, LOC_16=21, LOC_17=22,
LOC_18=23, LOC_19=24, LOC_20=25, LOC_21=26, LOC_22=27, LOC_23=28, LOC_24=29,
LOC_25=30, LOC_26=31, LOC_27=32, LOC_28=33, LOC_29=34, LOC_30=35, LOC_31=36,
LINE_2=37, HOME=38;
 
 
wire clock = clock_100MHz;
reg [31:0] a0, a1, a2, a3, a4, a5, a6, a7;
reg [5:0] state;
wire bell;
 
// LCD driver signals
reg [8:0] lcd_command;
reg lcd_write;
wire lcd_ack;
 
assign bell = ~(lcd_write | lcd_ack);
 
always @(posedge clock_Mem) begin
ack <= (reset) ? 0 : (writeEnable != 4'b0000);
end
 
/* 32 bytes of LCD memory held on the FPGA fabric. The following is BIG ENDIAN */
always @(posedge clock_Mem) begin
a0[31:24] <= (reset) ? 8'h20 : (((address == 3'd0) & writeEnable[3]) ? data[31:24] : a0[31:24]);
a0[23:16] <= (reset) ? 8'h20 : (((address == 3'd0) & writeEnable[2]) ? data[23:16] : a0[23:16]);
a0[15:8] <= (reset) ? 8'h20 : (((address == 3'd0) & writeEnable[1]) ? data[15:8] : a0[15:8]);
a0[7:0] <= (reset) ? 8'h20 : (((address == 3'd0) & writeEnable[0]) ? data[7:0] : a0[7:0]);
a1[31:24] <= (reset) ? 8'h20 : (((address == 3'd1) & writeEnable[3]) ? data[31:24] : a1[31:24]);
a1[23:16] <= (reset) ? 8'h20 : (((address == 3'd1) & writeEnable[2]) ? data[23:16] : a1[23:16]);
a1[15:8] <= (reset) ? 8'h20 : (((address == 3'd1) & writeEnable[1]) ? data[15:8] : a1[15:8]);
a1[7:0] <= (reset) ? 8'h20 : (((address == 3'd1) & writeEnable[0]) ? data[7:0] : a1[7:0]);
a2[31:24] <= (reset) ? 8'h20 : (((address == 3'd2) & writeEnable[3]) ? data[31:24] : a2[31:24]);
a2[23:16] <= (reset) ? 8'h20 : (((address == 3'd2) & writeEnable[2]) ? data[23:16] : a2[23:16]);
a2[15:8] <= (reset) ? 8'h20 : (((address == 3'd2) & writeEnable[1]) ? data[15:8] : a2[15:8]);
a2[7:0] <= (reset) ? 8'h20 : (((address == 3'd2) & writeEnable[0]) ? data[7:0] : a2[7:0]);
a3[31:24] <= (reset) ? 8'h20 : (((address == 3'd3) & writeEnable[3]) ? data[31:24] : a3[31:24]);
a3[23:16] <= (reset) ? 8'h20 : (((address == 3'd3) & writeEnable[2]) ? data[23:16] : a3[23:16]);
a3[15:8] <= (reset) ? 8'h20 : (((address == 3'd3) & writeEnable[1]) ? data[15:8] : a3[15:8]);
a3[7:0] <= (reset) ? 8'h21 : (((address == 3'd3) & writeEnable[0]) ? data[7:0] : a3[7:0]);
a4[31:24] <= (reset) ? 8'h20 : (((address == 3'd4) & writeEnable[3]) ? data[31:24] : a4[31:24]);
a4[23:16] <= (reset) ? 8'h20 : (((address == 3'd4) & writeEnable[2]) ? data[23:16] : a4[23:16]);
a4[15:8] <= (reset) ? 8'h20 : (((address == 3'd4) & writeEnable[1]) ? data[15:8] : a4[15:8]);
a4[7:0] <= (reset) ? 8'h20 : (((address == 3'd4) & writeEnable[0]) ? data[7:0] : a4[7:0]);
a5[31:24] <= (reset) ? 8'h20 : (((address == 3'd5) & writeEnable[3]) ? data[31:24] : a5[31:24]);
a5[23:16] <= (reset) ? 8'h20 : (((address == 3'd5) & writeEnable[2]) ? data[23:16] : a5[23:16]);
a5[15:8] <= (reset) ? 8'h20 : (((address == 3'd5) & writeEnable[1]) ? data[15:8] : a5[15:8]);
a5[7:0] <= (reset) ? 8'h20 : (((address == 3'd5) & writeEnable[0]) ? data[7:0] : a5[7:0]);
a6[31:24] <= (reset) ? 8'h20 : (((address == 3'd6) & writeEnable[3]) ? data[31:24] : a6[31:24]);
a6[23:16] <= (reset) ? 8'h20 : (((address == 3'd6) & writeEnable[2]) ? data[23:16] : a6[23:16]);
a6[15:8] <= (reset) ? 8'h20 : (((address == 3'd6) & writeEnable[1]) ? data[15:8] : a6[15:8]);
a6[7:0] <= (reset) ? 8'h20 : (((address == 3'd6) & writeEnable[0]) ? data[7:0] : a6[7:0]);
a7[31:24] <= (reset) ? 8'h20 : (((address == 3'd7) & writeEnable[3]) ? data[31:24] : a7[31:24]);
a7[23:16] <= (reset) ? 8'h20 : (((address == 3'd7) & writeEnable[2]) ? data[23:16] : a7[23:16]);
a7[15:8] <= (reset) ? 8'h20 : (((address == 3'd7) & writeEnable[1]) ? data[15:8] : a7[15:8]);
`timescale 1ns / 1ps
/*
* File : LCD.v
* Project : University of Utah, XUM Project MIPS32 core
* Creator(s) : Grant Ayers (ayers@cs.utah.edu)
*
* Modification History:
* Rev Date Initials Description of Change
* 1.0 16-Jun-2012 GEA Initial design.
*
* Standards/Formatting:
* Verilog 2001, 4 soft tab, wide column.
*
* Description:
* The top-level LCD controller. This module bridges the underlying 16x2 LCD
* hardware controller and the data memory bus. It caches 32 bytes of data which
* each correspond to a location on the LCD screen. The LCD screen is continuously
* updated with these 32 bytes as quickly as possible.
*/
module LCD(
input clock_100MHz,
input clock_Mem,
input reset,
input [2:0] address,
input [31:0] data,
input [3:0] writeEnable,
output reg ack,
output [6:0] LCD
);
 
localparam [5:0] INIT_1=1, INIT_2=2, INIT_3=3, INIT_4=4, LOC_0=5, LOC_1=6, LOC_2=7,
LOC_3=8, LOC_4=9, LOC_5=10, LOC_6=11, LOC_7=12, LOC_8=13, LOC_9=14, LOC_10=15,
LOC_11=16, LOC_12=17, LOC_13=18, LOC_14=19, LOC_15=20, LOC_16=21, LOC_17=22,
LOC_18=23, LOC_19=24, LOC_20=25, LOC_21=26, LOC_22=27, LOC_23=28, LOC_24=29,
LOC_25=30, LOC_26=31, LOC_27=32, LOC_28=33, LOC_29=34, LOC_30=35, LOC_31=36,
LINE_2=37, HOME=38;
 
 
wire clock = clock_100MHz;
reg [31:0] a0, a1, a2, a3, a4, a5, a6, a7;
reg [5:0] state;
wire bell;
 
// LCD driver signals
reg [8:0] lcd_command;
reg lcd_write;
wire lcd_ack;
 
assign bell = ~(lcd_write | lcd_ack);
 
always @(posedge clock_Mem) begin
ack <= (reset) ? 0 : (writeEnable != 4'b0000);
end
 
/* 32 bytes of LCD memory held on the FPGA fabric. The following is BIG ENDIAN */
always @(posedge clock_Mem) begin
a0[31:24] <= (reset) ? 8'h20 : (((address == 3'd0) & writeEnable[3]) ? data[31:24] : a0[31:24]);
a0[23:16] <= (reset) ? 8'h20 : (((address == 3'd0) & writeEnable[2]) ? data[23:16] : a0[23:16]);
a0[15:8] <= (reset) ? 8'h20 : (((address == 3'd0) & writeEnable[1]) ? data[15:8] : a0[15:8]);
a0[7:0] <= (reset) ? 8'h20 : (((address == 3'd0) & writeEnable[0]) ? data[7:0] : a0[7:0]);
a1[31:24] <= (reset) ? 8'h20 : (((address == 3'd1) & writeEnable[3]) ? data[31:24] : a1[31:24]);
a1[23:16] <= (reset) ? 8'h20 : (((address == 3'd1) & writeEnable[2]) ? data[23:16] : a1[23:16]);
a1[15:8] <= (reset) ? 8'h20 : (((address == 3'd1) & writeEnable[1]) ? data[15:8] : a1[15:8]);
a1[7:0] <= (reset) ? 8'h20 : (((address == 3'd1) & writeEnable[0]) ? data[7:0] : a1[7:0]);
a2[31:24] <= (reset) ? 8'h20 : (((address == 3'd2) & writeEnable[3]) ? data[31:24] : a2[31:24]);
a2[23:16] <= (reset) ? 8'h20 : (((address == 3'd2) & writeEnable[2]) ? data[23:16] : a2[23:16]);
a2[15:8] <= (reset) ? 8'h20 : (((address == 3'd2) & writeEnable[1]) ? data[15:8] : a2[15:8]);
a2[7:0] <= (reset) ? 8'h20 : (((address == 3'd2) & writeEnable[0]) ? data[7:0] : a2[7:0]);
a3[31:24] <= (reset) ? 8'h20 : (((address == 3'd3) & writeEnable[3]) ? data[31:24] : a3[31:24]);
a3[23:16] <= (reset) ? 8'h20 : (((address == 3'd3) & writeEnable[2]) ? data[23:16] : a3[23:16]);
a3[15:8] <= (reset) ? 8'h20 : (((address == 3'd3) & writeEnable[1]) ? data[15:8] : a3[15:8]);
a3[7:0] <= (reset) ? 8'h21 : (((address == 3'd3) & writeEnable[0]) ? data[7:0] : a3[7:0]);
a4[31:24] <= (reset) ? 8'h20 : (((address == 3'd4) & writeEnable[3]) ? data[31:24] : a4[31:24]);
a4[23:16] <= (reset) ? 8'h20 : (((address == 3'd4) & writeEnable[2]) ? data[23:16] : a4[23:16]);
a4[15:8] <= (reset) ? 8'h20 : (((address == 3'd4) & writeEnable[1]) ? data[15:8] : a4[15:8]);
a4[7:0] <= (reset) ? 8'h20 : (((address == 3'd4) & writeEnable[0]) ? data[7:0] : a4[7:0]);
a5[31:24] <= (reset) ? 8'h20 : (((address == 3'd5) & writeEnable[3]) ? data[31:24] : a5[31:24]);
a5[23:16] <= (reset) ? 8'h20 : (((address == 3'd5) & writeEnable[2]) ? data[23:16] : a5[23:16]);
a5[15:8] <= (reset) ? 8'h20 : (((address == 3'd5) & writeEnable[1]) ? data[15:8] : a5[15:8]);
a5[7:0] <= (reset) ? 8'h20 : (((address == 3'd5) & writeEnable[0]) ? data[7:0] : a5[7:0]);
a6[31:24] <= (reset) ? 8'h20 : (((address == 3'd6) & writeEnable[3]) ? data[31:24] : a6[31:24]);
a6[23:16] <= (reset) ? 8'h20 : (((address == 3'd6) & writeEnable[2]) ? data[23:16] : a6[23:16]);
a6[15:8] <= (reset) ? 8'h20 : (((address == 3'd6) & writeEnable[1]) ? data[15:8] : a6[15:8]);
a6[7:0] <= (reset) ? 8'h20 : (((address == 3'd6) & writeEnable[0]) ? data[7:0] : a6[7:0]);
a7[31:24] <= (reset) ? 8'h20 : (((address == 3'd7) & writeEnable[3]) ? data[31:24] : a7[31:24]);
a7[23:16] <= (reset) ? 8'h20 : (((address == 3'd7) & writeEnable[2]) ? data[23:16] : a7[23:16]);
a7[15:8] <= (reset) ? 8'h20 : (((address == 3'd7) & writeEnable[1]) ? data[15:8] : a7[15:8]);
a7[7:0] <= (reset) ? 8'h20 : (((address == 3'd7) & writeEnable[0]) ? data[7:0] : a7[7:0]);
end
 
/* The LCD continuously writes the memory locations as fast as possible */
always @(posedge clock) begin
lcd_write <= (reset) ? 1 : ~lcd_ack;
end
 
/* LCD commands for initialization and looping through 32 locations */
always @(*) begin
case (state)
INIT_1 : lcd_command <= 9'b000101000; // 0x28 'Function Set' Not sure what this means
INIT_2 : lcd_command <= 9'b000000110; // Entry mode: set auto increment and no shifting
INIT_3 : lcd_command <= 9'b000001100; // Turn LCD on, disable cursor/blinking
INIT_4 : lcd_command <= 9'b000000001; // Clear display
LOC_0 : lcd_command <= {1'b1, a0[31:24]};
LOC_1 : lcd_command <= {1'b1, a0[23:16]};
LOC_2 : lcd_command <= {1'b1, a0[15:8]};
LOC_3 : lcd_command <= {1'b1, a0[7:0]};
LOC_4 : lcd_command <= {1'b1, a1[31:24]};
LOC_5 : lcd_command <= {1'b1, a1[23:16]};
LOC_6 : lcd_command <= {1'b1, a1[15:8]};
LOC_7 : lcd_command <= {1'b1, a1[7:0]};
LOC_8 : lcd_command <= {1'b1, a2[31:24]};
LOC_9 : lcd_command <= {1'b1, a2[23:16]};
LOC_10 : lcd_command <= {1'b1, a2[15:8]};
LOC_11 : lcd_command <= {1'b1, a2[7:0]};
LOC_12 : lcd_command <= {1'b1, a3[31:24]};
LOC_13 : lcd_command <= {1'b1, a3[23:16]};
LOC_14 : lcd_command <= {1'b1, a3[15:8]};
LOC_15 : lcd_command <= {1'b1, a3[7:0]};
LINE_2 : lcd_command <= 9'b011000000;
LOC_16 : lcd_command <= {1'b1, a4[31:24]};
LOC_17 : lcd_command <= {1'b1, a4[23:16]};
LOC_18 : lcd_command <= {1'b1, a4[15:8]};
LOC_19 : lcd_command <= {1'b1, a4[7:0]};
LOC_20 : lcd_command <= {1'b1, a5[31:24]};
LOC_21 : lcd_command <= {1'b1, a5[23:16]};
LOC_22 : lcd_command <= {1'b1, a5[15:8]};
LOC_23 : lcd_command <= {1'b1, a5[7:0]};
LOC_24 : lcd_command <= {1'b1, a6[31:24]};
LOC_25 : lcd_command <= {1'b1, a6[23:16]};
LOC_26 : lcd_command <= {1'b1, a6[15:8]};
LOC_27 : lcd_command <= {1'b1, a6[7:0]};
LOC_28 : lcd_command <= {1'b1, a7[31:24]};
LOC_29 : lcd_command <= {1'b1, a7[23:16]};
LOC_30 : lcd_command <= {1'b1, a7[15:8]};
LOC_31 : lcd_command <= {1'b1, a7[7:0]};
HOME : lcd_command <= 9'b010000000;
default : lcd_command <= 9'bx_xxxx_xxxx;
endcase
end
 
/* Main state machine */
always @(posedge clock) begin
if (reset) begin
state <= INIT_1;
end
else begin
case (state)
INIT_1 : state <= (bell) ? INIT_2 : INIT_1;
INIT_2 : state <= (bell) ? INIT_3 : INIT_2;
INIT_3 : state <= (bell) ? INIT_4 : INIT_3;
INIT_4 : state <= (bell) ? LOC_0 : INIT_4;
LOC_0 : state <= (bell) ? LOC_1 : LOC_0;
LOC_1 : state <= (bell) ? LOC_2 : LOC_1;
LOC_2 : state <= (bell) ? LOC_3 : LOC_2;
LOC_3 : state <= (bell) ? LOC_4 : LOC_3;
LOC_4 : state <= (bell) ? LOC_5 : LOC_4;
LOC_5 : state <= (bell) ? LOC_6 : LOC_5;
LOC_6 : state <= (bell) ? LOC_7 : LOC_6;
LOC_7 : state <= (bell) ? LOC_8 : LOC_7;
LOC_8 : state <= (bell) ? LOC_9 : LOC_8;
LOC_9 : state <= (bell) ? LOC_10 : LOC_9;
LOC_10 : state <= (bell) ? LOC_11 : LOC_10;
LOC_11 : state <= (bell) ? LOC_12 : LOC_11;
LOC_12 : state <= (bell) ? LOC_13 : LOC_12;
LOC_13 : state <= (bell) ? LOC_14 : LOC_13;
LOC_14 : state <= (bell) ? LOC_15 : LOC_14;
LOC_15 : state <= (bell) ? LINE_2 : LOC_15;
LINE_2 : state <= (bell) ? LOC_16 : LINE_2;
LOC_16 : state <= (bell) ? LOC_17 : LOC_16;
LOC_17 : state <= (bell) ? LOC_18 : LOC_17;
LOC_18 : state <= (bell) ? LOC_19 : LOC_18;
LOC_19 : state <= (bell) ? LOC_20 : LOC_19;
LOC_20 : state <= (bell) ? LOC_21 : LOC_20;
LOC_21 : state <= (bell) ? LOC_22 : LOC_21;
LOC_22 : state <= (bell) ? LOC_23 : LOC_22;
LOC_23 : state <= (bell) ? LOC_24 : LOC_23;
LOC_24 : state <= (bell) ? LOC_25 : LOC_24;
LOC_25 : state <= (bell) ? LOC_26 : LOC_25;
LOC_26 : state <= (bell) ? LOC_27 : LOC_26;
LOC_27 : state <= (bell) ? LOC_28 : LOC_27;
LOC_28 : state <= (bell) ? LOC_29 : LOC_28;
LOC_29 : state <= (bell) ? LOC_30 : LOC_29;
LOC_30 : state <= (bell) ? LOC_31 : LOC_30;
LOC_31 : state <= (bell) ? HOME : LOC_31;
HOME : state <= (bell) ? LOC_0 : HOME;
default : state <= 6'bxxxxxx;
endcase
end
end
 
lcd_ctrl LCD_Driver (
.clock (clock),
.reset (reset),
.command (lcd_command),
.write (lcd_write),
.ack (lcd_ack),
.LCD_D (LCD[6:3]),
.LCD_E (LCD[2]),
.LCD_RS (LCD[1]),
.LCD_RW (LCD[0])
);
 
endmodule
end
 
/* The LCD continuously writes the memory locations as fast as possible */
always @(posedge clock) begin
lcd_write <= (reset) ? 1 : ~lcd_ack;
end
 
/* LCD commands for initialization and looping through 32 locations */
always @(*) begin
case (state)
INIT_1 : lcd_command <= 9'b000101000; // 0x28 'Function Set' Not sure what this means
INIT_2 : lcd_command <= 9'b000000110; // Entry mode: set auto increment and no shifting
INIT_3 : lcd_command <= 9'b000001100; // Turn LCD on, disable cursor/blinking
INIT_4 : lcd_command <= 9'b000000001; // Clear display
LOC_0 : lcd_command <= {1'b1, a0[31:24]};
LOC_1 : lcd_command <= {1'b1, a0[23:16]};
LOC_2 : lcd_command <= {1'b1, a0[15:8]};
LOC_3 : lcd_command <= {1'b1, a0[7:0]};
LOC_4 : lcd_command <= {1'b1, a1[31:24]};
LOC_5 : lcd_command <= {1'b1, a1[23:16]};
LOC_6 : lcd_command <= {1'b1, a1[15:8]};
LOC_7 : lcd_command <= {1'b1, a1[7:0]};
LOC_8 : lcd_command <= {1'b1, a2[31:24]};
LOC_9 : lcd_command <= {1'b1, a2[23:16]};
LOC_10 : lcd_command <= {1'b1, a2[15:8]};
LOC_11 : lcd_command <= {1'b1, a2[7:0]};
LOC_12 : lcd_command <= {1'b1, a3[31:24]};
LOC_13 : lcd_command <= {1'b1, a3[23:16]};
LOC_14 : lcd_command <= {1'b1, a3[15:8]};
LOC_15 : lcd_command <= {1'b1, a3[7:0]};
LINE_2 : lcd_command <= 9'b011000000;
LOC_16 : lcd_command <= {1'b1, a4[31:24]};
LOC_17 : lcd_command <= {1'b1, a4[23:16]};
LOC_18 : lcd_command <= {1'b1, a4[15:8]};
LOC_19 : lcd_command <= {1'b1, a4[7:0]};
LOC_20 : lcd_command <= {1'b1, a5[31:24]};
LOC_21 : lcd_command <= {1'b1, a5[23:16]};
LOC_22 : lcd_command <= {1'b1, a5[15:8]};
LOC_23 : lcd_command <= {1'b1, a5[7:0]};
LOC_24 : lcd_command <= {1'b1, a6[31:24]};
LOC_25 : lcd_command <= {1'b1, a6[23:16]};
LOC_26 : lcd_command <= {1'b1, a6[15:8]};
LOC_27 : lcd_command <= {1'b1, a6[7:0]};
LOC_28 : lcd_command <= {1'b1, a7[31:24]};
LOC_29 : lcd_command <= {1'b1, a7[23:16]};
LOC_30 : lcd_command <= {1'b1, a7[15:8]};
LOC_31 : lcd_command <= {1'b1, a7[7:0]};
HOME : lcd_command <= 9'b010000000;
default : lcd_command <= 9'bx_xxxx_xxxx;
endcase
end
 
/* Main state machine */
always @(posedge clock) begin
if (reset) begin
state <= INIT_1;
end
else begin
case (state)
INIT_1 : state <= (bell) ? INIT_2 : INIT_1;
INIT_2 : state <= (bell) ? INIT_3 : INIT_2;
INIT_3 : state <= (bell) ? INIT_4 : INIT_3;
INIT_4 : state <= (bell) ? LOC_0 : INIT_4;
LOC_0 : state <= (bell) ? LOC_1 : LOC_0;
LOC_1 : state <= (bell) ? LOC_2 : LOC_1;
LOC_2 : state <= (bell) ? LOC_3 : LOC_2;
LOC_3 : state <= (bell) ? LOC_4 : LOC_3;
LOC_4 : state <= (bell) ? LOC_5 : LOC_4;
LOC_5 : state <= (bell) ? LOC_6 : LOC_5;
LOC_6 : state <= (bell) ? LOC_7 : LOC_6;
LOC_7 : state <= (bell) ? LOC_8 : LOC_7;
LOC_8 : state <= (bell) ? LOC_9 : LOC_8;
LOC_9 : state <= (bell) ? LOC_10 : LOC_9;
LOC_10 : state <= (bell) ? LOC_11 : LOC_10;
LOC_11 : state <= (bell) ? LOC_12 : LOC_11;
LOC_12 : state <= (bell) ? LOC_13 : LOC_12;
LOC_13 : state <= (bell) ? LOC_14 : LOC_13;
LOC_14 : state <= (bell) ? LOC_15 : LOC_14;
LOC_15 : state <= (bell) ? LINE_2 : LOC_15;
LINE_2 : state <= (bell) ? LOC_16 : LINE_2;
LOC_16 : state <= (bell) ? LOC_17 : LOC_16;
LOC_17 : state <= (bell) ? LOC_18 : LOC_17;
LOC_18 : state <= (bell) ? LOC_19 : LOC_18;
LOC_19 : state <= (bell) ? LOC_20 : LOC_19;
LOC_20 : state <= (bell) ? LOC_21 : LOC_20;
LOC_21 : state <= (bell) ? LOC_22 : LOC_21;
LOC_22 : state <= (bell) ? LOC_23 : LOC_22;
LOC_23 : state <= (bell) ? LOC_24 : LOC_23;
LOC_24 : state <= (bell) ? LOC_25 : LOC_24;
LOC_25 : state <= (bell) ? LOC_26 : LOC_25;
LOC_26 : state <= (bell) ? LOC_27 : LOC_26;
LOC_27 : state <= (bell) ? LOC_28 : LOC_27;
LOC_28 : state <= (bell) ? LOC_29 : LOC_28;
LOC_29 : state <= (bell) ? LOC_30 : LOC_29;
LOC_30 : state <= (bell) ? LOC_31 : LOC_30;
LOC_31 : state <= (bell) ? HOME : LOC_31;
HOME : state <= (bell) ? LOC_0 : HOME;
default : state <= 6'bxxxxxx;
endcase
end
end
 
lcd_ctrl LCD_Driver (
.clock (clock),
.reset (reset),
.command (lcd_command),
.write (lcd_write),
.ack (lcd_ack),
.LCD_D (LCD[6:3]),
.LCD_E (LCD[2]),
.LCD_RS (LCD[1]),
.LCD_RW (LCD[0])
);
 
endmodule
 
/XUPV5-LX110T_SoC/MIPS32-Pipelined-Hw/src/LCD/lcd_ctrl.v
136,3 → 136,4
end
 
endmodule
 
/XUPV5-LX110T_SoC/MIPS32-Pipelined-Hw/src/LED/LED.v
46,3 → 46,4
assign dataOut = data;
 
endmodule
 
/XUPV5-LX110T_SoC/MIPS32-Pipelined-Hw/src/Simulation/Top_Tester.v
24,48 → 24,48
 
module Top_Tester;
 
// Inputs
reg clock_100MHz;
reg reset_n;
reg [7:0] Switch;
reg UART_Rx;
// Inputs
reg clock_100MHz;
reg reset_n;
reg [7:0] Switch;
reg UART_Rx;
 
// Outputs
wire [14:0] LED;
wire [6:0] LCD;
wire UART_Tx;
wire Piezo;
// Outputs
wire [14:0] LED;
wire [6:0] LCD;
wire UART_Tx;
wire Piezo;
 
// Bidirs
wire i2c_scl;
wire i2c_sda;
// Bidirs
wire i2c_scl;
wire i2c_sda;
 
// Instantiate the Unit Under Test (UUT)
Top uut (
.clock_100MHz(clock_100MHz),
.reset_n(reset_n),
.Switch(Switch),
.LED(LED),
.LCD(LCD),
.UART_Rx(UART_Rx),
.UART_Tx(UART_Tx),
.i2c_scl(i2c_scl),
.i2c_sda(i2c_sda),
.Piezo(Piezo)
);
// Instantiate the Unit Under Test (UUT)
Top uut (
.clock_100MHz(clock_100MHz),
.reset_n(reset_n),
.Switch(Switch),
.LED(LED),
.LCD(LCD),
.UART_Rx(UART_Rx),
.UART_Tx(UART_Tx),
.i2c_scl(i2c_scl),
.i2c_sda(i2c_sda),
.Piezo(Piezo)
);
integer i;
 
initial begin
// Initialize Inputs
clock_100MHz = 0;
reset_n = 0;
Switch = 0;
UART_Rx = 0;
initial begin
// Initialize Inputs
clock_100MHz = 0;
reset_n = 0;
Switch = 0;
UART_Rx = 0;
 
// Wait 100 ns for global reset to finish
#100;
// Wait 100 ns for global reset to finish
#100;
// Add stimulus here
// Add stimulus here
for (i=0; i<900000; i=i+1) begin
reset_n = (i < 28) ? 0 : 1;
clock_100MHz = ~clock_100MHz;
73,7 → 73,7
if (i > 100000) i = i - 1;
#5;
end
end
end
endmodule
 
/XUPV5-LX110T_SoC/MIPS32-Pipelined-Hw/src/Top.v
16,9 → 16,9
* file connects all processor, memory, clocks, and I/O devices together.
* All inputs and outputs correspond to actual FPGA pins.
*/
module Top(
input clock_100MHz,
input reset_n,
module Top(
input clock_100MHz,
input reset_n,
// I/O
input [7:0] Switch,
output [14:0] LED,
28,7 → 28,7
inout i2c_scl,
inout i2c_sda,
output Piezo
);
);
// Clock signals
110,24 → 110,24
.LOCKED_OUT (PLL_Locked)
);
 
// MIPS-32 Core
Processor MIPS32 (
.clock (clock),
.reset ((reset | UART_BootResetCPU)),
// MIPS-32 Core
Processor MIPS32 (
.clock (clock),
.reset ((reset | UART_BootResetCPU)),
.Interrupts (MIPS32_Interrupts),
.NMI (MIPS32_NMI),
.DataMem_In (MIPS32_DataMem_In),
.DataMem_Ready (MIPS32_DataMem_Ready),
.DataMem_Read (MIPS32_DataMem_Read),
.DataMem_Write (MIPS32_DataMem_WE),
.DataMem_Address (MIPS32_DataMem_Address),
.DataMem_Out (MIPS32_DataMem_Out),
.InstMem_In (MIPS32_InstMem_In),
.InstMem_Address (MIPS32_InstMem_Address),
.InstMem_Ready (BRAM_ReadyA),
.InstMem_Read (MIPS32_InstMem_Read),
.DataMem_In (MIPS32_DataMem_In),
.DataMem_Ready (MIPS32_DataMem_Ready),
.DataMem_Read (MIPS32_DataMem_Read),
.DataMem_Write (MIPS32_DataMem_WE),
.DataMem_Address (MIPS32_DataMem_Address),
.DataMem_Out (MIPS32_DataMem_Out),
.InstMem_In (MIPS32_InstMem_In),
.InstMem_Address (MIPS32_InstMem_Address),
.InstMem_Ready (BRAM_ReadyA),
.InstMem_Read (MIPS32_InstMem_Read),
.IP (MIPS32_IP)
);
);
 
// On-Chip Block RAM
BRAM_592KB_Wrapper Memory (
304,3 → 304,4
assign Switches_RE = (MIPS32_DataMem_Address[29:26] == 4'b1101) ? MIPS32_DataMem_Read : 0;
endmodule
 
/XUPV5-LX110T_SoC/MIPS32-Pipelined-Hw/src/Common/Mux2.v
15,11 → 15,12
* A 2-input Mux of variable width, defaulting to 32-bit width.
*/
module Mux2 #(parameter WIDTH = 32)(
input sel,
input [(WIDTH-1):0] in0, in1,
output [(WIDTH-1):0] out
);
input sel,
input [(WIDTH-1):0] in0, in1,
output [(WIDTH-1):0] out
);
 
assign out = (sel) ? in1 : in0;
assign out = (sel) ? in1 : in0;
 
endmodule
 
/XUPV5-LX110T_SoC/MIPS32-Pipelined-Hw/src/Common/Decoder_2to4.v
1,4 → 1,4
`timescale 1ns / 1ps
`timescale 1ns / 1ps
/*
* File : Decoder_2to4.v
* Project : University of Utah, XUM Project MIPS32 core
12,27 → 12,28
* Verilog 2001, 4 soft tab, wide column.
*
* Description:
* A simple 2-to-4 line single bit decoder. Accepts a two bit number
* and sets one of four outputs high based on that number.
*
* Mapping:
* 00 -> 0001
* 01 -> 0010
* 10 -> 0100
* A simple 2-to-4 line single bit decoder. Accepts a two bit number
* and sets one of four outputs high based on that number.
*
* Mapping:
* 00 -> 0001
* 01 -> 0010
* 10 -> 0100
* 11 -> 1000
*/
module Decoder_2to4(
input [1:0] A,
output reg [3:0] B
);
 
always @(A) begin
case (A)
2'd0 : B <= 4'b0001;
2'd1 : B <= 4'b0010;
2'd2 : B <= 4'b0100;
2'd3 : B <= 4'b1000;
endcase
end
 
endmodule
*/
module Decoder_2to4(
input [1:0] A,
output reg [3:0] B
);
 
always @(A) begin
case (A)
2'd0 : B <= 4'b0001;
2'd1 : B <= 4'b0010;
2'd2 : B <= 4'b0100;
2'd3 : B <= 4'b1000;
endcase
end
 
endmodule
 
/XUPV5-LX110T_SoC/MIPS32-Pipelined-Hw/src/Common/Mux4.v
15,18 → 15,19
* A 4-input Mux of variable width, defaulting to 32-bit width.
*/
module Mux4 #(parameter WIDTH = 32)(
input [1:0] sel,
input [(WIDTH-1):0] in0, in1, in2, in3,
output reg [(WIDTH-1):0] out
);
input [1:0] sel,
input [(WIDTH-1):0] in0, in1, in2, in3,
output reg [(WIDTH-1):0] out
);
 
always @(*) begin
case (sel)
2'b00 : out <= in0;
2'b01 : out <= in1;
2'b10 : out <= in2;
2'b11 : out <= in3;
endcase
end
always @(*) begin
case (sel)
2'b00 : out <= in0;
2'b01 : out <= in1;
2'b10 : out <= in2;
2'b11 : out <= in3;
endcase
end
 
endmodule
 
/XUPV5-LX110T_SoC/MIPS32-Pipelined-Hw/src/Common/SRAM.v
1,21 → 1,21
`timescale 1ns / 1ps
/*
* File : SRAM.v
* Project : University of Utah, XUM Project MIPS32 core
* Creator(s) : Grant Ayers (ayers@cs.utah.edu)
*
* Modification History:
* Rev Date Initials Description of Change
* 1.0 4-Apr-2010 GEA Initial design.
*
* Standards/Formatting:
* Verilog 2001, 4 soft tab, wide column.
*
* Description:
* A simple memory of varying width and depth. Reads are asynchronous,
/*
* File : SRAM.v
* Project : University of Utah, XUM Project MIPS32 core
* Creator(s) : Grant Ayers (ayers@cs.utah.edu)
*
* Modification History:
* Rev Date Initials Description of Change
* 1.0 4-Apr-2010 GEA Initial design.
*
* Standards/Formatting:
* Verilog 2001, 4 soft tab, wide column.
*
* Description:
* A simple memory of varying width and depth. Reads are asynchronous,
* writes are synchronous. Defaults to 8-bit width and 8-bit depth for
* a total of 8-bit * 256 entry or 256 bytes of storage.
*/
* a total of 8-bit * 256 entry or 256 bytes of storage.
*/
module SRAM(clock, wEn, rAddr, wAddr, dIn, dOut);
parameter DATA_WIDTH = 8;
parameter ADDR_WIDTH = 8;
35,3 → 35,4
end
 
endmodule
 
/XUPV5-LX110T_SoC/MIPS32-Pipelined-Hw/src/Common/FIFO.v
1,30 → 1,30
`timescale 1ns / 1ps
/*
* File : FIFO.v
* Project : University of Utah, XUM Project MIPS32 core
* Creator(s) : Grant Ayers (ayers@cs.utah.edu)
*
* Modification History:
* Rev Date Initials Description of Change
* 1.0 4-Apr-2010 GEA Initial design.
*
* Standards/Formatting:
* Verilog 2001, 4 soft tab, wide column.
*
* Description:
* A synchronous FIFO of variable data width and depth. 'enQ' is ignored when
* the FIFO is full and 'deQ' is ignored when the FIFO is empty. If 'enQ' and
* 'deQ' are asserted simultaneously, the FIFO is unchanged and the output data
* is the same as the input data.
*
* This FIFO is "First word fall-through" meaning data can be read without
* asserting 'deQ' by merely supplying an address. However, when 'deQ' is
* asserted, the data is "removed" from the FIFO and one location is freed.
* If the FIFO is empty and 'enQ' and 'deQ' are not asserted simultaneously,
* the output data will be 0s.
*
* Variation:
* - None. This is the basic FIFO module.
`timescale 1ns / 1ps
/*
* File : FIFO.v
* Project : University of Utah, XUM Project MIPS32 core
* Creator(s) : Grant Ayers (ayers@cs.utah.edu)
*
* Modification History:
* Rev Date Initials Description of Change
* 1.0 4-Apr-2010 GEA Initial design.
*
* Standards/Formatting:
* Verilog 2001, 4 soft tab, wide column.
*
* Description:
* A synchronous FIFO of variable data width and depth. 'enQ' is ignored when
* the FIFO is full and 'deQ' is ignored when the FIFO is empty. If 'enQ' and
* 'deQ' are asserted simultaneously, the FIFO is unchanged and the output data
* is the same as the input data.
*
* This FIFO is "First word fall-through" meaning data can be read without
* asserting 'deQ' by merely supplying an address. However, when 'deQ' is
* asserted, the data is "removed" from the FIFO and one location is freed.
* If the FIFO is empty and 'enQ' and 'deQ' are not asserted simultaneously,
* the output data will be 0s.
*
* Variation:
* - None. This is the basic FIFO module.
*/
module FIFO(clock, reset, clear, enQ, deQ, data_in, data_out, empty, full);
parameter DATA_WIDTH = 8;
36,7 → 36,7
input deQ;
input [(DATA_WIDTH-1):0] data_in;
output [(DATA_WIDTH-1):0] data_out;
output empty;
output empty;
output full;
 
reg [(ADDR_WIDTH-1):0] enQ_ptr, deQ_ptr; // Addresses for reading from and writing to internal memory
77,3 → 77,4
);
endmodule
 
/XUPV5-LX110T_SoC/MIPS32-Pipelined-Hw/src/Common/FIFO_Clear.v
1,30 → 1,30
`timescale 1ns / 1ps
/*
* File : FIFO_Clear.v
* Project : University of Utah, XUM Project MIPS32 core
* Creator(s) : Grant Ayers (ayers@cs.utah.edu)
*
* Modification History:
* Rev Date Initials Description of Change
* 1.0 4-Apr-2010 GEA Initial design.
*
* Standards/Formatting:
* Verilog 2001, 4 soft tab, wide column.
*
* Description:
* A synchronous FIFO of variable data width and depth. 'enQ' is ignored when
* the FIFO is full and 'deQ' is ignored when the FIFO is empty. If 'enQ' and
* 'deQ' are asserted simultaneously, the FIFO is unchanged and the output data
* is the same as the input data.
*
* This FIFO is "First word fall-through" meaning data can be read without
* asserting 'deQ' by merely supplying an address. However, when 'deQ' is
* asserted, the data is "removed" from the FIFO and one location is freed.
* If the FIFO is empty and 'enQ' and 'deQ' are not asserted simultaneously,
* the output data will be 0s.
*
* Variation:
* - Input 'clear' empties the FIFO exactly like 'reset' does.
`timescale 1ns / 1ps
/*
* File : FIFO_Clear.v
* Project : University of Utah, XUM Project MIPS32 core
* Creator(s) : Grant Ayers (ayers@cs.utah.edu)
*
* Modification History:
* Rev Date Initials Description of Change
* 1.0 4-Apr-2010 GEA Initial design.
*
* Standards/Formatting:
* Verilog 2001, 4 soft tab, wide column.
*
* Description:
* A synchronous FIFO of variable data width and depth. 'enQ' is ignored when
* the FIFO is full and 'deQ' is ignored when the FIFO is empty. If 'enQ' and
* 'deQ' are asserted simultaneously, the FIFO is unchanged and the output data
* is the same as the input data.
*
* This FIFO is "First word fall-through" meaning data can be read without
* asserting 'deQ' by merely supplying an address. However, when 'deQ' is
* asserted, the data is "removed" from the FIFO and one location is freed.
* If the FIFO is empty and 'enQ' and 'deQ' are not asserted simultaneously,
* the output data will be 0s.
*
* Variation:
* - Input 'clear' empties the FIFO exactly like 'reset' does.
*/
module FIFO_Clear(clock, reset, clear, enQ, deQ, data_in, data_out, empty, full);
parameter DATA_WIDTH = 8;
31,13 → 31,13
parameter ADDR_WIDTH = 8;
parameter RAM_DEPTH = 1 << ADDR_WIDTH;
input clock;
input reset;
input reset;
input clear;
input enQ;
input deQ;
input [(DATA_WIDTH-1):0] data_in;
output [(DATA_WIDTH-1):0] data_out;
output empty;
output empty;
output full;
 
reg [(ADDR_WIDTH-1):0] enQ_ptr, deQ_ptr; // Addresses for reading from and writing to internal memory
78,3 → 78,4
);
endmodule
 
/XUPV5-LX110T_SoC/MIPS32-Pipelined-Hw/src/Common/FIFO_NoFull_Count.v
1,81 → 1,82
`timescale 1ns / 1ps
/*
* File : FIFO_NoFull_Count.v
* Project : University of Utah, XUM Project MIPS32 core
* Creator(s) : Grant Ayers (ayers@cs.utah.edu)
*
* Modification History:
* Rev Date Initials Description of Change
* 1.0 24-May-2010 GEA Initial design.
*
* Standards/Formatting:
* Verilog 2001, 4 soft tab, wide column.
*
* Description:
* A synchronous FIFO of variable data width and depth. 'enQ' is ignored when
* the FIFO is full and 'deQ' is ignored when the FIFO is empty. If 'enQ' and
* 'deQ' are asserted simultaneously, the FIFO is unchanged and the output data
* is the same as the input data.
*
* This FIFO is "First word fall-through" meaning data can be read without
* asserting 'deQ' by merely supplying an address. However, when 'deQ' is
* asserted, the data is "removed" from the FIFO and one location is freed.
* If the FIFO is empty and 'enQ' and 'deQ' are not asserted simultaneously,
* the output data will be 0s.
*
* Variation:
* - There is no output to indicate the FIFO is full.
* - Output 'count' indicates how many elements are in the FIFO, from 0 to 256
* (for 8-bit ADDR_WIDTH).
*/
module FIFO_NoFull_Count(clock, reset, enQ, deQ, data_in, data_out, empty, count);
parameter DATA_WIDTH = 8;
parameter ADDR_WIDTH = 8;
parameter RAM_DEPTH = 1 << ADDR_WIDTH;
input clock;
input reset;
input enQ;
input deQ;
input [(DATA_WIDTH-1):0] data_in;
output [(DATA_WIDTH-1):0] data_out;
output empty;
output reg [(ADDR_WIDTH):0] count; // How many elements are in the FIFO (0->256)
 
reg [(ADDR_WIDTH-1):0] enQ_ptr, deQ_ptr; // Addresses for reading from and writing to internal memory
 
assign empty = (count == 0);
wire full = (count == (1 << ADDR_WIDTH));
 
wire [(DATA_WIDTH-1):0] w_data_out;
assign data_out = (empty) ? ((enQ & deQ) ? data_in : 0) : w_data_out;
 
wire w_enQ = (full) ? 0 : enQ; // Mask 'enQ' when the FIFO is full
wire w_deQ = (empty) ? 0 : deQ; // Mask 'deQ' when the FIFO is empty
always @(posedge clock) begin
if (reset) begin
enQ_ptr <= 0;
deQ_ptr <= 0;
count <= 0;
end
else begin
enQ_ptr <= (w_enQ) ? enQ_ptr +1 : enQ_ptr;
deQ_ptr <= (w_deQ) ? deQ_ptr +1 : deQ_ptr;
count <= (w_enQ ~^ w_deQ) ? count : ((w_enQ) ? count +1 : count -1);
end
end
 
SRAM #(
.DATA_WIDTH (DATA_WIDTH),
.ADDR_WIDTH (ADDR_WIDTH),
.RAM_DEPTH (RAM_DEPTH))
ram(
.clock (clock),
.wEn (w_enQ),
.rAddr (deQ_ptr),
.wAddr (enQ_ptr),
.dIn (data_in),
.dOut (w_data_out)
);
endmodule
`timescale 1ns / 1ps
/*
* File : FIFO_NoFull_Count.v
* Project : University of Utah, XUM Project MIPS32 core
* Creator(s) : Grant Ayers (ayers@cs.utah.edu)
*
* Modification History:
* Rev Date Initials Description of Change
* 1.0 24-May-2010 GEA Initial design.
*
* Standards/Formatting:
* Verilog 2001, 4 soft tab, wide column.
*
* Description:
* A synchronous FIFO of variable data width and depth. 'enQ' is ignored when
* the FIFO is full and 'deQ' is ignored when the FIFO is empty. If 'enQ' and
* 'deQ' are asserted simultaneously, the FIFO is unchanged and the output data
* is the same as the input data.
*
* This FIFO is "First word fall-through" meaning data can be read without
* asserting 'deQ' by merely supplying an address. However, when 'deQ' is
* asserted, the data is "removed" from the FIFO and one location is freed.
* If the FIFO is empty and 'enQ' and 'deQ' are not asserted simultaneously,
* the output data will be 0s.
*
* Variation:
* - There is no output to indicate the FIFO is full.
* - Output 'count' indicates how many elements are in the FIFO, from 0 to 256
* (for 8-bit ADDR_WIDTH).
*/
module FIFO_NoFull_Count(clock, reset, enQ, deQ, data_in, data_out, empty, count);
parameter DATA_WIDTH = 8;
parameter ADDR_WIDTH = 8;
parameter RAM_DEPTH = 1 << ADDR_WIDTH;
input clock;
input reset;
input enQ;
input deQ;
input [(DATA_WIDTH-1):0] data_in;
output [(DATA_WIDTH-1):0] data_out;
output empty;
output reg [(ADDR_WIDTH):0] count; // How many elements are in the FIFO (0->256)
 
reg [(ADDR_WIDTH-1):0] enQ_ptr, deQ_ptr; // Addresses for reading from and writing to internal memory
 
assign empty = (count == 0);
wire full = (count == (1 << ADDR_WIDTH));
 
wire [(DATA_WIDTH-1):0] w_data_out;
assign data_out = (empty) ? ((enQ & deQ) ? data_in : 0) : w_data_out;
 
wire w_enQ = (full) ? 0 : enQ; // Mask 'enQ' when the FIFO is full
wire w_deQ = (empty) ? 0 : deQ; // Mask 'deQ' when the FIFO is empty
always @(posedge clock) begin
if (reset) begin
enQ_ptr <= 0;
deQ_ptr <= 0;
count <= 0;
end
else begin
enQ_ptr <= (w_enQ) ? enQ_ptr +1 : enQ_ptr;
deQ_ptr <= (w_deQ) ? deQ_ptr +1 : deQ_ptr;
count <= (w_enQ ~^ w_deQ) ? count : ((w_enQ) ? count +1 : count -1);
end
end
 
SRAM #(
.DATA_WIDTH (DATA_WIDTH),
.ADDR_WIDTH (ADDR_WIDTH),
.RAM_DEPTH (RAM_DEPTH))
ram(
.clock (clock),
.wEn (w_enQ),
.rAddr (deQ_ptr),
.wAddr (enQ_ptr),
.dIn (data_in),
.dOut (w_data_out)
);
endmodule
 
/XUPV5-LX110T_SoC/MIPS32-Pipelined-Hw/src/Switches/Switches.v
37,5 → 37,5
.switch_out (Switch_out)
);
 
endmodule
 
endmodule
/XUPV5-LX110T_SoC/MIPS32-Pipelined-Hw/src/UART/uart_bootloader_v1.v
1,4 → 1,4
`timescale 1ns / 1ps
`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company:
// Engineer: Grant Ayers (ayers@cs.utah.edu)
180,3 → 180,4
);
endmodule
 
/XUPV5-LX110T_SoC/MIPS32-Pipelined-Hw/src/UART/uart_rx.v
93,3 → 93,4
assign data_ready = (uart_tick_16x & next_bit & (state==STOP));
endmodule
 
/XUPV5-LX110T_SoC/MIPS32-Pipelined-Hw/src/UART/uart_clock.v
54,3 → 54,4
assign uart_tick = (uart_tick_16x==1'b1 && (uart_16x_count == 4'b1111));
endmodule
 
/XUPV5-LX110T_SoC/MIPS32-Pipelined-Hw/src/I2C/I2C_Phy.v
234,3 → 234,4
);
 
endmodule
 
/XUPV5-LX110T_SoC/MIPS32-Pipelined-Hw/src/I2C/I2C_Clock.v
1,20 → 1,20
`timescale 1ns / 1ps
/*
* File : I2C_Clock.v
* Project : University of Utah, XUM Project MIPS32 core
* Creator(s) : Grant Ayers (ayers@cs.utah.edu)
*
* Modification History:
* Rev Date Initials Description of Change
* 1.0 21-Jun-2012 GEA Initial design.
*
* Standards/Formatting:
* Verilog 2001, 4 soft tab, wide column.
*
* Description:
* Generates a 100 kHz clock signal and an indicator which pulses
* in the middle of the high and low periods of the clock.
*/
/*
* File : I2C_Clock.v
* Project : University of Utah, XUM Project MIPS32 core
* Creator(s) : Grant Ayers (ayers@cs.utah.edu)
*
* Modification History:
* Rev Date Initials Description of Change
* 1.0 21-Jun-2012 GEA Initial design.
*
* Standards/Formatting:
* Verilog 2001, 4 soft tab, wide column.
*
* Description:
* Generates a 100 kHz clock signal and an indicator which pulses
* in the middle of the high and low periods of the clock.
*/
module I2C_Clock(
input clock, // 100 MHz
input reset,
26,7 → 26,7
always @(posedge clock) begin
//count_4x <= (reset) ? 8'h00 : (scl) ? count_4x + 1 : count_4x;
//count_4x <= (reset) ? 8'h00 : (scl) ? count_4x + 1 : count_4x;
count_4x <= (reset) ? 8'h00 : count_4x + 1; // XXX SIMULATION ONLY
end
 
46,9 → 46,10
2'd3 : state <= (tick_4x) ? 2'd0 : 2'd3;
endcase
end
end
end
 
assign scl = ((state == 2'd0) || (state == 2'd1));
assign scl_tick_90 = tick_4x & ((state == 2'd0) || (state == 2'd2));
 
endmodule
 
/XUPV5-LX110T_SoC/MIPS32-Pipelined-Hw/src/MIPS32/IDEX_Stage.v
114,7 → 114,7
reg [16:0] EX_SignExtImm_pre;
reg EX_RegDst;
assign EX_LinkRegDst = (EX_Link) ? 2'b10 : ((EX_RegDst) ? 2'b01 : 2'b00);
assign EX_LinkRegDst = (EX_Link) ? 2'b10 : ((EX_RegDst) ? 2'b01 : 2'b00);
assign EX_Rd = EX_SignExtImm[15:11];
assign EX_Shamt = EX_SignExtImm[10:6];
assign EX_SignExtImm = (EX_SignExtImm_pre[16]) ? {15'h7fff, EX_SignExtImm_pre[16:0]} : {15'h0000, EX_SignExtImm_pre[16:0]};
156,3 → 156,4
end
 
endmodule
 
/XUPV5-LX110T_SoC/MIPS32-Pipelined-Hw/src/MIPS32/Processor.v
18,24 → 18,24
* hardware design diagram. It contains very little logic itself.
*/
module Processor(
input clock,
input reset,
input clock,
input reset,
input [4:0] Interrupts, // 5 general-purpose hardware interrupts
input NMI, // Non-maskable interrupt
// Data Memory Interface
input [31:0] DataMem_In,
input DataMem_Ready,
output DataMem_Read,
// Data Memory Interface
input [31:0] DataMem_In,
input DataMem_Ready,
output DataMem_Read,
output [3:0] DataMem_Write, // 4-bit Write, one for each byte in word.
output [29:0] DataMem_Address, // Addresses are words, not bytes.
output [31:0] DataMem_Out,
// Instruction Memory Interface
input [31:0] InstMem_In,
output [29:0] InstMem_Address, // Addresses are words, not bytes.
input InstMem_Ready,
output InstMem_Read,
output [29:0] DataMem_Address, // Addresses are words, not bytes.
output [31:0] DataMem_Out,
// Instruction Memory Interface
input [31:0] InstMem_In,
output [29:0] InstMem_Address, // Addresses are words, not bytes.
input InstMem_Ready,
output InstMem_Read,
output [7:0] IP // Pending interrupts (diagnostic)
);
);
 
`include "MIPS_Parameters.v"
 
674,3 → 674,4
);
 
endmodule
 
/XUPV5-LX110T_SoC/MIPS32-Pipelined-Hw/src/MIPS32/Control.v
1,4 → 1,4
`timescale 1ns / 1ps
`timescale 1ns / 1ps
/*
* File : Control.v
* Project : University of Utah, XUM Project MIPS32 core
19,26 → 19,26
* the effective operation of the processor through each pipeline stage.
*/
module Control(
input ID_Stall,
input [5:0] OpCode,
input [5:0] Funct,
input [4:0] Rs, // used to differentiate mfc0 and mtc0
input [4:0] Rt, // used to differentiate bgez,bgezal,bltz,bltzal,teqi,tgei,tgeiu,tlti,tltiu,tnei
input Cmp_EQ,
input Cmp_GZ,
input Cmp_GEZ,
input Cmp_LZ,
input Cmp_LEZ,
//------------
output IF_Flush,
output reg [7:0] DP_Hazards,
output [1:0] PCSrc,
output SignExtend,
output Link,
output Movn,
input ID_Stall,
input [5:0] OpCode,
input [5:0] Funct,
input [4:0] Rs, // used to differentiate mfc0 and mtc0
input [4:0] Rt, // used to differentiate bgez,bgezal,bltz,bltzal,teqi,tgei,tgeiu,tlti,tltiu,tnei
input Cmp_EQ,
input Cmp_GZ,
input Cmp_GEZ,
input Cmp_LZ,
input Cmp_LEZ,
//------------
output IF_Flush,
output reg [7:0] DP_Hazards,
output [1:0] PCSrc,
output SignExtend,
output Link,
output Movn,
output Movz,
output Mfc0,
output Mtc0,
output Mfc0,
output Mtc0,
output CP1,
output CP2,
output CP3,
51,28 → 51,28
output ID_CanErr,
output EX_CanErr,
output M_CanErr,
output NextIsDelay,
output RegDst,
output ALUSrcImm,
output reg [4:0] ALUOp,
output NextIsDelay,
output RegDst,
output ALUSrcImm,
output reg [4:0] ALUOp,
output LLSC,
output MemWrite,
output MemRead,
output MemByte,
output MemHalf,
output MemSignExtend,
output MemWrite,
output MemRead,
output MemByte,
output MemHalf,
output MemSignExtend,
output Left,
output Right,
output RegWrite,
output MemtoReg
);
`include "MIPS_Parameters.v"
output RegWrite,
output MemtoReg
);
`include "MIPS_Parameters.v"
 
wire Movc;
wire Branch, Branch_EQ, Branch_GTZ, Branch_LEZ, Branch_NEQ, Branch_GEZ, Branch_LTZ;
wire Movc;
wire Branch, Branch_EQ, Branch_GTZ, Branch_LEZ, Branch_NEQ, Branch_GEZ, Branch_LTZ;
wire Unaligned_Mem;
reg [15:0] Datapath;
assign PCSrc[0] = Datapath[14];
assign Link = Datapath[13];
94,356 → 94,356
assign ID_CanErr = DP_Exceptions[2];
assign EX_CanErr = DP_Exceptions[1];
assign M_CanErr = DP_Exceptions[0];
// Set the main datapath control signals based on the Op Code
always @(*) begin
if (ID_Stall)
Datapath <= DP_None;
else begin
case (OpCode)
// R-Type
Op_Type_R :
begin
case (Funct)
Funct_Add : Datapath <= DP_Add;
Funct_Addu : Datapath <= DP_Addu;
Funct_And : Datapath <= DP_And;
Funct_Break : Datapath <= DP_Break;
Funct_Div : Datapath <= DP_Div;
Funct_Divu : Datapath <= DP_Divu;
Funct_Jalr : Datapath <= DP_Jalr;
Funct_Jr : Datapath <= DP_Jr;
Funct_Mfhi : Datapath <= DP_Mfhi;
Funct_Mflo : Datapath <= DP_Mflo;
Funct_Movn : Datapath <= DP_Movn;
Funct_Movz : Datapath <= DP_Movz;
Funct_Mthi : Datapath <= DP_Mthi;
Funct_Mtlo : Datapath <= DP_Mtlo;
Funct_Mult : Datapath <= DP_Mult;
Funct_Multu : Datapath <= DP_Multu;
Funct_Nor : Datapath <= DP_Nor;
Funct_Or : Datapath <= DP_Or;
Funct_Sll : Datapath <= DP_Sll;
Funct_Sllv : Datapath <= DP_Sllv;
Funct_Slt : Datapath <= DP_Slt;
Funct_Sltu : Datapath <= DP_Sltu;
Funct_Sra : Datapath <= DP_Sra;
Funct_Srav : Datapath <= DP_Srav;
Funct_Srl : Datapath <= DP_Srl;
Funct_Srlv : Datapath <= DP_Srlv;
Funct_Sub : Datapath <= DP_Sub;
Funct_Subu : Datapath <= DP_Subu;
Funct_Syscall : Datapath <= DP_Syscall;
Funct_Teq : Datapath <= DP_Teq;
Funct_Tge : Datapath <= DP_Tge;
Funct_Tgeu : Datapath <= DP_Tgeu;
Funct_Tlt : Datapath <= DP_Tlt;
Funct_Tltu : Datapath <= DP_Tltu;
Funct_Tne : Datapath <= DP_Tne;
Funct_Xor : Datapath <= DP_Xor;
default : Datapath <= DP_None;
endcase
end
// R2-Type
Op_Type_R2 :
begin
case (Funct)
Funct_Clo : Datapath <= DP_Clo;
Funct_Clz : Datapath <= DP_Clz;
Funct_Madd : Datapath <= DP_Madd;
Funct_Maddu : Datapath <= DP_Maddu;
Funct_Msub : Datapath <= DP_Msub;
Funct_Msubu : Datapath <= DP_Msubu;
Funct_Mul : Datapath <= DP_Mul;
default : Datapath <= DP_None;
endcase
end
// I-Type
Op_Addi : Datapath <= DP_Addi;
Op_Addiu : Datapath <= DP_Addiu;
Op_Andi : Datapath <= DP_Andi;
Op_Ori : Datapath <= DP_Ori;
Op_Pref : Datapath <= DP_Pref;
Op_Slti : Datapath <= DP_Slti;
Op_Sltiu : Datapath <= DP_Sltiu;
Op_Xori : Datapath <= DP_Xori;
// Jumps (using immediates)
Op_J : Datapath <= DP_J;
Op_Jal : Datapath <= DP_Jal;
// Branches and Traps
Op_Type_BI :
begin
case (Rt)
OpRt_Bgez : Datapath <= DP_Bgez;
OpRt_Bgezal : Datapath <= DP_Bgezal;
OpRt_Bltz : Datapath <= DP_Bltz;
OpRt_Bltzal : Datapath <= DP_Bltzal;
OpRt_Teqi : Datapath <= DP_Teqi;
OpRt_Tgei : Datapath <= DP_Tgei;
OpRt_Tgeiu : Datapath <= DP_Tgeiu;
OpRt_Tlti : Datapath <= DP_Tlti;
OpRt_Tltiu : Datapath <= DP_Tltiu;
OpRt_Tnei : Datapath <= DP_Tnei;
default : Datapath <= DP_None;
endcase
end
Op_Beq : Datapath <= DP_Beq;
Op_Bgtz : Datapath <= DP_Bgtz;
Op_Blez : Datapath <= DP_Blez;
Op_Bne : Datapath <= DP_Bne;
// Coprocessor 0
Op_Type_CP0 :
begin
case (Rs)
OpRs_MF : Datapath <= DP_Mfc0;
OpRs_MT : Datapath <= DP_Mtc0;
// Set the main datapath control signals based on the Op Code
always @(*) begin
if (ID_Stall)
Datapath <= DP_None;
else begin
case (OpCode)
// R-Type
Op_Type_R :
begin
case (Funct)
Funct_Add : Datapath <= DP_Add;
Funct_Addu : Datapath <= DP_Addu;
Funct_And : Datapath <= DP_And;
Funct_Break : Datapath <= DP_Break;
Funct_Div : Datapath <= DP_Div;
Funct_Divu : Datapath <= DP_Divu;
Funct_Jalr : Datapath <= DP_Jalr;
Funct_Jr : Datapath <= DP_Jr;
Funct_Mfhi : Datapath <= DP_Mfhi;
Funct_Mflo : Datapath <= DP_Mflo;
Funct_Movn : Datapath <= DP_Movn;
Funct_Movz : Datapath <= DP_Movz;
Funct_Mthi : Datapath <= DP_Mthi;
Funct_Mtlo : Datapath <= DP_Mtlo;
Funct_Mult : Datapath <= DP_Mult;
Funct_Multu : Datapath <= DP_Multu;
Funct_Nor : Datapath <= DP_Nor;
Funct_Or : Datapath <= DP_Or;
Funct_Sll : Datapath <= DP_Sll;
Funct_Sllv : Datapath <= DP_Sllv;
Funct_Slt : Datapath <= DP_Slt;
Funct_Sltu : Datapath <= DP_Sltu;
Funct_Sra : Datapath <= DP_Sra;
Funct_Srav : Datapath <= DP_Srav;
Funct_Srl : Datapath <= DP_Srl;
Funct_Srlv : Datapath <= DP_Srlv;
Funct_Sub : Datapath <= DP_Sub;
Funct_Subu : Datapath <= DP_Subu;
Funct_Syscall : Datapath <= DP_Syscall;
Funct_Teq : Datapath <= DP_Teq;
Funct_Tge : Datapath <= DP_Tge;
Funct_Tgeu : Datapath <= DP_Tgeu;
Funct_Tlt : Datapath <= DP_Tlt;
Funct_Tltu : Datapath <= DP_Tltu;
Funct_Tne : Datapath <= DP_Tne;
Funct_Xor : Datapath <= DP_Xor;
default : Datapath <= DP_None;
endcase
end
// R2-Type
Op_Type_R2 :
begin
case (Funct)
Funct_Clo : Datapath <= DP_Clo;
Funct_Clz : Datapath <= DP_Clz;
Funct_Madd : Datapath <= DP_Madd;
Funct_Maddu : Datapath <= DP_Maddu;
Funct_Msub : Datapath <= DP_Msub;
Funct_Msubu : Datapath <= DP_Msubu;
Funct_Mul : Datapath <= DP_Mul;
default : Datapath <= DP_None;
endcase
end
// I-Type
Op_Addi : Datapath <= DP_Addi;
Op_Addiu : Datapath <= DP_Addiu;
Op_Andi : Datapath <= DP_Andi;
Op_Ori : Datapath <= DP_Ori;
Op_Pref : Datapath <= DP_Pref;
Op_Slti : Datapath <= DP_Slti;
Op_Sltiu : Datapath <= DP_Sltiu;
Op_Xori : Datapath <= DP_Xori;
// Jumps (using immediates)
Op_J : Datapath <= DP_J;
Op_Jal : Datapath <= DP_Jal;
// Branches and Traps
Op_Type_BI :
begin
case (Rt)
OpRt_Bgez : Datapath <= DP_Bgez;
OpRt_Bgezal : Datapath <= DP_Bgezal;
OpRt_Bltz : Datapath <= DP_Bltz;
OpRt_Bltzal : Datapath <= DP_Bltzal;
OpRt_Teqi : Datapath <= DP_Teqi;
OpRt_Tgei : Datapath <= DP_Tgei;
OpRt_Tgeiu : Datapath <= DP_Tgeiu;
OpRt_Tlti : Datapath <= DP_Tlti;
OpRt_Tltiu : Datapath <= DP_Tltiu;
OpRt_Tnei : Datapath <= DP_Tnei;
default : Datapath <= DP_None;
endcase
end
Op_Beq : Datapath <= DP_Beq;
Op_Bgtz : Datapath <= DP_Bgtz;
Op_Blez : Datapath <= DP_Blez;
Op_Bne : Datapath <= DP_Bne;
// Coprocessor 0
Op_Type_CP0 :
begin
case (Rs)
OpRs_MF : Datapath <= DP_Mfc0;
OpRs_MT : Datapath <= DP_Mtc0;
OpRs_ERET : Datapath <= (Funct == Funct_ERET) ? DP_Eret : DP_None;
default : Datapath <= DP_None;
endcase
end
// Memory
Op_Lb : Datapath <= DP_Lb;
Op_Lbu : Datapath <= DP_Lbu;
Op_Lh : Datapath <= DP_Lh;
Op_Lhu : Datapath <= DP_Lhu;
Op_Ll : Datapath <= DP_Ll;
Op_Lui : Datapath <= DP_Lui;
Op_Lw : Datapath <= DP_Lw;
Op_Lwl : Datapath <= DP_Lwl;
Op_Lwr : Datapath <= DP_Lwr;
Op_Sb : Datapath <= DP_Sb;
Op_Sc : Datapath <= DP_Sc;
Op_Sh : Datapath <= DP_Sh;
Op_Sw : Datapath <= DP_Sw;
Op_Swl : Datapath <= DP_Swl;
Op_Swr : Datapath <= DP_Swr;
default : Datapath <= DP_None;
endcase
end
end
default : Datapath <= DP_None;
endcase
end
// Memory
Op_Lb : Datapath <= DP_Lb;
Op_Lbu : Datapath <= DP_Lbu;
Op_Lh : Datapath <= DP_Lh;
Op_Lhu : Datapath <= DP_Lhu;
Op_Ll : Datapath <= DP_Ll;
Op_Lui : Datapath <= DP_Lui;
Op_Lw : Datapath <= DP_Lw;
Op_Lwl : Datapath <= DP_Lwl;
Op_Lwr : Datapath <= DP_Lwr;
Op_Sb : Datapath <= DP_Sb;
Op_Sc : Datapath <= DP_Sc;
Op_Sh : Datapath <= DP_Sh;
Op_Sw : Datapath <= DP_Sw;
Op_Swl : Datapath <= DP_Swl;
Op_Swr : Datapath <= DP_Swr;
default : Datapath <= DP_None;
endcase
end
end
 
// Set the Hazard Control Signals and Exception Indicators based on the Op Code
always @(*) begin
case (OpCode)
// R-Type
Op_Type_R :
begin
case (Funct)
Funct_Add : begin DP_Hazards <= HAZ_Add; DP_Exceptions <= EXC_Add; end
Funct_Addu : begin DP_Hazards <= HAZ_Addu; DP_Exceptions <= EXC_Addu; end
Funct_And : begin DP_Hazards <= HAZ_And; DP_Exceptions <= EXC_And; end
Funct_Break : begin DP_Hazards <= HAZ_Break; DP_Exceptions <= EXC_Break; end
Funct_Div : begin DP_Hazards <= HAZ_Div; DP_Exceptions <= EXC_Div; end
Funct_Divu : begin DP_Hazards <= HAZ_Divu; DP_Exceptions <= EXC_Divu; end
Funct_Jalr : begin DP_Hazards <= HAZ_Jalr; DP_Exceptions <= EXC_Jalr; end
Funct_Jr : begin DP_Hazards <= HAZ_Jr; DP_Exceptions <= EXC_Jr; end
Funct_Mfhi : begin DP_Hazards <= HAZ_Mfhi; DP_Exceptions <= EXC_Mfhi; end
Funct_Mflo : begin DP_Hazards <= HAZ_Mflo; DP_Exceptions <= EXC_Mflo; end
Funct_Movn : begin DP_Hazards <= HAZ_Movn; DP_Exceptions <= EXC_Movn; end
Funct_Movz : begin DP_Hazards <= HAZ_Movz; DP_Exceptions <= EXC_Movz; end
Funct_Mthi : begin DP_Hazards <= HAZ_Mthi; DP_Exceptions <= EXC_Mthi; end
Funct_Mtlo : begin DP_Hazards <= HAZ_Mtlo; DP_Exceptions <= EXC_Mtlo; end
Funct_Mult : begin DP_Hazards <= HAZ_Mult; DP_Exceptions <= EXC_Mult; end
Funct_Multu : begin DP_Hazards <= HAZ_Multu; DP_Exceptions <= EXC_Multu; end
Funct_Nor : begin DP_Hazards <= HAZ_Nor; DP_Exceptions <= EXC_Nor; end
Funct_Or : begin DP_Hazards <= HAZ_Or; DP_Exceptions <= EXC_Or; end
Funct_Sll : begin DP_Hazards <= HAZ_Sll; DP_Exceptions <= EXC_Sll; end
Funct_Sllv : begin DP_Hazards <= HAZ_Sllv; DP_Exceptions <= EXC_Sllv; end
Funct_Slt : begin DP_Hazards <= HAZ_Slt; DP_Exceptions <= EXC_Slt; end
Funct_Sltu : begin DP_Hazards <= HAZ_Sltu; DP_Exceptions <= EXC_Sltu; end
Funct_Sra : begin DP_Hazards <= HAZ_Sra; DP_Exceptions <= EXC_Sra; end
Funct_Srav : begin DP_Hazards <= HAZ_Srav; DP_Exceptions <= EXC_Srav; end
Funct_Srl : begin DP_Hazards <= HAZ_Srl; DP_Exceptions <= EXC_Srl; end
Funct_Srlv : begin DP_Hazards <= HAZ_Srlv; DP_Exceptions <= EXC_Srlv; end
Funct_Sub : begin DP_Hazards <= HAZ_Sub; DP_Exceptions <= EXC_Sub; end
Funct_Subu : begin DP_Hazards <= HAZ_Subu; DP_Exceptions <= EXC_Subu; end
Funct_Syscall : begin DP_Hazards <= HAZ_Syscall; DP_Exceptions <= EXC_Syscall; end
Funct_Teq : begin DP_Hazards <= HAZ_Teq; DP_Exceptions <= EXC_Teq; end
Funct_Tge : begin DP_Hazards <= HAZ_Tge; DP_Exceptions <= EXC_Tge; end
Funct_Tgeu : begin DP_Hazards <= HAZ_Tgeu; DP_Exceptions <= EXC_Tgeu; end
Funct_Tlt : begin DP_Hazards <= HAZ_Tlt; DP_Exceptions <= EXC_Tlt; end
Funct_Tltu : begin DP_Hazards <= HAZ_Tltu; DP_Exceptions <= EXC_Tltu; end
Funct_Tne : begin DP_Hazards <= HAZ_Tne; DP_Exceptions <= EXC_Tne; end
Funct_Xor : begin DP_Hazards <= HAZ_Xor; DP_Exceptions <= EXC_Xor; end
default : begin DP_Hazards <= 8'hxx; DP_Exceptions <= 3'bxxx; end
endcase
end
// R2-Type
Op_Type_R2 :
begin
case (Funct)
Funct_Clo : begin DP_Hazards <= HAZ_Clo; DP_Exceptions <= EXC_Clo; end
Funct_Clz : begin DP_Hazards <= HAZ_Clz; DP_Exceptions <= EXC_Clz; end
Funct_Madd : begin DP_Hazards <= HAZ_Madd; DP_Exceptions <= EXC_Madd; end
Funct_Maddu : begin DP_Hazards <= HAZ_Maddu; DP_Exceptions <= EXC_Maddu; end
Funct_Msub : begin DP_Hazards <= HAZ_Msub; DP_Exceptions <= EXC_Msub; end
Funct_Msubu : begin DP_Hazards <= HAZ_Msubu; DP_Exceptions <= EXC_Msubu; end
Funct_Mul : begin DP_Hazards <= HAZ_Mul; DP_Exceptions <= EXC_Mul; end
default : begin DP_Hazards <= 8'hxx; DP_Exceptions <= 3'bxxx; end
endcase
end
// I-Type
Op_Addi : begin DP_Hazards <= HAZ_Addi; DP_Exceptions <= EXC_Addi; end
Op_Addiu : begin DP_Hazards <= HAZ_Addiu; DP_Exceptions <= EXC_Addiu; end
Op_Andi : begin DP_Hazards <= HAZ_Andi; DP_Exceptions <= EXC_Andi; end
Op_Ori : begin DP_Hazards <= HAZ_Ori; DP_Exceptions <= EXC_Ori; end
Op_Pref : begin DP_Hazards <= HAZ_Pref; DP_Exceptions <= EXC_Pref; end
Op_Slti : begin DP_Hazards <= HAZ_Slti; DP_Exceptions <= EXC_Slti; end
Op_Sltiu : begin DP_Hazards <= HAZ_Sltiu; DP_Exceptions <= EXC_Sltiu; end
Op_Xori : begin DP_Hazards <= HAZ_Xori; DP_Exceptions <= EXC_Xori; end
// Jumps
Op_J : begin DP_Hazards <= HAZ_J; DP_Exceptions <= EXC_J; end
Op_Jal : begin DP_Hazards <= HAZ_Jal; DP_Exceptions <= EXC_Jal; end
// Branches and Traps
Op_Type_BI :
begin
case (Rt)
OpRt_Bgez : begin DP_Hazards <= HAZ_Bgez; DP_Exceptions <= EXC_Bgez; end
OpRt_Bgezal : begin DP_Hazards <= HAZ_Bgezal; DP_Exceptions <= EXC_Bgezal; end
OpRt_Bltz : begin DP_Hazards <= HAZ_Bltz; DP_Exceptions <= EXC_Bltz; end
OpRt_Bltzal : begin DP_Hazards <= HAZ_Bltzal; DP_Exceptions <= EXC_Bltzal; end
OpRt_Teqi : begin DP_Hazards <= HAZ_Teqi; DP_Exceptions <= EXC_Teqi; end
OpRt_Tgei : begin DP_Hazards <= HAZ_Tgei; DP_Exceptions <= EXC_Tgei; end
OpRt_Tgeiu : begin DP_Hazards <= HAZ_Tgeiu; DP_Exceptions <= EXC_Tgeiu; end
OpRt_Tlti : begin DP_Hazards <= HAZ_Tlti; DP_Exceptions <= EXC_Tlti; end
OpRt_Tltiu : begin DP_Hazards <= HAZ_Tltiu; DP_Exceptions <= EXC_Tltiu; end
OpRt_Tnei : begin DP_Hazards <= HAZ_Tnei; DP_Exceptions <= EXC_Tnei; end
default : begin DP_Hazards <= 8'hxx; DP_Exceptions <= 3'bxxx; end
endcase
end
Op_Beq : begin DP_Hazards <= HAZ_Beq; DP_Exceptions <= EXC_Beq; end
Op_Bgtz : begin DP_Hazards <= HAZ_Bgtz; DP_Exceptions <= EXC_Bgtz; end
Op_Blez : begin DP_Hazards <= HAZ_Blez; DP_Exceptions <= EXC_Blez; end
Op_Bne : begin DP_Hazards <= HAZ_Bne; DP_Exceptions <= EXC_Bne; end
// Coprocessor 0
Op_Type_CP0 :
begin
case (Rs)
OpRs_MF : begin DP_Hazards <= HAZ_Mfc0; DP_Exceptions <= EXC_Mfc0; end
OpRs_MT : begin DP_Hazards <= HAZ_Mtc0; DP_Exceptions <= EXC_Mtc0; end
// Set the Hazard Control Signals and Exception Indicators based on the Op Code
always @(*) begin
case (OpCode)
// R-Type
Op_Type_R :
begin
case (Funct)
Funct_Add : begin DP_Hazards <= HAZ_Add; DP_Exceptions <= EXC_Add; end
Funct_Addu : begin DP_Hazards <= HAZ_Addu; DP_Exceptions <= EXC_Addu; end
Funct_And : begin DP_Hazards <= HAZ_And; DP_Exceptions <= EXC_And; end
Funct_Break : begin DP_Hazards <= HAZ_Break; DP_Exceptions <= EXC_Break; end
Funct_Div : begin DP_Hazards <= HAZ_Div; DP_Exceptions <= EXC_Div; end
Funct_Divu : begin DP_Hazards <= HAZ_Divu; DP_Exceptions <= EXC_Divu; end
Funct_Jalr : begin DP_Hazards <= HAZ_Jalr; DP_Exceptions <= EXC_Jalr; end
Funct_Jr : begin DP_Hazards <= HAZ_Jr; DP_Exceptions <= EXC_Jr; end
Funct_Mfhi : begin DP_Hazards <= HAZ_Mfhi; DP_Exceptions <= EXC_Mfhi; end
Funct_Mflo : begin DP_Hazards <= HAZ_Mflo; DP_Exceptions <= EXC_Mflo; end
Funct_Movn : begin DP_Hazards <= HAZ_Movn; DP_Exceptions <= EXC_Movn; end
Funct_Movz : begin DP_Hazards <= HAZ_Movz; DP_Exceptions <= EXC_Movz; end
Funct_Mthi : begin DP_Hazards <= HAZ_Mthi; DP_Exceptions <= EXC_Mthi; end
Funct_Mtlo : begin DP_Hazards <= HAZ_Mtlo; DP_Exceptions <= EXC_Mtlo; end
Funct_Mult : begin DP_Hazards <= HAZ_Mult; DP_Exceptions <= EXC_Mult; end
Funct_Multu : begin DP_Hazards <= HAZ_Multu; DP_Exceptions <= EXC_Multu; end
Funct_Nor : begin DP_Hazards <= HAZ_Nor; DP_Exceptions <= EXC_Nor; end
Funct_Or : begin DP_Hazards <= HAZ_Or; DP_Exceptions <= EXC_Or; end
Funct_Sll : begin DP_Hazards <= HAZ_Sll; DP_Exceptions <= EXC_Sll; end
Funct_Sllv : begin DP_Hazards <= HAZ_Sllv; DP_Exceptions <= EXC_Sllv; end
Funct_Slt : begin DP_Hazards <= HAZ_Slt; DP_Exceptions <= EXC_Slt; end
Funct_Sltu : begin DP_Hazards <= HAZ_Sltu; DP_Exceptions <= EXC_Sltu; end
Funct_Sra : begin DP_Hazards <= HAZ_Sra; DP_Exceptions <= EXC_Sra; end
Funct_Srav : begin DP_Hazards <= HAZ_Srav; DP_Exceptions <= EXC_Srav; end
Funct_Srl : begin DP_Hazards <= HAZ_Srl; DP_Exceptions <= EXC_Srl; end
Funct_Srlv : begin DP_Hazards <= HAZ_Srlv; DP_Exceptions <= EXC_Srlv; end
Funct_Sub : begin DP_Hazards <= HAZ_Sub; DP_Exceptions <= EXC_Sub; end
Funct_Subu : begin DP_Hazards <= HAZ_Subu; DP_Exceptions <= EXC_Subu; end
Funct_Syscall : begin DP_Hazards <= HAZ_Syscall; DP_Exceptions <= EXC_Syscall; end
Funct_Teq : begin DP_Hazards <= HAZ_Teq; DP_Exceptions <= EXC_Teq; end
Funct_Tge : begin DP_Hazards <= HAZ_Tge; DP_Exceptions <= EXC_Tge; end
Funct_Tgeu : begin DP_Hazards <= HAZ_Tgeu; DP_Exceptions <= EXC_Tgeu; end
Funct_Tlt : begin DP_Hazards <= HAZ_Tlt; DP_Exceptions <= EXC_Tlt; end
Funct_Tltu : begin DP_Hazards <= HAZ_Tltu; DP_Exceptions <= EXC_Tltu; end
Funct_Tne : begin DP_Hazards <= HAZ_Tne; DP_Exceptions <= EXC_Tne; end
Funct_Xor : begin DP_Hazards <= HAZ_Xor; DP_Exceptions <= EXC_Xor; end
default : begin DP_Hazards <= 8'hxx; DP_Exceptions <= 3'bxxx; end
endcase
end
// R2-Type
Op_Type_R2 :
begin
case (Funct)
Funct_Clo : begin DP_Hazards <= HAZ_Clo; DP_Exceptions <= EXC_Clo; end
Funct_Clz : begin DP_Hazards <= HAZ_Clz; DP_Exceptions <= EXC_Clz; end
Funct_Madd : begin DP_Hazards <= HAZ_Madd; DP_Exceptions <= EXC_Madd; end
Funct_Maddu : begin DP_Hazards <= HAZ_Maddu; DP_Exceptions <= EXC_Maddu; end
Funct_Msub : begin DP_Hazards <= HAZ_Msub; DP_Exceptions <= EXC_Msub; end
Funct_Msubu : begin DP_Hazards <= HAZ_Msubu; DP_Exceptions <= EXC_Msubu; end
Funct_Mul : begin DP_Hazards <= HAZ_Mul; DP_Exceptions <= EXC_Mul; end
default : begin DP_Hazards <= 8'hxx; DP_Exceptions <= 3'bxxx; end
endcase
end
// I-Type
Op_Addi : begin DP_Hazards <= HAZ_Addi; DP_Exceptions <= EXC_Addi; end
Op_Addiu : begin DP_Hazards <= HAZ_Addiu; DP_Exceptions <= EXC_Addiu; end
Op_Andi : begin DP_Hazards <= HAZ_Andi; DP_Exceptions <= EXC_Andi; end
Op_Ori : begin DP_Hazards <= HAZ_Ori; DP_Exceptions <= EXC_Ori; end
Op_Pref : begin DP_Hazards <= HAZ_Pref; DP_Exceptions <= EXC_Pref; end
Op_Slti : begin DP_Hazards <= HAZ_Slti; DP_Exceptions <= EXC_Slti; end
Op_Sltiu : begin DP_Hazards <= HAZ_Sltiu; DP_Exceptions <= EXC_Sltiu; end
Op_Xori : begin DP_Hazards <= HAZ_Xori; DP_Exceptions <= EXC_Xori; end
// Jumps
Op_J : begin DP_Hazards <= HAZ_J; DP_Exceptions <= EXC_J; end
Op_Jal : begin DP_Hazards <= HAZ_Jal; DP_Exceptions <= EXC_Jal; end
// Branches and Traps
Op_Type_BI :
begin
case (Rt)
OpRt_Bgez : begin DP_Hazards <= HAZ_Bgez; DP_Exceptions <= EXC_Bgez; end
OpRt_Bgezal : begin DP_Hazards <= HAZ_Bgezal; DP_Exceptions <= EXC_Bgezal; end
OpRt_Bltz : begin DP_Hazards <= HAZ_Bltz; DP_Exceptions <= EXC_Bltz; end
OpRt_Bltzal : begin DP_Hazards <= HAZ_Bltzal; DP_Exceptions <= EXC_Bltzal; end
OpRt_Teqi : begin DP_Hazards <= HAZ_Teqi; DP_Exceptions <= EXC_Teqi; end
OpRt_Tgei : begin DP_Hazards <= HAZ_Tgei; DP_Exceptions <= EXC_Tgei; end
OpRt_Tgeiu : begin DP_Hazards <= HAZ_Tgeiu; DP_Exceptions <= EXC_Tgeiu; end
OpRt_Tlti : begin DP_Hazards <= HAZ_Tlti; DP_Exceptions <= EXC_Tlti; end
OpRt_Tltiu : begin DP_Hazards <= HAZ_Tltiu; DP_Exceptions <= EXC_Tltiu; end
OpRt_Tnei : begin DP_Hazards <= HAZ_Tnei; DP_Exceptions <= EXC_Tnei; end
default : begin DP_Hazards <= 8'hxx; DP_Exceptions <= 3'bxxx; end
endcase
end
Op_Beq : begin DP_Hazards <= HAZ_Beq; DP_Exceptions <= EXC_Beq; end
Op_Bgtz : begin DP_Hazards <= HAZ_Bgtz; DP_Exceptions <= EXC_Bgtz; end
Op_Blez : begin DP_Hazards <= HAZ_Blez; DP_Exceptions <= EXC_Blez; end
Op_Bne : begin DP_Hazards <= HAZ_Bne; DP_Exceptions <= EXC_Bne; end
// Coprocessor 0
Op_Type_CP0 :
begin
case (Rs)
OpRs_MF : begin DP_Hazards <= HAZ_Mfc0; DP_Exceptions <= EXC_Mfc0; end
OpRs_MT : begin DP_Hazards <= HAZ_Mtc0; DP_Exceptions <= EXC_Mtc0; end
OpRs_ERET : begin DP_Hazards <= (Funct == Funct_ERET) ? DP_Eret : 8'hxx; DP_Exceptions <= EXC_Eret; end
default : begin DP_Hazards <= 8'hxx; DP_Exceptions <= 3'bxxx; end
endcase
end
// Memory
Op_Lb : begin DP_Hazards <= HAZ_Lb; DP_Exceptions <= EXC_Lb; end
Op_Lbu : begin DP_Hazards <= HAZ_Lbu; DP_Exceptions <= EXC_Lbu; end
Op_Lh : begin DP_Hazards <= HAZ_Lh; DP_Exceptions <= EXC_Lh; end
Op_Lhu : begin DP_Hazards <= HAZ_Lhu; DP_Exceptions <= EXC_Lhu; end
Op_Ll : begin DP_Hazards <= HAZ_Ll; DP_Exceptions <= EXC_Ll; end
Op_Lui : begin DP_Hazards <= HAZ_Lui; DP_Exceptions <= EXC_Lui; end
Op_Lw : begin DP_Hazards <= HAZ_Lw; DP_Exceptions <= EXC_Lw; end
Op_Lwl : begin DP_Hazards <= HAZ_Lwl; DP_Exceptions <= EXC_Lwl; end
Op_Lwr : begin DP_Hazards <= HAZ_Lwr; DP_Exceptions <= EXC_Lwr; end
Op_Sb : begin DP_Hazards <= HAZ_Sb; DP_Exceptions <= EXC_Sb; end
Op_Sc : begin DP_Hazards <= HAZ_Sc; DP_Exceptions <= EXC_Sc; end
Op_Sh : begin DP_Hazards <= HAZ_Sh; DP_Exceptions <= EXC_Sh; end
Op_Sw : begin DP_Hazards <= HAZ_Sw; DP_Exceptions <= EXC_Sw; end
Op_Swl : begin DP_Hazards <= HAZ_Swl; DP_Exceptions <= EXC_Swl; end
Op_Swr : begin DP_Hazards <= HAZ_Swr; DP_Exceptions <= EXC_Swr; end
default : begin DP_Hazards <= 8'hxx; DP_Exceptions <= 3'bxxx; end
endcase
end
default : begin DP_Hazards <= 8'hxx; DP_Exceptions <= 3'bxxx; end
endcase
end
// Memory
Op_Lb : begin DP_Hazards <= HAZ_Lb; DP_Exceptions <= EXC_Lb; end
Op_Lbu : begin DP_Hazards <= HAZ_Lbu; DP_Exceptions <= EXC_Lbu; end
Op_Lh : begin DP_Hazards <= HAZ_Lh; DP_Exceptions <= EXC_Lh; end
Op_Lhu : begin DP_Hazards <= HAZ_Lhu; DP_Exceptions <= EXC_Lhu; end
Op_Ll : begin DP_Hazards <= HAZ_Ll; DP_Exceptions <= EXC_Ll; end
Op_Lui : begin DP_Hazards <= HAZ_Lui; DP_Exceptions <= EXC_Lui; end
Op_Lw : begin DP_Hazards <= HAZ_Lw; DP_Exceptions <= EXC_Lw; end
Op_Lwl : begin DP_Hazards <= HAZ_Lwl; DP_Exceptions <= EXC_Lwl; end
Op_Lwr : begin DP_Hazards <= HAZ_Lwr; DP_Exceptions <= EXC_Lwr; end
Op_Sb : begin DP_Hazards <= HAZ_Sb; DP_Exceptions <= EXC_Sb; end
Op_Sc : begin DP_Hazards <= HAZ_Sc; DP_Exceptions <= EXC_Sc; end
Op_Sh : begin DP_Hazards <= HAZ_Sh; DP_Exceptions <= EXC_Sh; end
Op_Sw : begin DP_Hazards <= HAZ_Sw; DP_Exceptions <= EXC_Sw; end
Op_Swl : begin DP_Hazards <= HAZ_Swl; DP_Exceptions <= EXC_Swl; end
Op_Swr : begin DP_Hazards <= HAZ_Swr; DP_Exceptions <= EXC_Swr; end
default : begin DP_Hazards <= 8'hxx; DP_Exceptions <= 3'bxxx; end
endcase
end
 
// ALU Assignment
always @(*) begin
if (ID_Stall)
ALUOp <= AluOp_Addu; // Any Op that doesn't write HILO or cause exceptions
else begin
case (OpCode)
Op_Type_R :
begin
case (Funct)
Funct_Add : ALUOp <= AluOp_Add;
Funct_Addu : ALUOp <= AluOp_Addu;
Funct_And : ALUOp <= AluOp_And;
Funct_Div : ALUOp <= AluOp_Div;
Funct_Divu : ALUOp <= AluOp_Divu;
Funct_Jalr : ALUOp <= AluOp_Addu;
Funct_Mfhi : ALUOp <= AluOp_Mfhi;
Funct_Mflo : ALUOp <= AluOp_Mflo;
Funct_Movn : ALUOp <= AluOp_Addu;
Funct_Movz : ALUOp <= AluOp_Addu;
Funct_Mthi : ALUOp <= AluOp_Mthi;
Funct_Mtlo : ALUOp <= AluOp_Mtlo;
Funct_Mult : ALUOp <= AluOp_Mult;
Funct_Multu : ALUOp <= AluOp_Multu;
Funct_Nor : ALUOp <= AluOp_Nor;
Funct_Or : ALUOp <= AluOp_Or;
Funct_Sll : ALUOp <= AluOp_Sll;
Funct_Sllv : ALUOp <= AluOp_Sllv;
Funct_Slt : ALUOp <= AluOp_Slt;
Funct_Sltu : ALUOp <= AluOp_Sltu;
Funct_Sra : ALUOp <= AluOp_Sra;
Funct_Srav : ALUOp <= AluOp_Srav;
Funct_Srl : ALUOp <= AluOp_Srl;
Funct_Srlv : ALUOp <= AluOp_Srlv;
Funct_Sub : ALUOp <= AluOp_Sub;
Funct_Subu : ALUOp <= AluOp_Subu;
// ALU Assignment
always @(*) begin
if (ID_Stall)
ALUOp <= AluOp_Addu; // Any Op that doesn't write HILO or cause exceptions
else begin
case (OpCode)
Op_Type_R :
begin
case (Funct)
Funct_Add : ALUOp <= AluOp_Add;
Funct_Addu : ALUOp <= AluOp_Addu;
Funct_And : ALUOp <= AluOp_And;
Funct_Div : ALUOp <= AluOp_Div;
Funct_Divu : ALUOp <= AluOp_Divu;
Funct_Jalr : ALUOp <= AluOp_Addu;
Funct_Mfhi : ALUOp <= AluOp_Mfhi;
Funct_Mflo : ALUOp <= AluOp_Mflo;
Funct_Movn : ALUOp <= AluOp_Addu;
Funct_Movz : ALUOp <= AluOp_Addu;
Funct_Mthi : ALUOp <= AluOp_Mthi;
Funct_Mtlo : ALUOp <= AluOp_Mtlo;
Funct_Mult : ALUOp <= AluOp_Mult;
Funct_Multu : ALUOp <= AluOp_Multu;
Funct_Nor : ALUOp <= AluOp_Nor;
Funct_Or : ALUOp <= AluOp_Or;
Funct_Sll : ALUOp <= AluOp_Sll;
Funct_Sllv : ALUOp <= AluOp_Sllv;
Funct_Slt : ALUOp <= AluOp_Slt;
Funct_Sltu : ALUOp <= AluOp_Sltu;
Funct_Sra : ALUOp <= AluOp_Sra;
Funct_Srav : ALUOp <= AluOp_Srav;
Funct_Srl : ALUOp <= AluOp_Srl;
Funct_Srlv : ALUOp <= AluOp_Srlv;
Funct_Sub : ALUOp <= AluOp_Sub;
Funct_Subu : ALUOp <= AluOp_Subu;
Funct_Syscall : ALUOp <= AluOp_Addu;
Funct_Teq : ALUOp <= AluOp_Subu;
Funct_Tge : ALUOp <= AluOp_Slt;
Funct_Tgeu : ALUOp <= AluOp_Sltu;
Funct_Tlt : ALUOp <= AluOp_Slt;
Funct_Tltu : ALUOp <= AluOp_Sltu;
Funct_Tne : ALUOp <= AluOp_Subu;
Funct_Xor : ALUOp <= AluOp_Xor;
default : ALUOp <= AluOp_Addu;
endcase
end
Op_Type_R2 :
begin
case (Funct)
Funct_Clo : ALUOp <= AluOp_Clo;
Funct_Clz : ALUOp <= AluOp_Clz;
Funct_Madd : ALUOp <= AluOp_Madd;
Funct_Maddu : ALUOp <= AluOp_Maddu;
Funct_Msub : ALUOp <= AluOp_Msub;
Funct_Msubu : ALUOp <= AluOp_Msubu;
Funct_Mul : ALUOp <= AluOp_Mul;
default : ALUOp <= AluOp_Addu;
endcase
end
Funct_Tge : ALUOp <= AluOp_Slt;
Funct_Tgeu : ALUOp <= AluOp_Sltu;
Funct_Tlt : ALUOp <= AluOp_Slt;
Funct_Tltu : ALUOp <= AluOp_Sltu;
Funct_Tne : ALUOp <= AluOp_Subu;
Funct_Xor : ALUOp <= AluOp_Xor;
default : ALUOp <= AluOp_Addu;
endcase
end
Op_Type_R2 :
begin
case (Funct)
Funct_Clo : ALUOp <= AluOp_Clo;
Funct_Clz : ALUOp <= AluOp_Clz;
Funct_Madd : ALUOp <= AluOp_Madd;
Funct_Maddu : ALUOp <= AluOp_Maddu;
Funct_Msub : ALUOp <= AluOp_Msub;
Funct_Msubu : ALUOp <= AluOp_Msubu;
Funct_Mul : ALUOp <= AluOp_Mul;
default : ALUOp <= AluOp_Addu;
endcase
end
Op_Type_BI :
begin
case (Rt)
OpRt_Teqi : ALUOp <= AluOp_Subu;
OpRt_Tgei : ALUOp <= AluOp_Slt;
OpRt_Tgeiu : ALUOp <= AluOp_Sltu;
OpRt_Tlti : ALUOp <= AluOp_Slt;
OpRt_Tltiu : ALUOp <= AluOp_Sltu;
OpRt_Tnei : ALUOp <= AluOp_Subu;
default : ALUOp <= AluOp_Addu; // Branches don't matter.
endcase
OpRt_Teqi : ALUOp <= AluOp_Subu;
OpRt_Tgei : ALUOp <= AluOp_Slt;
OpRt_Tgeiu : ALUOp <= AluOp_Sltu;
OpRt_Tlti : ALUOp <= AluOp_Slt;
OpRt_Tltiu : ALUOp <= AluOp_Sltu;
OpRt_Tnei : ALUOp <= AluOp_Subu;
default : ALUOp <= AluOp_Addu; // Branches don't matter.
endcase
end
Op_Type_CP0 : ALUOp <= AluOp_Addu;
Op_Addi : ALUOp <= AluOp_Add;
Op_Addiu : ALUOp <= AluOp_Addu;
Op_Andi : ALUOp <= AluOp_And;
Op_Jal : ALUOp <= AluOp_Addu;
Op_Lb : ALUOp <= AluOp_Addu;
Op_Lbu : ALUOp <= AluOp_Addu;
Op_Lh : ALUOp <= AluOp_Addu;
Op_Lhu : ALUOp <= AluOp_Addu;
Op_Ll : ALUOp <= AluOp_Addu;
Op_Lui : ALUOp <= AluOp_Sllc;
Op_Lw : ALUOp <= AluOp_Addu;
Op_Lwl : ALUOp <= AluOp_Addu;
Op_Lwr : ALUOp <= AluOp_Addu;
Op_Ori : ALUOp <= AluOp_Or;
Op_Sb : ALUOp <= AluOp_Addu;
Op_Sc : ALUOp <= AluOp_Addu; // XXX Needs HW implement
Op_Sh : ALUOp <= AluOp_Addu;
Op_Slti : ALUOp <= AluOp_Slt;
Op_Sltiu : ALUOp <= AluOp_Sltu;
Op_Sw : ALUOp <= AluOp_Addu;
Op_Swl : ALUOp <= AluOp_Addu;
Op_Swr : ALUOp <= AluOp_Addu;
Op_Xori : ALUOp <= AluOp_Xor;
default : ALUOp <= AluOp_Addu;
endcase
end
end
Op_Addi : ALUOp <= AluOp_Add;
Op_Addiu : ALUOp <= AluOp_Addu;
Op_Andi : ALUOp <= AluOp_And;
Op_Jal : ALUOp <= AluOp_Addu;
Op_Lb : ALUOp <= AluOp_Addu;
Op_Lbu : ALUOp <= AluOp_Addu;
Op_Lh : ALUOp <= AluOp_Addu;
Op_Lhu : ALUOp <= AluOp_Addu;
Op_Ll : ALUOp <= AluOp_Addu;
Op_Lui : ALUOp <= AluOp_Sllc;
Op_Lw : ALUOp <= AluOp_Addu;
Op_Lwl : ALUOp <= AluOp_Addu;
Op_Lwr : ALUOp <= AluOp_Addu;
Op_Ori : ALUOp <= AluOp_Or;
Op_Sb : ALUOp <= AluOp_Addu;
Op_Sc : ALUOp <= AluOp_Addu; // XXX Needs HW implement
Op_Sh : ALUOp <= AluOp_Addu;
Op_Slti : ALUOp <= AluOp_Slt;
Op_Sltiu : ALUOp <= AluOp_Sltu;
Op_Sw : ALUOp <= AluOp_Addu;
Op_Swl : ALUOp <= AluOp_Addu;
Op_Swr : ALUOp <= AluOp_Addu;
Op_Xori : ALUOp <= AluOp_Xor;
default : ALUOp <= AluOp_Addu;
endcase
end
end
 
/***
These remaining options cover portions of the datapath that are not
465,15 → 465,15
assign PCSrc[1] = (Datapath[15] & ~Datapath[14]) ? Branch : Datapath[15];
/* In MIPS32, all Branch and Jump operations execute the Branch Delay Slot,
* or next instruction, regardless if the branch is taken or not. The exception
* is the "Branch Likely" instruction group. These are deprecated, however, and not
* implemented here. "IF_Flush" is defined to allow for the cancelation of a
* Branch Delay Slot should these be implemented later.
*/
assign IF_Flush = 0;
* or next instruction, regardless if the branch is taken or not. The exception
* is the "Branch Likely" instruction group. These are deprecated, however, and not
* implemented here. "IF_Flush" is defined to allow for the cancelation of a
* Branch Delay Slot should these be implemented later.
*/
assign IF_Flush = 0;
 
// Indicator that next instruction is a Branch Delay Slot.
assign NextIsDelay = Datapath[15] | Datapath[14];
// Indicator that next instruction is a Branch Delay Slot.
assign NextIsDelay = Datapath[15] | Datapath[14];
// Sign- or Zero-Extension Control. The only ops that require zero-extension are
// Andi, Ori, and Xori. The following also zero-extends 'lui', however it does not alter the effect of lui.
482,10 → 482,10
// Move Conditional
assign Movn = Movc & Funct[0];
assign Movz = Movc & ~Funct[0];
// Coprocessor 0 (Mfc0, Mtc0) control signals.
// Coprocessor 0 (Mfc0, Mtc0) control signals.
assign Mfc0 = ((OpCode == Op_Type_CP0) && (Rs == OpRs_MF));
assign Mtc0 = ((OpCode == Op_Type_CP0) && (Rs == OpRs_MT));
assign Mtc0 = ((OpCode == Op_Type_CP0) && (Rs == OpRs_MT));
assign Eret = ((OpCode == Op_Type_CP0) && (Rs == OpRs_ERET) && (Funct == Funct_ERET));
// Coprocessor 1,2,3 accesses (not implemented)
506,3 → 506,4
assign EXC_RI = 0;
endmodule
 
/XUPV5-LX110T_SoC/MIPS32-Pipelined-Hw/src/MIPS32/ALU.v
1,207 → 1,209
`timescale 1ns / 1ps
/*
* File : ALU.v
* Project : University of Utah, XUM Project MIPS32 core
* Creator(s) : Grant Ayers (ayers@cs.utah.edu)
*
* Modification History:
* Rev Date Initials Description of Change
* 1.0 7-Jun-2011 GEA Initial design.
* 2.0 26-Jul-2012 GEA Many changes have been made.
*
* Standards/Formatting:
* Verilog 2001, 4 soft tab, wide column.
*
* Description:
* An Arithmetic Logic Unit for a MIPS32 processor. This module computes all
* arithmetic operations, including the following:
*
* Add, Subtract, Multiply, And, Or, Nor, Xor, Shift, Count leading 1s/0s.
*/
module ALU(
input clock,
input reset,
input EX_Stall,
input EX_Flush,
input [31:0] A, B,
input [4:0] Operation,
input signed [4:0] Shamt,
output reg signed [31:0] Result,
output BZero, // Used for Movc
output reg EXC_Ov
);
 
`include "MIPS_Parameters.v"
/***
Performance Notes:
The ALU is the longest delay path in the Execute stage, and one of the longest
in the entire processor. This path varies based on the logic blocks that are
chosen to implement various functions, but there is certainly room to improve
the speed of arithmetic operations. The ALU could also be placed in a separate
pipeline stage after the Execute forwarding has completed.
***/
wire signed [31:0] As = A;
wire signed [31:0] Bs = B;
reg [63:0] HILO;
wire [31:0] HI = HILO[63:32];
wire [31:0] LO = HILO[31:0];
wire HILO_Commit = ~(EX_Stall | EX_Flush);
wire AddSub_Add = ((Operation == AluOp_Add) | (Operation == AluOp_Addu));
wire signed [31:0] AddSub_Result = (AddSub_Add) ? (A + B) : (A - B);
wire signed [63:0] Mult_Result = As * Bs;
wire [63:0] Multu_Result = A * B;
reg [5:0] CLO_Result, CLZ_Result;
assign BZero = (B == 32'h00000000);
always @(*) begin
case (Operation)
AluOp_Add : Result <= AddSub_Result;
AluOp_Addu : Result <= AddSub_Result;
AluOp_And : Result <= A & B;
AluOp_Clo : Result <= {26'b0, CLO_Result};
AluOp_Clz : Result <= {26'b0, CLZ_Result};
AluOp_Div : Result <= 32'hdeafbeef; // XXX implement division
AluOp_Divu : Result <= 32'hdeadbeef; // XXX implement division
AluOp_Mfhi : Result <= HI;
AluOp_Mflo : Result <= LO;
AluOp_Mul : Result <= Mult_Result[31:0];
AluOp_Nor : Result <= ~(A | B);
AluOp_Or : Result <= A | B;
AluOp_Sll : Result <= B << Shamt;
AluOp_Sllc : Result <= {B[15:0], 16'b0};
AluOp_Sllv : Result <= B << A[4:0];
AluOp_Slt : Result <= (As < Bs) ? 32'h00000001 : 32'h00000000;
AluOp_Sltu : Result <= (A < B) ? 32'h00000001 : 32'h00000000;
AluOp_Sra : Result <= Bs >>> Shamt;
AluOp_Srav : Result <= Bs >>> As[4:0];
AluOp_Srl : Result <= B >> Shamt;
AluOp_Srlv : Result <= B >> A[4:0];
AluOp_Sub : Result <= AddSub_Result;
AluOp_Subu : Result <= AddSub_Result;
AluOp_Xor : Result <= A ^ B;
default : Result <= 32'bx;
endcase
end
always @(posedge clock) begin
if (reset) begin
HILO <= 64'h00000000_00000000;
end
else if (HILO_Commit) begin
case (Operation)
AluOp_Mult : HILO <= Mult_Result;
AluOp_Multu : HILO <= Multu_Result;
AluOp_Madd : HILO <= HILO + Mult_Result;
AluOp_Maddu : HILO <= HILO + Multu_Result;
AluOp_Msub : HILO <= HILO - Mult_Result;
AluOp_Msubu : HILO <= HILO - Multu_Result;
AluOp_Mthi : HILO <= {A, LO};
AluOp_Mtlo : HILO <= {HI, B};
default : HILO <= HILO;
endcase
end
else begin
HILO <= HILO;
end
end
// Detect overflow for signed operations. Note that MIPS32 has no overflow
// detection for multiplication/division operations.
always @(*) begin
case (Operation)
`timescale 1ns / 1ps
/*
* File : ALU.v
* Project : University of Utah, XUM Project MIPS32 core
* Creator(s) : Grant Ayers (ayers@cs.utah.edu)
*
* Modification History:
* Rev Date Initials Description of Change
* 1.0 7-Jun-2011 GEA Initial design.
* 2.0 26-Jul-2012 GEA Many changes have been made.
*
* Standards/Formatting:
* Verilog 2001, 4 soft tab, wide column.
*
* Description:
* An Arithmetic Logic Unit for a MIPS32 processor. This module computes all
* arithmetic operations, including the following:
*
* Add, Subtract, Multiply, And, Or, Nor, Xor, Shift, Count leading 1s/0s.
*/
module ALU(
input clock,
input reset,
input EX_Stall,
input EX_Flush,
input [31:0] A, B,
input [4:0] Operation,
input signed [4:0] Shamt,
output reg signed [31:0] Result,
output BZero, // Used for Movc
output reg EXC_Ov
);
 
`include "MIPS_Parameters.v"
/***
Performance Notes:
The ALU is the longest delay path in the Execute stage, and one of the longest
in the entire processor. This path varies based on the logic blocks that are
chosen to implement various functions, but there is certainly room to improve
the speed of arithmetic operations. The ALU could also be placed in a separate
pipeline stage after the Execute forwarding has completed.
***/
wire signed [31:0] As = A;
wire signed [31:0] Bs = B;
reg [63:0] HILO;
wire [31:0] HI = HILO[63:32];
wire [31:0] LO = HILO[31:0];
wire HILO_Commit = ~(EX_Stall | EX_Flush);
wire AddSub_Add = ((Operation == AluOp_Add) | (Operation == AluOp_Addu));
wire signed [31:0] AddSub_Result = (AddSub_Add) ? (A + B) : (A - B);
wire signed [63:0] Mult_Result = As * Bs;
wire [63:0] Multu_Result = A * B;
reg [5:0] CLO_Result, CLZ_Result;
assign BZero = (B == 32'h00000000);
always @(*) begin
case (Operation)
AluOp_Add : Result <= AddSub_Result;
AluOp_Addu : Result <= AddSub_Result;
AluOp_And : Result <= A & B;
AluOp_Clo : Result <= {26'b0, CLO_Result};
AluOp_Clz : Result <= {26'b0, CLZ_Result};
AluOp_Div : Result <= 32'hdeafbeef; // XXX implement division
AluOp_Divu : Result <= 32'hdeadbeef; // XXX implement division
AluOp_Mfhi : Result <= HI;
AluOp_Mflo : Result <= LO;
AluOp_Mul : Result <= Mult_Result[31:0];
AluOp_Nor : Result <= ~(A | B);
AluOp_Or : Result <= A | B;
AluOp_Sll : Result <= B << Shamt;
AluOp_Sllc : Result <= {B[15:0], 16'b0};
AluOp_Sllv : Result <= B << A[4:0];
AluOp_Slt : Result <= (As < Bs) ? 32'h00000001 : 32'h00000000;
AluOp_Sltu : Result <= (A < B) ? 32'h00000001 : 32'h00000000;
AluOp_Sra : Result <= Bs >>> Shamt;
AluOp_Srav : Result <= Bs >>> As[4:0];
AluOp_Srl : Result <= B >> Shamt;
AluOp_Srlv : Result <= B >> A[4:0];
AluOp_Sub : Result <= AddSub_Result;
AluOp_Subu : Result <= AddSub_Result;
AluOp_Xor : Result <= A ^ B;
default : Result <= 32'bx;
endcase
end
always @(posedge clock) begin
if (reset) begin
HILO <= 64'h00000000_00000000;
end
else if (HILO_Commit) begin
case (Operation)
AluOp_Mult : HILO <= Mult_Result;
AluOp_Multu : HILO <= Multu_Result;
AluOp_Madd : HILO <= HILO + Mult_Result;
AluOp_Maddu : HILO <= HILO + Multu_Result;
AluOp_Msub : HILO <= HILO - Mult_Result;
AluOp_Msubu : HILO <= HILO - Multu_Result;
AluOp_Mthi : HILO <= {A, LO};
AluOp_Mtlo : HILO <= {HI, B};
default : HILO <= HILO;
endcase
end
else begin
HILO <= HILO;
end
end
// Detect overflow for signed operations. Note that MIPS32 has no overflow
// detection for multiplication/division operations.
always @(*) begin
case (Operation)
AluOp_Add : EXC_Ov <= ((A[31] ~^ B[31]) & (A[31] ^ AddSub_Result[31]));
AluOp_Sub : EXC_Ov <= ((A[31] ^ B[31]) & (A[31] ^ AddSub_Result[31]));
default : EXC_Ov <= 0;
endcase
end
// Count Leading Ones
always @(A) begin
casex (A)
32'b0xxx_xxxx_xxxx_xxxx_xxxx_xxxx_xxxx_xxxx : CLO_Result <= 6'd0;
32'b10xx_xxxx_xxxx_xxxx_xxxx_xxxx_xxxx_xxxx : CLO_Result <= 6'd1;
32'b110x_xxxx_xxxx_xxxx_xxxx_xxxx_xxxx_xxxx : CLO_Result <= 6'd2;
32'b1110_xxxx_xxxx_xxxx_xxxx_xxxx_xxxx_xxxx : CLO_Result <= 6'd3;
32'b1111_0xxx_xxxx_xxxx_xxxx_xxxx_xxxx_xxxx : CLO_Result <= 6'd4;
32'b1111_10xx_xxxx_xxxx_xxxx_xxxx_xxxx_xxxx : CLO_Result <= 6'd5;
32'b1111_110x_xxxx_xxxx_xxxx_xxxx_xxxx_xxxx : CLO_Result <= 6'd6;
32'b1111_1110_xxxx_xxxx_xxxx_xxxx_xxxx_xxxx : CLO_Result <= 6'd7;
32'b1111_1111_0xxx_xxxx_xxxx_xxxx_xxxx_xxxx : CLO_Result <= 6'd8;
32'b1111_1111_10xx_xxxx_xxxx_xxxx_xxxx_xxxx : CLO_Result <= 6'd9;
32'b1111_1111_110x_xxxx_xxxx_xxxx_xxxx_xxxx : CLO_Result <= 6'd10;
32'b1111_1111_1110_xxxx_xxxx_xxxx_xxxx_xxxx : CLO_Result <= 6'd11;
32'b1111_1111_1111_0xxx_xxxx_xxxx_xxxx_xxxx : CLO_Result <= 6'd12;
32'b1111_1111_1111_10xx_xxxx_xxxx_xxxx_xxxx : CLO_Result <= 6'd13;
32'b1111_1111_1111_110x_xxxx_xxxx_xxxx_xxxx : CLO_Result <= 6'd14;
32'b1111_1111_1111_1110_xxxx_xxxx_xxxx_xxxx : CLO_Result <= 6'd15;
32'b1111_1111_1111_1111_0xxx_xxxx_xxxx_xxxx : CLO_Result <= 6'd16;
32'b1111_1111_1111_1111_10xx_xxxx_xxxx_xxxx : CLO_Result <= 6'd17;
32'b1111_1111_1111_1111_110x_xxxx_xxxx_xxxx : CLO_Result <= 6'd18;
32'b1111_1111_1111_1111_1110_xxxx_xxxx_xxxx : CLO_Result <= 6'd19;
32'b1111_1111_1111_1111_1111_0xxx_xxxx_xxxx : CLO_Result <= 6'd20;
32'b1111_1111_1111_1111_1111_10xx_xxxx_xxxx : CLO_Result <= 6'd21;
32'b1111_1111_1111_1111_1111_110x_xxxx_xxxx : CLO_Result <= 6'd22;
32'b1111_1111_1111_1111_1111_1110_xxxx_xxxx : CLO_Result <= 6'd23;
32'b1111_1111_1111_1111_1111_1111_0xxx_xxxx : CLO_Result <= 6'd24;
32'b1111_1111_1111_1111_1111_1111_10xx_xxxx : CLO_Result <= 6'd25;
32'b1111_1111_1111_1111_1111_1111_110x_xxxx : CLO_Result <= 6'd26;
32'b1111_1111_1111_1111_1111_1111_1110_xxxx : CLO_Result <= 6'd27;
32'b1111_1111_1111_1111_1111_1111_1111_0xxx : CLO_Result <= 6'd28;
32'b1111_1111_1111_1111_1111_1111_1111_10xx : CLO_Result <= 6'd29;
32'b1111_1111_1111_1111_1111_1111_1111_110x : CLO_Result <= 6'd30;
32'b1111_1111_1111_1111_1111_1111_1111_1110 : CLO_Result <= 6'd31;
32'b1111_1111_1111_1111_1111_1111_1111_1111 : CLO_Result <= 6'd32;
default : CLO_Result <= 6'd0;
endcase
end
 
// Count Leading Zeros
always @(A) begin
casex (A)
32'b1xxx_xxxx_xxxx_xxxx_xxxx_xxxx_xxxx_xxxx : CLZ_Result <= 6'd0;
32'b01xx_xxxx_xxxx_xxxx_xxxx_xxxx_xxxx_xxxx : CLZ_Result <= 6'd1;
32'b001x_xxxx_xxxx_xxxx_xxxx_xxxx_xxxx_xxxx : CLZ_Result <= 6'd2;
32'b0001_xxxx_xxxx_xxxx_xxxx_xxxx_xxxx_xxxx : CLZ_Result <= 6'd3;
32'b0000_1xxx_xxxx_xxxx_xxxx_xxxx_xxxx_xxxx : CLZ_Result <= 6'd4;
32'b0000_01xx_xxxx_xxxx_xxxx_xxxx_xxxx_xxxx : CLZ_Result <= 6'd5;
32'b0000_001x_xxxx_xxxx_xxxx_xxxx_xxxx_xxxx : CLZ_Result <= 6'd6;
32'b0000_0001_xxxx_xxxx_xxxx_xxxx_xxxx_xxxx : CLZ_Result <= 6'd7;
32'b0000_0000_1xxx_xxxx_xxxx_xxxx_xxxx_xxxx : CLZ_Result <= 6'd8;
32'b0000_0000_01xx_xxxx_xxxx_xxxx_xxxx_xxxx : CLZ_Result <= 6'd9;
32'b0000_0000_001x_xxxx_xxxx_xxxx_xxxx_xxxx : CLZ_Result <= 6'd10;
32'b0000_0000_0001_xxxx_xxxx_xxxx_xxxx_xxxx : CLZ_Result <= 6'd11;
32'b0000_0000_0000_1xxx_xxxx_xxxx_xxxx_xxxx : CLZ_Result <= 6'd12;
32'b0000_0000_0000_01xx_xxxx_xxxx_xxxx_xxxx : CLZ_Result <= 6'd13;
32'b0000_0000_0000_001x_xxxx_xxxx_xxxx_xxxx : CLZ_Result <= 6'd14;
32'b0000_0000_0000_0001_xxxx_xxxx_xxxx_xxxx : CLZ_Result <= 6'd15;
32'b0000_0000_0000_0000_1xxx_xxxx_xxxx_xxxx : CLZ_Result <= 6'd16;
32'b0000_0000_0000_0000_01xx_xxxx_xxxx_xxxx : CLZ_Result <= 6'd17;
32'b0000_0000_0000_0000_001x_xxxx_xxxx_xxxx : CLZ_Result <= 6'd18;
32'b0000_0000_0000_0000_0001_xxxx_xxxx_xxxx : CLZ_Result <= 6'd19;
32'b0000_0000_0000_0000_0000_1xxx_xxxx_xxxx : CLZ_Result <= 6'd20;
32'b0000_0000_0000_0000_0000_01xx_xxxx_xxxx : CLZ_Result <= 6'd21;
32'b0000_0000_0000_0000_0000_001x_xxxx_xxxx : CLZ_Result <= 6'd22;
32'b0000_0000_0000_0000_0000_0001_xxxx_xxxx : CLZ_Result <= 6'd23;
32'b0000_0000_0000_0000_0000_0000_1xxx_xxxx : CLZ_Result <= 6'd24;
32'b0000_0000_0000_0000_0000_0000_01xx_xxxx : CLZ_Result <= 6'd25;
32'b0000_0000_0000_0000_0000_0000_001x_xxxx : CLZ_Result <= 6'd26;
32'b0000_0000_0000_0000_0000_0000_0001_xxxx : CLZ_Result <= 6'd27;
32'b0000_0000_0000_0000_0000_0000_0000_1xxx : CLZ_Result <= 6'd28;
32'b0000_0000_0000_0000_0000_0000_0000_01xx : CLZ_Result <= 6'd29;
32'b0000_0000_0000_0000_0000_0000_0000_001x : CLZ_Result <= 6'd30;
32'b0000_0000_0000_0000_0000_0000_0000_0001 : CLZ_Result <= 6'd31;
32'b0000_0000_0000_0000_0000_0000_0000_0000 : CLZ_Result <= 6'd32;
default : CLZ_Result <= 6'd0;
endcase
end
endmodule
AluOp_Sub : EXC_Ov <= ((A[31] ^ B[31]) & (A[31] ^ AddSub_Result[31]));
default : EXC_Ov <= 0;
endcase
end
// Count Leading Ones
always @(A) begin
casex (A)
32'b0xxx_xxxx_xxxx_xxxx_xxxx_xxxx_xxxx_xxxx : CLO_Result <= 6'd0;
32'b10xx_xxxx_xxxx_xxxx_xxxx_xxxx_xxxx_xxxx : CLO_Result <= 6'd1;
32'b110x_xxxx_xxxx_xxxx_xxxx_xxxx_xxxx_xxxx : CLO_Result <= 6'd2;
32'b1110_xxxx_xxxx_xxxx_xxxx_xxxx_xxxx_xxxx : CLO_Result <= 6'd3;
32'b1111_0xxx_xxxx_xxxx_xxxx_xxxx_xxxx_xxxx : CLO_Result <= 6'd4;
32'b1111_10xx_xxxx_xxxx_xxxx_xxxx_xxxx_xxxx : CLO_Result <= 6'd5;
32'b1111_110x_xxxx_xxxx_xxxx_xxxx_xxxx_xxxx : CLO_Result <= 6'd6;
32'b1111_1110_xxxx_xxxx_xxxx_xxxx_xxxx_xxxx : CLO_Result <= 6'd7;
32'b1111_1111_0xxx_xxxx_xxxx_xxxx_xxxx_xxxx : CLO_Result <= 6'd8;
32'b1111_1111_10xx_xxxx_xxxx_xxxx_xxxx_xxxx : CLO_Result <= 6'd9;
32'b1111_1111_110x_xxxx_xxxx_xxxx_xxxx_xxxx : CLO_Result <= 6'd10;
32'b1111_1111_1110_xxxx_xxxx_xxxx_xxxx_xxxx : CLO_Result <= 6'd11;
32'b1111_1111_1111_0xxx_xxxx_xxxx_xxxx_xxxx : CLO_Result <= 6'd12;
32'b1111_1111_1111_10xx_xxxx_xxxx_xxxx_xxxx : CLO_Result <= 6'd13;
32'b1111_1111_1111_110x_xxxx_xxxx_xxxx_xxxx : CLO_Result <= 6'd14;
32'b1111_1111_1111_1110_xxxx_xxxx_xxxx_xxxx : CLO_Result <= 6'd15;
32'b1111_1111_1111_1111_0xxx_xxxx_xxxx_xxxx : CLO_Result <= 6'd16;
32'b1111_1111_1111_1111_10xx_xxxx_xxxx_xxxx : CLO_Result <= 6'd17;
32'b1111_1111_1111_1111_110x_xxxx_xxxx_xxxx : CLO_Result <= 6'd18;
32'b1111_1111_1111_1111_1110_xxxx_xxxx_xxxx : CLO_Result <= 6'd19;
32'b1111_1111_1111_1111_1111_0xxx_xxxx_xxxx : CLO_Result <= 6'd20;
32'b1111_1111_1111_1111_1111_10xx_xxxx_xxxx : CLO_Result <= 6'd21;
32'b1111_1111_1111_1111_1111_110x_xxxx_xxxx : CLO_Result <= 6'd22;
32'b1111_1111_1111_1111_1111_1110_xxxx_xxxx : CLO_Result <= 6'd23;
32'b1111_1111_1111_1111_1111_1111_0xxx_xxxx : CLO_Result <= 6'd24;
32'b1111_1111_1111_1111_1111_1111_10xx_xxxx : CLO_Result <= 6'd25;
32'b1111_1111_1111_1111_1111_1111_110x_xxxx : CLO_Result <= 6'd26;
32'b1111_1111_1111_1111_1111_1111_1110_xxxx : CLO_Result <= 6'd27;
32'b1111_1111_1111_1111_1111_1111_1111_0xxx : CLO_Result <= 6'd28;
32'b1111_1111_1111_1111_1111_1111_1111_10xx : CLO_Result <= 6'd29;
32'b1111_1111_1111_1111_1111_1111_1111_110x : CLO_Result <= 6'd30;
32'b1111_1111_1111_1111_1111_1111_1111_1110 : CLO_Result <= 6'd31;
32'b1111_1111_1111_1111_1111_1111_1111_1111 : CLO_Result <= 6'd32;
default : CLO_Result <= 6'd0;
endcase
end
 
// Count Leading Zeros
always @(A) begin
casex (A)
32'b1xxx_xxxx_xxxx_xxxx_xxxx_xxxx_xxxx_xxxx : CLZ_Result <= 6'd0;
32'b01xx_xxxx_xxxx_xxxx_xxxx_xxxx_xxxx_xxxx : CLZ_Result <= 6'd1;
32'b001x_xxxx_xxxx_xxxx_xxxx_xxxx_xxxx_xxxx : CLZ_Result <= 6'd2;
32'b0001_xxxx_xxxx_xxxx_xxxx_xxxx_xxxx_xxxx : CLZ_Result <= 6'd3;
32'b0000_1xxx_xxxx_xxxx_xxxx_xxxx_xxxx_xxxx : CLZ_Result <= 6'd4;
32'b0000_01xx_xxxx_xxxx_xxxx_xxxx_xxxx_xxxx : CLZ_Result <= 6'd5;
32'b0000_001x_xxxx_xxxx_xxxx_xxxx_xxxx_xxxx : CLZ_Result <= 6'd6;
32'b0000_0001_xxxx_xxxx_xxxx_xxxx_xxxx_xxxx : CLZ_Result <= 6'd7;
32'b0000_0000_1xxx_xxxx_xxxx_xxxx_xxxx_xxxx : CLZ_Result <= 6'd8;
32'b0000_0000_01xx_xxxx_xxxx_xxxx_xxxx_xxxx : CLZ_Result <= 6'd9;
32'b0000_0000_001x_xxxx_xxxx_xxxx_xxxx_xxxx : CLZ_Result <= 6'd10;
32'b0000_0000_0001_xxxx_xxxx_xxxx_xxxx_xxxx : CLZ_Result <= 6'd11;
32'b0000_0000_0000_1xxx_xxxx_xxxx_xxxx_xxxx : CLZ_Result <= 6'd12;
32'b0000_0000_0000_01xx_xxxx_xxxx_xxxx_xxxx : CLZ_Result <= 6'd13;
32'b0000_0000_0000_001x_xxxx_xxxx_xxxx_xxxx : CLZ_Result <= 6'd14;
32'b0000_0000_0000_0001_xxxx_xxxx_xxxx_xxxx : CLZ_Result <= 6'd15;
32'b0000_0000_0000_0000_1xxx_xxxx_xxxx_xxxx : CLZ_Result <= 6'd16;
32'b0000_0000_0000_0000_01xx_xxxx_xxxx_xxxx : CLZ_Result <= 6'd17;
32'b0000_0000_0000_0000_001x_xxxx_xxxx_xxxx : CLZ_Result <= 6'd18;
32'b0000_0000_0000_0000_0001_xxxx_xxxx_xxxx : CLZ_Result <= 6'd19;
32'b0000_0000_0000_0000_0000_1xxx_xxxx_xxxx : CLZ_Result <= 6'd20;
32'b0000_0000_0000_0000_0000_01xx_xxxx_xxxx : CLZ_Result <= 6'd21;
32'b0000_0000_0000_0000_0000_001x_xxxx_xxxx : CLZ_Result <= 6'd22;
32'b0000_0000_0000_0000_0000_0001_xxxx_xxxx : CLZ_Result <= 6'd23;
32'b0000_0000_0000_0000_0000_0000_1xxx_xxxx : CLZ_Result <= 6'd24;
32'b0000_0000_0000_0000_0000_0000_01xx_xxxx : CLZ_Result <= 6'd25;
32'b0000_0000_0000_0000_0000_0000_001x_xxxx : CLZ_Result <= 6'd26;
32'b0000_0000_0000_0000_0000_0000_0001_xxxx : CLZ_Result <= 6'd27;
32'b0000_0000_0000_0000_0000_0000_0000_1xxx : CLZ_Result <= 6'd28;
32'b0000_0000_0000_0000_0000_0000_0000_01xx : CLZ_Result <= 6'd29;
32'b0000_0000_0000_0000_0000_0000_0000_001x : CLZ_Result <= 6'd30;
32'b0000_0000_0000_0000_0000_0000_0000_0001 : CLZ_Result <= 6'd31;
32'b0000_0000_0000_0000_0000_0000_0000_0000 : CLZ_Result <= 6'd32;
default : CLZ_Result <= 6'd0;
endcase
end
 
endmodule
 
/XUPV5-LX110T_SoC/MIPS32-Pipelined-Hw/src/MIPS32/Register.v
16,18 → 16,19
* value. Default is 32-bit width and 0s for initial value.
*/
module Register #(parameter WIDTH = 32, INIT = 0)(
input clock,
input reset,
input enable,
input [(WIDTH-1):0] D,
output reg [(WIDTH-1):0] Q
);
initial
Q = INIT;
input clock,
input reset,
input enable,
input [(WIDTH-1):0] D,
output reg [(WIDTH-1):0] Q
);
initial
Q = INIT;
 
always @(posedge clock) begin
Q <= (reset) ? INIT : ((enable) ? D : Q);
end
always @(posedge clock) begin
Q <= (reset) ? INIT : ((enable) ? D : Q);
end
 
endmodule
 
/XUPV5-LX110T_SoC/MIPS32-Pipelined-Hw/src/MIPS32/RegisterFile.v
54,5 → 54,5
assign ReadData1 = (ReadReg1 == 0) ? 32'h00000000 : registers[ReadReg1];
assign ReadData2 = (ReadReg2 == 0) ? 32'h00000000 : registers[ReadReg2];
 
endmodule
 
endmodule
/XUPV5-LX110T_SoC/MIPS32-Pipelined-Hw/src/MIPS32/Compare.v
20,21 → 20,22
* LEZ : A is less than or equal to zero
*/
module Compare(
input [31:0] A,
input [31:0] B,
output EQ,
output GZ,
output LZ,
output GEZ,
output LEZ
);
input [31:0] A,
input [31:0] B,
output EQ,
output GZ,
output LZ,
output GEZ,
output LEZ
);
 
wire ZeroA = (A == 32'b0);
wire ZeroA = (A == 32'b0);
 
assign EQ = ( A == B);
assign GZ = (~A[31] & ~ZeroA);
assign LZ = A[31];
assign GEZ = ~A[31];
assign LEZ = ( A[31] | ZeroA);
assign EQ = ( A == B);
assign GZ = (~A[31] & ~ZeroA);
assign LZ = A[31];
assign GEZ = ~A[31];
assign LEZ = ( A[31] | ZeroA);
endmodule
 
/XUPV5-LX110T_SoC/MIPS32-Pipelined-Hw/src/MIPS32/Add.v
15,11 → 15,12
* A simple 32-bit 2-input adder.
*/
module Add(
input [31:0] A,
input [31:0] B,
output [31:0] C
);
assign C = (A + B);
input [31:0] A,
input [31:0] B,
output [31:0] C
);
assign C = (A + B);
 
endmodule
 
/XUPV5-LX110T_SoC/MIPS32-Pipelined-Hw/src/MIPS32/MEMWB_Stage.v
16,27 → 16,27
* The Pipeline Register to bridge the Memory and Writeback stages.
*/
module MEMWB_Stage(
input clock,
input reset,
input clock,
input reset,
input M_Flush,
input M_Stall,
input WB_Stall,
// Control Signals
input M_RegWrite,
input M_MemtoReg,
// Data Signals
input [31:0] M_ReadData,
input [31:0] M_ALU_Result,
input [4:0] M_RtRd,
// ----------------
output reg WB_RegWrite,
output reg WB_MemtoReg,
output reg [31:0] WB_ReadData,
output reg [31:0] WB_ALU_Result,
output reg [4:0] WB_RtRd
);
input WB_Stall,
// Control Signals
input M_RegWrite,
input M_MemtoReg,
// Data Signals
input [31:0] M_ReadData,
input [31:0] M_ALU_Result,
input [4:0] M_RtRd,
// ----------------
output reg WB_RegWrite,
output reg WB_MemtoReg,
output reg [31:0] WB_ReadData,
output reg [31:0] WB_ALU_Result,
output reg [4:0] WB_RtRd
);
/***
The purpose of a pipeline register is to capture data from one pipeline stage
and provide it to the next pipeline stage. This creates at least one clock cycle
71,3 → 71,4
end
 
endmodule
 
/XUPV5-LX110T_SoC/MIPS32-Pipelined-Hw/src/MIPS32/MIPS_Parameters.v
1,331 → 1,331
/*
* File : MIPS_Parameters.v
* Project : University of Utah, XUM Project MIPS32 core
* Creator(s) : Grant Ayers (ayers@cs.utah.edu)
*
* Modification History:
* Rev Date Initials Description of Change
* 1.0 26-May-2012 GEA Release version.
*
* Standards/Formatting:
* Verilog 2001, 4 soft tab, wide column.
*
* Description:
* Provides a language abstraction for the MIPS32-specific op-codes and
* the processor-specific datapath, hazard, and exception bits which
* control the processor. These parameter names are used extensively
* throughout the processor HDL modules.
*/
 
 
/*** Exception Vector Locations ***
When the CPU powers up or is reset, it will begin execution at 'EXC_Vector_Base_Reset'.
All other exceptions are the sum of a base address and offset:
- The base address is either a bootstrap or normal value. It is controlled by
the 'BEV' bit in the CP0 'Status' register. Both base addresses can be mapped to
the same location.
- The offset address is either a standard offset (which is always used for
non-interrupt general exceptions in this processor because it lacks TLB Refill
and Cache errors), or a special interrupt-only offset for interrupts, which is
enabled with the 'IV' bit in the CP0 'Cause' register.
Current Setup:
General exceptions go to 0x0. Interrupts go to 0x8. Booting starts at 0x10.
*/
parameter [31:0] EXC_Vector_Base_Reset = 32'h0000_0010; // MIPS Standard is 0xBFC0_0000
parameter [31:0] EXC_Vector_Base_Other_NoBoot = 32'h0000_0000; // MIPS Standard is 0x8000_0000
parameter [31:0] EXC_Vector_Base_Other_Boot = 32'h0000_0000; // MIPS Standard is 0xBFC0_0200
parameter [31:0] EXC_Vector_Offset_General = 32'h0000_0000; // MIPS Standard is 0x0000_0180
parameter [31:0] EXC_Vector_Offset_Special = 32'h0000_0008; // MIPS Standard is 0x0000_0200
 
 
 
/*** Kernel/User Memory Areas ***
 
Kernel memory starts at address 0x0. User memory starts at 'UMem_Lower' and extends to
the end of the address space.
A distinction is made to protect against accesses to kernel memory while the processor
is in user mode. Lacking MMU hardware, these addresses are physical, not virtual.
This simple two-part division of the address space can be extended almost arbitrarily
in the Data Memory Controller. Note that there is currently no user/kernel space check
for the Instruction Memory, because it is assumed that instructions are in the kernel space.
*/
parameter [31:0] UMem_Lower = 32'h08000000;
 
 
 
/*** Processor Endianness ***
 
MIPS32 allows user-mode addresses to be configured as big- or little-endian. For simplicity
reasons, this processor fixes the endianness to little endian. To add support for both
modes, the Data Memory Controller should be updated as well as CP0, which should change
the 'RE' bit in the Status register from a wire to a writable register.
*/
parameter Big_Endian = 0;
 
 
 
/*** Encodings for MIPS32 Release 1 Architecture ***/
 
 
/* Op Code Categories */
parameter [5:0] Op_Type_R = 6'b00_0000; // Standard R-Type instructions
parameter [5:0] Op_Type_R2 = 6'b01_1100; // Extended R-Like instructions
parameter [5:0] Op_Type_BI = 6'b00_0001; // Branch/Trap extended instructions
parameter [5:0] Op_Type_CP0 = 6'b01_0000; // Coprocessor 0 instructions
parameter [5:0] Op_Type_CP1 = 6'b01_0001; // Coprocessor 1 instructions (not implemented)
parameter [5:0] Op_Type_CP2 = 6'b01_0010; // Coprocessor 2 instructions (not implemented)
parameter [5:0] Op_Type_CP3 = 6'b01_0011; // Coprocessor 3 instructions (not implemented)
// --------------------------------------
parameter [5:0] Op_Add = Op_Type_R;
parameter [5:0] Op_Addi = 6'b00_1000;
parameter [5:0] Op_Addiu = 6'b00_1001;
parameter [5:0] Op_Addu = Op_Type_R;
parameter [5:0] Op_And = Op_Type_R;
parameter [5:0] Op_Andi = 6'b00_1100;
parameter [5:0] Op_Beq = 6'b00_0100;
parameter [5:0] Op_Bgez = Op_Type_BI;
parameter [5:0] Op_Bgezal = Op_Type_BI;
parameter [5:0] Op_Bgtz = 6'b00_0111;
parameter [5:0] Op_Blez = 6'b00_0110;
parameter [5:0] Op_Bltz = Op_Type_BI;
parameter [5:0] Op_Bltzal = Op_Type_BI;
parameter [5:0] Op_Bne = 6'b00_0101;
parameter [5:0] Op_Break = Op_Type_R;
parameter [5:0] Op_Clo = Op_Type_R2;
parameter [5:0] Op_Clz = Op_Type_R2;
parameter [5:0] Op_Div = Op_Type_R;
parameter [5:0] Op_Divu = Op_Type_R;
parameter [5:0] Op_Eret = Op_Type_CP0;
parameter [5:0] Op_J = 6'b00_0010;
parameter [5:0] Op_Jal = 6'b00_0011;
parameter [5:0] Op_Jalr = Op_Type_R;
parameter [5:0] Op_Jr = Op_Type_R;
parameter [5:0] Op_Lb = 6'b10_0000;
parameter [5:0] Op_Lbu = 6'b10_0100;
parameter [5:0] Op_Lh = 6'b10_0001;
parameter [5:0] Op_Lhu = 6'b10_0101;
parameter [5:0] Op_Ll = 6'b11_0000;
parameter [5:0] Op_Lui = 6'b00_1111;
parameter [5:0] Op_Lw = 6'b10_0011;
parameter [5:0] Op_Lwl = 6'b10_0010;
parameter [5:0] Op_Lwr = 6'b10_0110;
parameter [5:0] Op_Madd = Op_Type_R2;
parameter [5:0] Op_Maddu = Op_Type_R2;
parameter [5:0] Op_Mfc0 = Op_Type_CP0;
parameter [5:0] Op_Mfhi = Op_Type_R;
parameter [5:0] Op_Mflo = Op_Type_R;
parameter [5:0] Op_Movn = Op_Type_R;
parameter [5:0] Op_Movz = Op_Type_R;
parameter [5:0] Op_Msub = Op_Type_R2;
parameter [5:0] Op_Msubu = Op_Type_R2;
parameter [5:0] Op_Mtc0 = Op_Type_CP0;
parameter [5:0] Op_Mthi = Op_Type_R;
parameter [5:0] Op_Mtlo = Op_Type_R;
parameter [5:0] Op_Mul = Op_Type_R2;
parameter [5:0] Op_Mult = Op_Type_R;
parameter [5:0] Op_Multu = Op_Type_R;
parameter [5:0] Op_Nor = Op_Type_R;
parameter [5:0] Op_Or = Op_Type_R;
parameter [5:0] Op_Ori = 6'b00_1101;
parameter [5:0] Op_Pref = 6'b11_0011; // Prefetch does nothing in this implementation.
parameter [5:0] Op_Sb = 6'b10_1000;
parameter [5:0] Op_Sc = 6'b11_1000;
parameter [5:0] Op_Sh = 6'b10_1001;
parameter [5:0] Op_Sll = Op_Type_R;
parameter [5:0] Op_Sllv = Op_Type_R;
parameter [5:0] Op_Slt = Op_Type_R;
parameter [5:0] Op_Slti = 6'b00_1010;
parameter [5:0] Op_Sltiu = 6'b00_1011;
parameter [5:0] Op_Sltu = Op_Type_R;
parameter [5:0] Op_Sra = Op_Type_R;
parameter [5:0] Op_Srav = Op_Type_R;
parameter [5:0] Op_Srl = Op_Type_R;
parameter [5:0] Op_Srlv = Op_Type_R;
parameter [5:0] Op_Sub = Op_Type_R;
parameter [5:0] Op_Subu = Op_Type_R;
parameter [5:0] Op_Sw = 6'b10_1011;
parameter [5:0] Op_Swl = 6'b10_1010;
parameter [5:0] Op_Swr = 6'b10_1110;
parameter [5:0] Op_Syscall = Op_Type_R;
parameter [5:0] Op_Teq = Op_Type_R;
parameter [5:0] Op_Teqi = Op_Type_BI;
parameter [5:0] Op_Tge = Op_Type_R;
parameter [5:0] Op_Tgei = Op_Type_BI;
parameter [5:0] Op_Tgeiu = Op_Type_BI;
parameter [5:0] Op_Tgeu = Op_Type_R;
parameter [5:0] Op_Tlt = Op_Type_R;
parameter [5:0] Op_Tlti = Op_Type_BI;
parameter [5:0] Op_Tltiu = Op_Type_BI;
parameter [5:0] Op_Tltu = Op_Type_R;
parameter [5:0] Op_Tne = Op_Type_R;
parameter [5:0] Op_Tnei = Op_Type_BI;
parameter [5:0] Op_Xor = Op_Type_R;
parameter [5:0] Op_Xori = 6'b00_1110;
 
/* Op Code Rt fields for Branches & Traps */
parameter [4:0] OpRt_Bgez = 5'b00001;
parameter [4:0] OpRt_Bgezal = 5'b10001;
parameter [4:0] OpRt_Bltz = 5'b00000;
parameter [4:0] OpRt_Bltzal = 5'b10000;
parameter [4:0] OpRt_Teqi = 5'b01100;
parameter [4:0] OpRt_Tgei = 5'b01000;
parameter [4:0] OpRt_Tgeiu = 5'b01001;
parameter [4:0] OpRt_Tlti = 5'b01010;
parameter [4:0] OpRt_Tltiu = 5'b01011;
parameter [4:0] OpRt_Tnei = 5'b01110;
 
/* Op Code Rs fields for Coprocessors */
parameter [4:0] OpRs_MF = 5'b00000;
parameter [4:0] OpRs_MT = 5'b00100;
 
/* Special handling for ERET */
parameter [4:0] OpRs_ERET = 5'b10000;
parameter [5:0] Funct_ERET = 6'b011000;
 
/* Function Codes for R-Type Op Codes */
parameter [5:0] Funct_Add = 6'b10_0000;
parameter [5:0] Funct_Addu = 6'b10_0001;
parameter [5:0] Funct_And = 6'b10_0100;
parameter [5:0] Funct_Break = 6'b00_1101;
parameter [5:0] Funct_Clo = 6'b10_0001; // same as Addu
parameter [5:0] Funct_Clz = 6'b10_0000; // same as Add
parameter [5:0] Funct_Div = 6'b01_1010;
parameter [5:0] Funct_Divu = 6'b01_1011;
parameter [5:0] Funct_Jr = 6'b00_1000;
parameter [5:0] Funct_Jalr = 6'b00_1001;
parameter [5:0] Funct_Madd = 6'b00_0000;
parameter [5:0] Funct_Maddu = 6'b00_0001;
parameter [5:0] Funct_Mfhi = 6'b01_0000;
parameter [5:0] Funct_Mflo = 6'b01_0010;
parameter [5:0] Funct_Movn = 6'b00_1011;
parameter [5:0] Funct_Movz = 6'b00_1010;
parameter [5:0] Funct_Msub = 6'b00_0100; // same as Sllv
parameter [5:0] Funct_Msubu = 6'b00_0101;
parameter [5:0] Funct_Mthi = 6'b01_0001;
parameter [5:0] Funct_Mtlo = 6'b01_0011;
parameter [5:0] Funct_Mul = 6'b00_0010; // same as Srl
parameter [5:0] Funct_Mult = 6'b01_1000;
parameter [5:0] Funct_Multu = 6'b01_1001;
parameter [5:0] Funct_Nor = 6'b10_0111;
parameter [5:0] Funct_Or = 6'b10_0101;
parameter [5:0] Funct_Sll = 6'b00_0000;
parameter [5:0] Funct_Sllv = 6'b00_0100;
parameter [5:0] Funct_Slt = 6'b10_1010;
parameter [5:0] Funct_Sltu = 6'b10_1011;
parameter [5:0] Funct_Sra = 6'b00_0011;
parameter [5:0] Funct_Srav = 6'b00_0111;
parameter [5:0] Funct_Srl = 6'b00_0010;
parameter [5:0] Funct_Srlv = 6'b00_0110;
parameter [5:0] Funct_Sub = 6'b10_0010;
parameter [5:0] Funct_Subu = 6'b10_0011;
parameter [5:0] Funct_Syscall = 6'b00_1100;
parameter [5:0] Funct_Teq = 6'b11_0100;
parameter [5:0] Funct_Tge = 6'b11_0000;
parameter [5:0] Funct_Tgeu = 6'b11_0001;
parameter [5:0] Funct_Tlt = 6'b11_0010;
parameter [5:0] Funct_Tltu = 6'b11_0011;
parameter [5:0] Funct_Tne = 6'b11_0110;
parameter [5:0] Funct_Xor = 6'b10_0110;
 
/* ALU Operations (Implementation) */
parameter [4:0] AluOp_Add = 5'd1;
parameter [4:0] AluOp_Addu = 5'd0;
parameter [4:0] AluOp_And = 5'd2;
parameter [4:0] AluOp_Clo = 5'd3;
parameter [4:0] AluOp_Clz = 5'd4;
parameter [4:0] AluOp_Div = 5'd5;
parameter [4:0] AluOp_Divu = 5'd6;
parameter [4:0] AluOp_Madd = 5'd7;
parameter [4:0] AluOp_Maddu = 5'd8;
parameter [4:0] AluOp_Mfhi = 5'd9;
parameter [4:0] AluOp_Mflo = 5'd10;
parameter [4:0] AluOp_Msub = 5'd13;
parameter [4:0] AluOp_Msubu = 5'd14;
parameter [4:0] AluOp_Mthi = 5'd11;
parameter [4:0] AluOp_Mtlo = 5'd12;
parameter [4:0] AluOp_Mul = 5'd15;
parameter [4:0] AluOp_Mult = 5'd16;
parameter [4:0] AluOp_Multu = 5'd17;
parameter [4:0] AluOp_Nor = 5'd18;
parameter [4:0] AluOp_Or = 5'd19;
parameter [4:0] AluOp_Sll = 5'd20;
parameter [4:0] AluOp_Sllc = 5'd21; // Move this if another AluOp is needed
parameter [4:0] AluOp_Sllv = 5'd22;
parameter [4:0] AluOp_Slt = 5'd23;
parameter [4:0] AluOp_Sltu = 5'd24;
parameter [4:0] AluOp_Sra = 5'd25;
parameter [4:0] AluOp_Srav = 5'd26;
parameter [4:0] AluOp_Srl = 5'd27;
parameter [4:0] AluOp_Srlv = 5'd28;
parameter [4:0] AluOp_Sub = 5'd29;
parameter [4:0] AluOp_Subu = 5'd30;
parameter [4:0] AluOp_Xor = 5'd31;
 
 
// Movc:10->11, Trap:9->10, TrapCond:8->9, RegDst:7->8
/*** Datapath ***
 
All Signals are Active High. Branching and Jump signals (determined by "PCSrc"),
as well as ALU operation signals ("ALUOp") are handled by the controller and are not found here.
 
Bit Name Description
------------------------------
15: PCSrc (Instruction Type)
14: 11: Instruction is Jump to Register
10: Instruction is Branch
01: Instruction is Jump to Immediate
00: Instruction does not branch nor jump
13: Link (Link on Branch/Jump)
------------------------------
12: ALUSrc (ALU Source) [0=ALU input B is 2nd register file output; 1=Immediate value]
11: Movc (Conditional Move)
10: Trap (Trap Instruction)
9 : TrapCond (Trap Condition) [0=ALU result is 0; 1=ALU result is not 0]
8 : RegDst (Register File Target) [0=Rt field; 1=Rd field]
------------------------------
7 : LLSC (Load Linked or Store Conditional)
6 : MemRead (Data Memory Read)
5 : MemWrite (Data Memory Write)
4 : MemHalf (Half Word Memory Access)
3 : MemByte (Byte size Memory Access)
2 : MemSignExtend (Sign Extend Read Memory) [0=Zero Extend; 1=Sign Extend]
------------------------------
1 : RegWrite (Register File Write)
0 : MemtoReg (Memory to Register) [0=Register File write data is ALU output; 1=Is Data Memory]
------------------------------
*/
parameter [15:0] DP_None = 16'b000_00000_000000_00; // Instructions which require nothing of the main datapath.
parameter [15:0] DP_RType = 16'b000_00001_000000_10; // Standard R-Type
parameter [15:0] DP_IType = 16'b000_10000_000000_10; // Standard I-Type
parameter [15:0] DP_Branch = 16'b100_00000_000000_00; // Standard Branch
parameter [15:0] DP_BranchLink = 16'b101_00000_000000_10; // Branch and Link
parameter [15:0] DP_HiLoWr = 16'b000_00000_000000_00; // Write to Hi/Lo ALU register (Div,Divu,Mult,Multu,Mthi,Mtlo). Currently 'DP_None'.
parameter [15:0] DP_Jump = 16'b010_00000_000000_00; // Standard Jump
parameter [15:0] DP_JumpLink = 16'b011_00000_000000_10; // Jump and Link
parameter [15:0] DP_JumpLinkReg = 16'b111_00000_000000_10; // Jump and Link Register
parameter [15:0] DP_JumpReg = 16'b110_00000_000000_00; // Jump Register
parameter [15:0] DP_LoadByteS = 16'b000_10000_010011_11; // Load Byte Signed
parameter [15:0] DP_LoadByteU = 16'b000_10000_010010_11; // Load Byte Unsigned
parameter [15:0] DP_LoadHalfS = 16'b000_10000_010101_11; // Load Half Signed
parameter [15:0] DP_LoadHalfU = 16'b000_10000_010100_11; // Load Half Unsigned
parameter [15:0] DP_LoadWord = 16'b000_10000_010000_11; // Load Word
parameter [15:0] DP_ExtWrRt = 16'b000_00000_000000_10; // A DP-external write to Rt
parameter [15:0] DP_ExtWrRd = 16'b000_00001_000000_10; // A DP-external write to Rd
parameter [15:0] DP_Movc = 16'b000_01001_000000_10; // Conditional Move
parameter [15:0] DP_LoadLinked = 16'b000_10000_110000_11; // Load Linked
parameter [15:0] DP_StoreCond = 16'b000_10000_101000_11; // Store Conditional
parameter [15:0] DP_StoreByte = 16'b000_10000_001010_00; // Store Byte
parameter [15:0] DP_StoreHalf = 16'b000_10000_001100_00; // Store Half
parameter [15:0] DP_StoreWord = 16'b000_10000_001000_00; // Store Word
parameter [15:0] DP_TrapRegCNZ = 16'b000_00110_000000_00; // Trap using Rs and Rt, non-zero ALU (Tlt, Tltu, Tne)
parameter [15:0] DP_TrapRegCZ = 16'b000_00100_000000_00; // Trap using RS and Rt, zero ALU (Teq, Tge, Tgeu)
parameter [15:0] DP_TrapImmCNZ = 16'b000_10110_000000_00; // Trap using Rs and Imm, non-zero ALU (Tlti, Tltiu, Tnei)
parameter [15:0] DP_TrapImmCZ = 16'b000_10100_000000_00; // Trap using Rs and Imm, zero ALU (Teqi, Tgei, Tgeiu)
//--------------------------------------------------------
/*
* File : MIPS_Parameters.v
* Project : University of Utah, XUM Project MIPS32 core
* Creator(s) : Grant Ayers (ayers@cs.utah.edu)
*
* Modification History:
* Rev Date Initials Description of Change
* 1.0 26-May-2012 GEA Release version.
*
* Standards/Formatting:
* Verilog 2001, 4 soft tab, wide column.
*
* Description:
* Provides a language abstraction for the MIPS32-specific op-codes and
* the processor-specific datapath, hazard, and exception bits which
* control the processor. These parameter names are used extensively
* throughout the processor HDL modules.
*/
 
 
/*** Exception Vector Locations ***
When the CPU powers up or is reset, it will begin execution at 'EXC_Vector_Base_Reset'.
All other exceptions are the sum of a base address and offset:
- The base address is either a bootstrap or normal value. It is controlled by
the 'BEV' bit in the CP0 'Status' register. Both base addresses can be mapped to
the same location.
- The offset address is either a standard offset (which is always used for
non-interrupt general exceptions in this processor because it lacks TLB Refill
and Cache errors), or a special interrupt-only offset for interrupts, which is
enabled with the 'IV' bit in the CP0 'Cause' register.
Current Setup:
General exceptions go to 0x0. Interrupts go to 0x8. Booting starts at 0x10.
*/
parameter [31:0] EXC_Vector_Base_Reset = 32'h0000_0010; // MIPS Standard is 0xBFC0_0000
parameter [31:0] EXC_Vector_Base_Other_NoBoot = 32'h0000_0000; // MIPS Standard is 0x8000_0000
parameter [31:0] EXC_Vector_Base_Other_Boot = 32'h0000_0000; // MIPS Standard is 0xBFC0_0200
parameter [31:0] EXC_Vector_Offset_General = 32'h0000_0000; // MIPS Standard is 0x0000_0180
parameter [31:0] EXC_Vector_Offset_Special = 32'h0000_0008; // MIPS Standard is 0x0000_0200
 
 
 
/*** Kernel/User Memory Areas ***
 
Kernel memory starts at address 0x0. User memory starts at 'UMem_Lower' and extends to
the end of the address space.
A distinction is made to protect against accesses to kernel memory while the processor
is in user mode. Lacking MMU hardware, these addresses are physical, not virtual.
This simple two-part division of the address space can be extended almost arbitrarily
in the Data Memory Controller. Note that there is currently no user/kernel space check
for the Instruction Memory, because it is assumed that instructions are in the kernel space.
*/
parameter [31:0] UMem_Lower = 32'h08000000;
 
 
 
/*** Processor Endianness ***
 
MIPS32 allows user-mode addresses to be configured as big- or little-endian. For simplicity
reasons, this processor fixes the endianness to little endian. To add support for both
modes, the Data Memory Controller should be updated as well as CP0, which should change
the 'RE' bit in the Status register from a wire to a writable register.
*/
parameter Big_Endian = 0;
 
 
 
/*** Encodings for MIPS32 Release 1 Architecture ***/
 
 
/* Op Code Categories */
parameter [5:0] Op_Type_R = 6'b00_0000; // Standard R-Type instructions
parameter [5:0] Op_Type_R2 = 6'b01_1100; // Extended R-Like instructions
parameter [5:0] Op_Type_BI = 6'b00_0001; // Branch/Trap extended instructions
parameter [5:0] Op_Type_CP0 = 6'b01_0000; // Coprocessor 0 instructions
parameter [5:0] Op_Type_CP1 = 6'b01_0001; // Coprocessor 1 instructions (not implemented)
parameter [5:0] Op_Type_CP2 = 6'b01_0010; // Coprocessor 2 instructions (not implemented)
parameter [5:0] Op_Type_CP3 = 6'b01_0011; // Coprocessor 3 instructions (not implemented)
// --------------------------------------
parameter [5:0] Op_Add = Op_Type_R;
parameter [5:0] Op_Addi = 6'b00_1000;
parameter [5:0] Op_Addiu = 6'b00_1001;
parameter [5:0] Op_Addu = Op_Type_R;
parameter [5:0] Op_And = Op_Type_R;
parameter [5:0] Op_Andi = 6'b00_1100;
parameter [5:0] Op_Beq = 6'b00_0100;
parameter [5:0] Op_Bgez = Op_Type_BI;
parameter [5:0] Op_Bgezal = Op_Type_BI;
parameter [5:0] Op_Bgtz = 6'b00_0111;
parameter [5:0] Op_Blez = 6'b00_0110;
parameter [5:0] Op_Bltz = Op_Type_BI;
parameter [5:0] Op_Bltzal = Op_Type_BI;
parameter [5:0] Op_Bne = 6'b00_0101;
parameter [5:0] Op_Break = Op_Type_R;
parameter [5:0] Op_Clo = Op_Type_R2;
parameter [5:0] Op_Clz = Op_Type_R2;
parameter [5:0] Op_Div = Op_Type_R;
parameter [5:0] Op_Divu = Op_Type_R;
parameter [5:0] Op_Eret = Op_Type_CP0;
parameter [5:0] Op_J = 6'b00_0010;
parameter [5:0] Op_Jal = 6'b00_0011;
parameter [5:0] Op_Jalr = Op_Type_R;
parameter [5:0] Op_Jr = Op_Type_R;
parameter [5:0] Op_Lb = 6'b10_0000;
parameter [5:0] Op_Lbu = 6'b10_0100;
parameter [5:0] Op_Lh = 6'b10_0001;
parameter [5:0] Op_Lhu = 6'b10_0101;
parameter [5:0] Op_Ll = 6'b11_0000;
parameter [5:0] Op_Lui = 6'b00_1111;
parameter [5:0] Op_Lw = 6'b10_0011;
parameter [5:0] Op_Lwl = 6'b10_0010;
parameter [5:0] Op_Lwr = 6'b10_0110;
parameter [5:0] Op_Madd = Op_Type_R2;
parameter [5:0] Op_Maddu = Op_Type_R2;
parameter [5:0] Op_Mfc0 = Op_Type_CP0;
parameter [5:0] Op_Mfhi = Op_Type_R;
parameter [5:0] Op_Mflo = Op_Type_R;
parameter [5:0] Op_Movn = Op_Type_R;
parameter [5:0] Op_Movz = Op_Type_R;
parameter [5:0] Op_Msub = Op_Type_R2;
parameter [5:0] Op_Msubu = Op_Type_R2;
parameter [5:0] Op_Mtc0 = Op_Type_CP0;
parameter [5:0] Op_Mthi = Op_Type_R;
parameter [5:0] Op_Mtlo = Op_Type_R;
parameter [5:0] Op_Mul = Op_Type_R2;
parameter [5:0] Op_Mult = Op_Type_R;
parameter [5:0] Op_Multu = Op_Type_R;
parameter [5:0] Op_Nor = Op_Type_R;
parameter [5:0] Op_Or = Op_Type_R;
parameter [5:0] Op_Ori = 6'b00_1101;
parameter [5:0] Op_Pref = 6'b11_0011; // Prefetch does nothing in this implementation.
parameter [5:0] Op_Sb = 6'b10_1000;
parameter [5:0] Op_Sc = 6'b11_1000;
parameter [5:0] Op_Sh = 6'b10_1001;
parameter [5:0] Op_Sll = Op_Type_R;
parameter [5:0] Op_Sllv = Op_Type_R;
parameter [5:0] Op_Slt = Op_Type_R;
parameter [5:0] Op_Slti = 6'b00_1010;
parameter [5:0] Op_Sltiu = 6'b00_1011;
parameter [5:0] Op_Sltu = Op_Type_R;
parameter [5:0] Op_Sra = Op_Type_R;
parameter [5:0] Op_Srav = Op_Type_R;
parameter [5:0] Op_Srl = Op_Type_R;
parameter [5:0] Op_Srlv = Op_Type_R;
parameter [5:0] Op_Sub = Op_Type_R;
parameter [5:0] Op_Subu = Op_Type_R;
parameter [5:0] Op_Sw = 6'b10_1011;
parameter [5:0] Op_Swl = 6'b10_1010;
parameter [5:0] Op_Swr = 6'b10_1110;
parameter [5:0] Op_Syscall = Op_Type_R;
parameter [5:0] Op_Teq = Op_Type_R;
parameter [5:0] Op_Teqi = Op_Type_BI;
parameter [5:0] Op_Tge = Op_Type_R;
parameter [5:0] Op_Tgei = Op_Type_BI;
parameter [5:0] Op_Tgeiu = Op_Type_BI;
parameter [5:0] Op_Tgeu = Op_Type_R;
parameter [5:0] Op_Tlt = Op_Type_R;
parameter [5:0] Op_Tlti = Op_Type_BI;
parameter [5:0] Op_Tltiu = Op_Type_BI;
parameter [5:0] Op_Tltu = Op_Type_R;
parameter [5:0] Op_Tne = Op_Type_R;
parameter [5:0] Op_Tnei = Op_Type_BI;
parameter [5:0] Op_Xor = Op_Type_R;
parameter [5:0] Op_Xori = 6'b00_1110;
 
/* Op Code Rt fields for Branches & Traps */
parameter [4:0] OpRt_Bgez = 5'b00001;
parameter [4:0] OpRt_Bgezal = 5'b10001;
parameter [4:0] OpRt_Bltz = 5'b00000;
parameter [4:0] OpRt_Bltzal = 5'b10000;
parameter [4:0] OpRt_Teqi = 5'b01100;
parameter [4:0] OpRt_Tgei = 5'b01000;
parameter [4:0] OpRt_Tgeiu = 5'b01001;
parameter [4:0] OpRt_Tlti = 5'b01010;
parameter [4:0] OpRt_Tltiu = 5'b01011;
parameter [4:0] OpRt_Tnei = 5'b01110;
 
/* Op Code Rs fields for Coprocessors */
parameter [4:0] OpRs_MF = 5'b00000;
parameter [4:0] OpRs_MT = 5'b00100;
 
/* Special handling for ERET */
parameter [4:0] OpRs_ERET = 5'b10000;
parameter [5:0] Funct_ERET = 6'b011000;
 
/* Function Codes for R-Type Op Codes */
parameter [5:0] Funct_Add = 6'b10_0000;
parameter [5:0] Funct_Addu = 6'b10_0001;
parameter [5:0] Funct_And = 6'b10_0100;
parameter [5:0] Funct_Break = 6'b00_1101;
parameter [5:0] Funct_Clo = 6'b10_0001; // same as Addu
parameter [5:0] Funct_Clz = 6'b10_0000; // same as Add
parameter [5:0] Funct_Div = 6'b01_1010;
parameter [5:0] Funct_Divu = 6'b01_1011;
parameter [5:0] Funct_Jr = 6'b00_1000;
parameter [5:0] Funct_Jalr = 6'b00_1001;
parameter [5:0] Funct_Madd = 6'b00_0000;
parameter [5:0] Funct_Maddu = 6'b00_0001;
parameter [5:0] Funct_Mfhi = 6'b01_0000;
parameter [5:0] Funct_Mflo = 6'b01_0010;
parameter [5:0] Funct_Movn = 6'b00_1011;
parameter [5:0] Funct_Movz = 6'b00_1010;
parameter [5:0] Funct_Msub = 6'b00_0100; // same as Sllv
parameter [5:0] Funct_Msubu = 6'b00_0101;
parameter [5:0] Funct_Mthi = 6'b01_0001;
parameter [5:0] Funct_Mtlo = 6'b01_0011;
parameter [5:0] Funct_Mul = 6'b00_0010; // same as Srl
parameter [5:0] Funct_Mult = 6'b01_1000;
parameter [5:0] Funct_Multu = 6'b01_1001;
parameter [5:0] Funct_Nor = 6'b10_0111;
parameter [5:0] Funct_Or = 6'b10_0101;
parameter [5:0] Funct_Sll = 6'b00_0000;
parameter [5:0] Funct_Sllv = 6'b00_0100;
parameter [5:0] Funct_Slt = 6'b10_1010;
parameter [5:0] Funct_Sltu = 6'b10_1011;
parameter [5:0] Funct_Sra = 6'b00_0011;
parameter [5:0] Funct_Srav = 6'b00_0111;
parameter [5:0] Funct_Srl = 6'b00_0010;
parameter [5:0] Funct_Srlv = 6'b00_0110;
parameter [5:0] Funct_Sub = 6'b10_0010;
parameter [5:0] Funct_Subu = 6'b10_0011;
parameter [5:0] Funct_Syscall = 6'b00_1100;
parameter [5:0] Funct_Teq = 6'b11_0100;
parameter [5:0] Funct_Tge = 6'b11_0000;
parameter [5:0] Funct_Tgeu = 6'b11_0001;
parameter [5:0] Funct_Tlt = 6'b11_0010;
parameter [5:0] Funct_Tltu = 6'b11_0011;
parameter [5:0] Funct_Tne = 6'b11_0110;
parameter [5:0] Funct_Xor = 6'b10_0110;
 
/* ALU Operations (Implementation) */
parameter [4:0] AluOp_Add = 5'd1;
parameter [4:0] AluOp_Addu = 5'd0;
parameter [4:0] AluOp_And = 5'd2;
parameter [4:0] AluOp_Clo = 5'd3;
parameter [4:0] AluOp_Clz = 5'd4;
parameter [4:0] AluOp_Div = 5'd5;
parameter [4:0] AluOp_Divu = 5'd6;
parameter [4:0] AluOp_Madd = 5'd7;
parameter [4:0] AluOp_Maddu = 5'd8;
parameter [4:0] AluOp_Mfhi = 5'd9;
parameter [4:0] AluOp_Mflo = 5'd10;
parameter [4:0] AluOp_Msub = 5'd13;
parameter [4:0] AluOp_Msubu = 5'd14;
parameter [4:0] AluOp_Mthi = 5'd11;
parameter [4:0] AluOp_Mtlo = 5'd12;
parameter [4:0] AluOp_Mul = 5'd15;
parameter [4:0] AluOp_Mult = 5'd16;
parameter [4:0] AluOp_Multu = 5'd17;
parameter [4:0] AluOp_Nor = 5'd18;
parameter [4:0] AluOp_Or = 5'd19;
parameter [4:0] AluOp_Sll = 5'd20;
parameter [4:0] AluOp_Sllc = 5'd21; // Move this if another AluOp is needed
parameter [4:0] AluOp_Sllv = 5'd22;
parameter [4:0] AluOp_Slt = 5'd23;
parameter [4:0] AluOp_Sltu = 5'd24;
parameter [4:0] AluOp_Sra = 5'd25;
parameter [4:0] AluOp_Srav = 5'd26;
parameter [4:0] AluOp_Srl = 5'd27;
parameter [4:0] AluOp_Srlv = 5'd28;
parameter [4:0] AluOp_Sub = 5'd29;
parameter [4:0] AluOp_Subu = 5'd30;
parameter [4:0] AluOp_Xor = 5'd31;
 
 
// Movc:10->11, Trap:9->10, TrapCond:8->9, RegDst:7->8
/*** Datapath ***
 
All Signals are Active High. Branching and Jump signals (determined by "PCSrc"),
as well as ALU operation signals ("ALUOp") are handled by the controller and are not found here.
 
Bit Name Description
------------------------------
15: PCSrc (Instruction Type)
14: 11: Instruction is Jump to Register
10: Instruction is Branch
01: Instruction is Jump to Immediate
00: Instruction does not branch nor jump
13: Link (Link on Branch/Jump)
------------------------------
12: ALUSrc (ALU Source) [0=ALU input B is 2nd register file output; 1=Immediate value]
11: Movc (Conditional Move)
10: Trap (Trap Instruction)
9 : TrapCond (Trap Condition) [0=ALU result is 0; 1=ALU result is not 0]
8 : RegDst (Register File Target) [0=Rt field; 1=Rd field]
------------------------------
7 : LLSC (Load Linked or Store Conditional)
6 : MemRead (Data Memory Read)
5 : MemWrite (Data Memory Write)
4 : MemHalf (Half Word Memory Access)
3 : MemByte (Byte size Memory Access)
2 : MemSignExtend (Sign Extend Read Memory) [0=Zero Extend; 1=Sign Extend]
------------------------------
1 : RegWrite (Register File Write)
0 : MemtoReg (Memory to Register) [0=Register File write data is ALU output; 1=Is Data Memory]
------------------------------
*/
parameter [15:0] DP_None = 16'b000_00000_000000_00; // Instructions which require nothing of the main datapath.
parameter [15:0] DP_RType = 16'b000_00001_000000_10; // Standard R-Type
parameter [15:0] DP_IType = 16'b000_10000_000000_10; // Standard I-Type
parameter [15:0] DP_Branch = 16'b100_00000_000000_00; // Standard Branch
parameter [15:0] DP_BranchLink = 16'b101_00000_000000_10; // Branch and Link
parameter [15:0] DP_HiLoWr = 16'b000_00000_000000_00; // Write to Hi/Lo ALU register (Div,Divu,Mult,Multu,Mthi,Mtlo). Currently 'DP_None'.
parameter [15:0] DP_Jump = 16'b010_00000_000000_00; // Standard Jump
parameter [15:0] DP_JumpLink = 16'b011_00000_000000_10; // Jump and Link
parameter [15:0] DP_JumpLinkReg = 16'b111_00000_000000_10; // Jump and Link Register
parameter [15:0] DP_JumpReg = 16'b110_00000_000000_00; // Jump Register
parameter [15:0] DP_LoadByteS = 16'b000_10000_010011_11; // Load Byte Signed
parameter [15:0] DP_LoadByteU = 16'b000_10000_010010_11; // Load Byte Unsigned
parameter [15:0] DP_LoadHalfS = 16'b000_10000_010101_11; // Load Half Signed
parameter [15:0] DP_LoadHalfU = 16'b000_10000_010100_11; // Load Half Unsigned
parameter [15:0] DP_LoadWord = 16'b000_10000_010000_11; // Load Word
parameter [15:0] DP_ExtWrRt = 16'b000_00000_000000_10; // A DP-external write to Rt
parameter [15:0] DP_ExtWrRd = 16'b000_00001_000000_10; // A DP-external write to Rd
parameter [15:0] DP_Movc = 16'b000_01001_000000_10; // Conditional Move
parameter [15:0] DP_LoadLinked = 16'b000_10000_110000_11; // Load Linked
parameter [15:0] DP_StoreCond = 16'b000_10000_101000_11; // Store Conditional
parameter [15:0] DP_StoreByte = 16'b000_10000_001010_00; // Store Byte
parameter [15:0] DP_StoreHalf = 16'b000_10000_001100_00; // Store Half
parameter [15:0] DP_StoreWord = 16'b000_10000_001000_00; // Store Word
parameter [15:0] DP_TrapRegCNZ = 16'b000_00110_000000_00; // Trap using Rs and Rt, non-zero ALU (Tlt, Tltu, Tne)
parameter [15:0] DP_TrapRegCZ = 16'b000_00100_000000_00; // Trap using RS and Rt, zero ALU (Teq, Tge, Tgeu)
parameter [15:0] DP_TrapImmCNZ = 16'b000_10110_000000_00; // Trap using Rs and Imm, non-zero ALU (Tlti, Tltiu, Tnei)
parameter [15:0] DP_TrapImmCZ = 16'b000_10100_000000_00; // Trap using Rs and Imm, zero ALU (Teqi, Tgei, Tgeiu)
//--------------------------------------------------------
parameter [15:0] DP_Add = DP_RType;
parameter [15:0] DP_Addi = DP_IType;
parameter [15:0] DP_Addiu = DP_IType;
410,223 → 410,223
parameter [15:0] DP_Tne = DP_TrapRegCNZ;
parameter [15:0] DP_Tnei = DP_TrapImmCNZ;
parameter [15:0] DP_Xor = DP_RType;
parameter [15:0] DP_Xori = DP_IType;
 
 
 
 
/*** Exception Information ***
 
All signals are Active High.
 
Bit Meaning
------------
2: Instruction can cause exceptions in ID
1: Instruction can cause exceptions in EX
0: Instruction can cause exceptions in MEM
*/
parameter [2:0] EXC_None = 3'b000;
parameter [2:0] EXC_ID = 3'b100;
parameter [2:0] EXC_EX = 3'b010;
parameter [2:0] EXC_MEM = 3'b001;
//--------------------------------
parameter [2:0] EXC_Add = EXC_EX;
parameter [2:0] EXC_Addi = EXC_EX;
parameter [2:0] EXC_Addiu = EXC_None;
parameter [2:0] EXC_Addu = EXC_None;
parameter [2:0] EXC_And = EXC_None;
parameter [2:0] EXC_Andi = EXC_None;
parameter [2:0] EXC_Beq = EXC_None;
parameter [2:0] EXC_Bgez = EXC_None;
parameter [2:0] EXC_Bgezal = EXC_None;
parameter [2:0] EXC_Bgtz = EXC_None;
parameter [2:0] EXC_Blez = EXC_None;
parameter [2:0] EXC_Bltz = EXC_None;
parameter [2:0] EXC_Bltzal = EXC_None;
parameter [2:0] EXC_Bne = EXC_None;
parameter [2:0] EXC_Break = EXC_ID;
parameter [2:0] EXC_Clo = EXC_None;
parameter [2:0] EXC_Clz = EXC_None;
parameter [2:0] EXC_Div = EXC_None;
parameter [2:0] EXC_Divu = EXC_None;
parameter [2:0] EXC_Eret = EXC_ID;
parameter [2:0] EXC_J = EXC_None;
parameter [2:0] EXC_Jal = EXC_None;
parameter [2:0] EXC_Jalr = EXC_None;
parameter [2:0] EXC_Jr = EXC_None;
parameter [2:0] EXC_Lb = EXC_MEM;
parameter [2:0] EXC_Lbu = EXC_MEM;
parameter [2:0] EXC_Lh = EXC_MEM;
parameter [2:0] EXC_Lhu = EXC_MEM;
parameter [2:0] EXC_Ll = EXC_MEM;
parameter [2:0] EXC_Lui = EXC_None;
parameter [2:0] EXC_Lw = EXC_MEM;
parameter [2:0] EXC_Lwl = EXC_MEM;
parameter [2:0] EXC_Lwr = EXC_MEM;
parameter [2:0] EXC_Madd = EXC_None;
parameter [2:0] EXC_Maddu = EXC_None;
parameter [2:0] EXC_Mfc0 = EXC_ID;
parameter [2:0] EXC_Mfhi = EXC_None;
parameter [2:0] EXC_Mflo = EXC_None;
parameter [2:0] EXC_Movn = EXC_None;
parameter [2:0] EXC_Movz = EXC_None;
parameter [2:0] EXC_Msub = EXC_None;
parameter [2:0] EXC_Msubu = EXC_None;
parameter [2:0] EXC_Mtc0 = EXC_ID;
parameter [2:0] EXC_Mthi = EXC_None;
parameter [2:0] EXC_Mtlo = EXC_None;
parameter [2:0] EXC_Mul = EXC_None;
parameter [2:0] EXC_Mult = EXC_None;
parameter [2:0] EXC_Multu = EXC_None;
parameter [2:0] EXC_Nor = EXC_None;
parameter [2:0] EXC_Or = EXC_None;
parameter [2:0] EXC_Ori = EXC_None;
parameter [2:0] EXC_Pref = EXC_None; // XXX
parameter [2:0] EXC_Sb = EXC_MEM;
parameter [2:0] EXC_Sc = EXC_MEM;
parameter [2:0] EXC_Sh = EXC_MEM;
parameter [2:0] EXC_Sll = EXC_None;
parameter [2:0] EXC_Sllv = EXC_None;
parameter [2:0] EXC_Slt = EXC_None;
parameter [2:0] EXC_Slti = EXC_None;
parameter [2:0] EXC_Sltiu = EXC_None;
parameter [2:0] EXC_Sltu = EXC_None;
parameter [2:0] EXC_Sra = EXC_None;
parameter [2:0] EXC_Srav = EXC_None;
parameter [2:0] EXC_Srl = EXC_None;
parameter [2:0] EXC_Srlv = EXC_None;
parameter [2:0] EXC_Sub = EXC_EX;
parameter [2:0] EXC_Subu = EXC_None;
parameter [2:0] EXC_Sw = EXC_MEM;
parameter [2:0] EXC_Swl = EXC_MEM;
parameter [2:0] EXC_Swr = EXC_MEM;
parameter [2:0] EXC_Syscall = EXC_ID;
parameter [2:0] EXC_Teq = EXC_MEM;
parameter [2:0] EXC_Teqi = EXC_MEM;
parameter [2:0] EXC_Tge = EXC_MEM;
parameter [2:0] EXC_Tgei = EXC_MEM;
parameter [2:0] EXC_Tgeiu = EXC_MEM;
parameter [2:0] EXC_Tgeu = EXC_MEM;
parameter [2:0] EXC_Tlt = EXC_MEM;
parameter [2:0] EXC_Tlti = EXC_MEM;
parameter [2:0] EXC_Tltiu = EXC_MEM;
parameter [2:0] EXC_Tltu = EXC_MEM;
parameter [2:0] EXC_Tne = EXC_MEM;
parameter [2:0] EXC_Tnei = EXC_MEM;
parameter [2:0] EXC_Xor = EXC_None;
parameter [2:0] EXC_Xori = EXC_None;
 
 
 
 
/*** Hazard & Forwarding Datapath ***
 
All signals are Active High.
Bit Meaning
------------
7: Wants Rs by ID
6: Needs Rs by ID
5: Wants Rt by ID
4: Needs Rt by ID
3: Wants Rs by EX
2: Needs Rs by EX
1: Wants Rt by EX
0: Needs Rt by EX
*/
parameter [7:0] HAZ_Nothing = 8'b00000000; // Jumps, Lui, Mfhi/lo, special, etc.
parameter [7:0] HAZ_IDRsIDRt = 8'b11110000; // Beq, Bne, Traps
parameter [7:0] HAZ_IDRs = 8'b11000000; // Most branches, Jumps to registers
parameter [7:0] HAZ_IDRt = 8'b00110000; // Mtc0
parameter [7:0] HAZ_IDRtEXRs = 8'b10111100; // Movn, Movz
parameter [7:0] HAZ_EXRsEXRt = 8'b10101111; // Many R-Type ops
parameter [7:0] HAZ_EXRs = 8'b10001100; // Immediates: Loads, Clo/z, Mthi/lo, etc.
parameter [7:0] HAZ_EXRsWRt = 8'b10101110; // Stores
parameter [7:0] HAZ_EXRt = 8'b00100011; // Shifts using Shamt field
//-----------------------------------------
parameter [7:0] HAZ_Add = HAZ_EXRsEXRt;
parameter [7:0] HAZ_Addi = HAZ_EXRs;
parameter [7:0] HAZ_Addiu = HAZ_EXRs;
parameter [7:0] HAZ_Addu = HAZ_EXRsEXRt;
parameter [7:0] HAZ_And = HAZ_EXRsEXRt;
parameter [7:0] HAZ_Andi = HAZ_EXRs;
parameter [7:0] HAZ_Beq = HAZ_IDRsIDRt;
parameter [7:0] HAZ_Bgez = HAZ_IDRs;
parameter [7:0] HAZ_Bgezal = HAZ_IDRs;
parameter [7:0] HAZ_Bgtz = HAZ_IDRs;
parameter [7:0] HAZ_Blez = HAZ_IDRs;
parameter [7:0] HAZ_Bltz = HAZ_IDRs;
parameter [7:0] HAZ_Bltzal = HAZ_IDRs;
parameter [7:0] HAZ_Bne = HAZ_IDRsIDRt;
parameter [7:0] HAZ_Break = HAZ_Nothing;
parameter [7:0] HAZ_Clo = HAZ_EXRs;
parameter [7:0] HAZ_Clz = HAZ_EXRs;
parameter [7:0] HAZ_Div = HAZ_EXRsEXRt;
parameter [7:0] HAZ_Divu = HAZ_EXRsEXRt;
parameter [7:0] HAZ_Eret = HAZ_Nothing;
parameter [7:0] HAZ_J = HAZ_Nothing;
parameter [7:0] HAZ_Jal = HAZ_Nothing;
parameter [7:0] HAZ_Jalr = HAZ_IDRs;
parameter [7:0] HAZ_Jr = HAZ_IDRs;
parameter [7:0] HAZ_Lb = HAZ_EXRs;
parameter [7:0] HAZ_Lbu = HAZ_EXRs;
parameter [7:0] HAZ_Lh = HAZ_EXRs;
parameter [7:0] HAZ_Lhu = HAZ_EXRs;
parameter [7:0] HAZ_Ll = HAZ_EXRs;
parameter [7:0] HAZ_Lui = HAZ_Nothing;
parameter [7:0] HAZ_Lw = HAZ_EXRs;
parameter [7:0] HAZ_Lwl = HAZ_EXRsEXRt;
parameter [7:0] HAZ_Lwr = HAZ_EXRsEXRt;
parameter [7:0] HAZ_Madd = HAZ_EXRsEXRt;
parameter [7:0] HAZ_Maddu = HAZ_EXRsEXRt;
parameter [7:0] HAZ_Mfc0 = HAZ_Nothing;
parameter [7:0] HAZ_Mfhi = HAZ_Nothing;
parameter [7:0] HAZ_Mflo = HAZ_Nothing;
parameter [7:0] HAZ_Movn = HAZ_IDRtEXRs;
parameter [7:0] HAZ_Movz = HAZ_IDRtEXRs;
parameter [7:0] HAZ_Msub = HAZ_EXRsEXRt;
parameter [7:0] HAZ_Msubu = HAZ_EXRsEXRt;
parameter [7:0] HAZ_Mtc0 = HAZ_IDRt;
parameter [7:0] HAZ_Mthi = HAZ_EXRs;
parameter [7:0] HAZ_Mtlo = HAZ_EXRs;
parameter [7:0] HAZ_Mul = HAZ_EXRsEXRt;
parameter [7:0] HAZ_Mult = HAZ_EXRsEXRt;
parameter [7:0] HAZ_Multu = HAZ_EXRsEXRt;
parameter [7:0] HAZ_Nor = HAZ_EXRsEXRt;
parameter [7:0] HAZ_Or = HAZ_EXRsEXRt;
parameter [7:0] HAZ_Ori = HAZ_EXRs;
parameter [7:0] HAZ_Pref = HAZ_Nothing; // XXX
parameter [7:0] HAZ_Sb = HAZ_EXRsWRt;
parameter [7:0] HAZ_Sc = HAZ_EXRsWRt;
parameter [7:0] HAZ_Sh = HAZ_EXRsWRt;
parameter [7:0] HAZ_Sll = HAZ_EXRt;
parameter [7:0] HAZ_Sllv = HAZ_EXRsEXRt;
parameter [7:0] HAZ_Slt = HAZ_EXRsEXRt;
parameter [7:0] HAZ_Slti = HAZ_EXRs;
parameter [7:0] HAZ_Sltiu = HAZ_EXRs;
parameter [7:0] HAZ_Sltu = HAZ_EXRsEXRt;
parameter [7:0] HAZ_Sra = HAZ_EXRt;
parameter [7:0] HAZ_Srav = HAZ_EXRsEXRt;
parameter [7:0] HAZ_Srl = HAZ_EXRt;
parameter [7:0] HAZ_Srlv = HAZ_EXRsEXRt;
parameter [7:0] HAZ_Sub = HAZ_EXRsEXRt;
parameter [7:0] HAZ_Subu = HAZ_EXRsEXRt;
parameter [7:0] HAZ_Sw = HAZ_EXRsWRt;
parameter [7:0] HAZ_Swl = HAZ_EXRsWRt;
parameter [7:0] HAZ_Swr = HAZ_EXRsWRt;
parameter [7:0] HAZ_Syscall = HAZ_Nothing;
parameter [7:0] HAZ_Teq = HAZ_EXRsEXRt;
parameter [7:0] HAZ_Teqi = HAZ_EXRs;
parameter [7:0] HAZ_Tge = HAZ_EXRsEXRt;
parameter [7:0] HAZ_Tgei = HAZ_EXRs;
parameter [7:0] HAZ_Tgeiu = HAZ_EXRs;
parameter [7:0] HAZ_Tgeu = HAZ_EXRsEXRt;
parameter [7:0] HAZ_Tlt = HAZ_EXRsEXRt;
parameter [7:0] HAZ_Tlti = HAZ_EXRs;
parameter [7:0] HAZ_Tltiu = HAZ_EXRs;
parameter [7:0] HAZ_Tltu = HAZ_EXRsEXRt;
parameter [7:0] HAZ_Tne = HAZ_EXRsEXRt;
parameter [7:0] HAZ_Tnei = HAZ_EXRs;
parameter [7:0] HAZ_Xor = HAZ_EXRsEXRt;
parameter [7:0] HAZ_Xori = HAZ_EXRs;
 
parameter [15:0] DP_Xori = DP_IType;
 
 
 
 
/*** Exception Information ***
 
All signals are Active High.
 
Bit Meaning
------------
2: Instruction can cause exceptions in ID
1: Instruction can cause exceptions in EX
0: Instruction can cause exceptions in MEM
*/
parameter [2:0] EXC_None = 3'b000;
parameter [2:0] EXC_ID = 3'b100;
parameter [2:0] EXC_EX = 3'b010;
parameter [2:0] EXC_MEM = 3'b001;
//--------------------------------
parameter [2:0] EXC_Add = EXC_EX;
parameter [2:0] EXC_Addi = EXC_EX;
parameter [2:0] EXC_Addiu = EXC_None;
parameter [2:0] EXC_Addu = EXC_None;
parameter [2:0] EXC_And = EXC_None;
parameter [2:0] EXC_Andi = EXC_None;
parameter [2:0] EXC_Beq = EXC_None;
parameter [2:0] EXC_Bgez = EXC_None;
parameter [2:0] EXC_Bgezal = EXC_None;
parameter [2:0] EXC_Bgtz = EXC_None;
parameter [2:0] EXC_Blez = EXC_None;
parameter [2:0] EXC_Bltz = EXC_None;
parameter [2:0] EXC_Bltzal = EXC_None;
parameter [2:0] EXC_Bne = EXC_None;
parameter [2:0] EXC_Break = EXC_ID;
parameter [2:0] EXC_Clo = EXC_None;
parameter [2:0] EXC_Clz = EXC_None;
parameter [2:0] EXC_Div = EXC_None;
parameter [2:0] EXC_Divu = EXC_None;
parameter [2:0] EXC_Eret = EXC_ID;
parameter [2:0] EXC_J = EXC_None;
parameter [2:0] EXC_Jal = EXC_None;
parameter [2:0] EXC_Jalr = EXC_None;
parameter [2:0] EXC_Jr = EXC_None;
parameter [2:0] EXC_Lb = EXC_MEM;
parameter [2:0] EXC_Lbu = EXC_MEM;
parameter [2:0] EXC_Lh = EXC_MEM;
parameter [2:0] EXC_Lhu = EXC_MEM;
parameter [2:0] EXC_Ll = EXC_MEM;
parameter [2:0] EXC_Lui = EXC_None;
parameter [2:0] EXC_Lw = EXC_MEM;
parameter [2:0] EXC_Lwl = EXC_MEM;
parameter [2:0] EXC_Lwr = EXC_MEM;
parameter [2:0] EXC_Madd = EXC_None;
parameter [2:0] EXC_Maddu = EXC_None;
parameter [2:0] EXC_Mfc0 = EXC_ID;
parameter [2:0] EXC_Mfhi = EXC_None;
parameter [2:0] EXC_Mflo = EXC_None;
parameter [2:0] EXC_Movn = EXC_None;
parameter [2:0] EXC_Movz = EXC_None;
parameter [2:0] EXC_Msub = EXC_None;
parameter [2:0] EXC_Msubu = EXC_None;
parameter [2:0] EXC_Mtc0 = EXC_ID;
parameter [2:0] EXC_Mthi = EXC_None;
parameter [2:0] EXC_Mtlo = EXC_None;
parameter [2:0] EXC_Mul = EXC_None;
parameter [2:0] EXC_Mult = EXC_None;
parameter [2:0] EXC_Multu = EXC_None;
parameter [2:0] EXC_Nor = EXC_None;
parameter [2:0] EXC_Or = EXC_None;
parameter [2:0] EXC_Ori = EXC_None;
parameter [2:0] EXC_Pref = EXC_None; // XXX
parameter [2:0] EXC_Sb = EXC_MEM;
parameter [2:0] EXC_Sc = EXC_MEM;
parameter [2:0] EXC_Sh = EXC_MEM;
parameter [2:0] EXC_Sll = EXC_None;
parameter [2:0] EXC_Sllv = EXC_None;
parameter [2:0] EXC_Slt = EXC_None;
parameter [2:0] EXC_Slti = EXC_None;
parameter [2:0] EXC_Sltiu = EXC_None;
parameter [2:0] EXC_Sltu = EXC_None;
parameter [2:0] EXC_Sra = EXC_None;
parameter [2:0] EXC_Srav = EXC_None;
parameter [2:0] EXC_Srl = EXC_None;
parameter [2:0] EXC_Srlv = EXC_None;
parameter [2:0] EXC_Sub = EXC_EX;
parameter [2:0] EXC_Subu = EXC_None;
parameter [2:0] EXC_Sw = EXC_MEM;
parameter [2:0] EXC_Swl = EXC_MEM;
parameter [2:0] EXC_Swr = EXC_MEM;
parameter [2:0] EXC_Syscall = EXC_ID;
parameter [2:0] EXC_Teq = EXC_MEM;
parameter [2:0] EXC_Teqi = EXC_MEM;
parameter [2:0] EXC_Tge = EXC_MEM;
parameter [2:0] EXC_Tgei = EXC_MEM;
parameter [2:0] EXC_Tgeiu = EXC_MEM;
parameter [2:0] EXC_Tgeu = EXC_MEM;
parameter [2:0] EXC_Tlt = EXC_MEM;
parameter [2:0] EXC_Tlti = EXC_MEM;
parameter [2:0] EXC_Tltiu = EXC_MEM;
parameter [2:0] EXC_Tltu = EXC_MEM;
parameter [2:0] EXC_Tne = EXC_MEM;
parameter [2:0] EXC_Tnei = EXC_MEM;
parameter [2:0] EXC_Xor = EXC_None;
parameter [2:0] EXC_Xori = EXC_None;
 
 
 
 
/*** Hazard & Forwarding Datapath ***
 
All signals are Active High.
Bit Meaning
------------
7: Wants Rs by ID
6: Needs Rs by ID
5: Wants Rt by ID
4: Needs Rt by ID
3: Wants Rs by EX
2: Needs Rs by EX
1: Wants Rt by EX
0: Needs Rt by EX
*/
parameter [7:0] HAZ_Nothing = 8'b00000000; // Jumps, Lui, Mfhi/lo, special, etc.
parameter [7:0] HAZ_IDRsIDRt = 8'b11110000; // Beq, Bne, Traps
parameter [7:0] HAZ_IDRs = 8'b11000000; // Most branches, Jumps to registers
parameter [7:0] HAZ_IDRt = 8'b00110000; // Mtc0
parameter [7:0] HAZ_IDRtEXRs = 8'b10111100; // Movn, Movz
parameter [7:0] HAZ_EXRsEXRt = 8'b10101111; // Many R-Type ops
parameter [7:0] HAZ_EXRs = 8'b10001100; // Immediates: Loads, Clo/z, Mthi/lo, etc.
parameter [7:0] HAZ_EXRsWRt = 8'b10101110; // Stores
parameter [7:0] HAZ_EXRt = 8'b00100011; // Shifts using Shamt field
//-----------------------------------------
parameter [7:0] HAZ_Add = HAZ_EXRsEXRt;
parameter [7:0] HAZ_Addi = HAZ_EXRs;
parameter [7:0] HAZ_Addiu = HAZ_EXRs;
parameter [7:0] HAZ_Addu = HAZ_EXRsEXRt;
parameter [7:0] HAZ_And = HAZ_EXRsEXRt;
parameter [7:0] HAZ_Andi = HAZ_EXRs;
parameter [7:0] HAZ_Beq = HAZ_IDRsIDRt;
parameter [7:0] HAZ_Bgez = HAZ_IDRs;
parameter [7:0] HAZ_Bgezal = HAZ_IDRs;
parameter [7:0] HAZ_Bgtz = HAZ_IDRs;
parameter [7:0] HAZ_Blez = HAZ_IDRs;
parameter [7:0] HAZ_Bltz = HAZ_IDRs;
parameter [7:0] HAZ_Bltzal = HAZ_IDRs;
parameter [7:0] HAZ_Bne = HAZ_IDRsIDRt;
parameter [7:0] HAZ_Break = HAZ_Nothing;
parameter [7:0] HAZ_Clo = HAZ_EXRs;
parameter [7:0] HAZ_Clz = HAZ_EXRs;
parameter [7:0] HAZ_Div = HAZ_EXRsEXRt;
parameter [7:0] HAZ_Divu = HAZ_EXRsEXRt;
parameter [7:0] HAZ_Eret = HAZ_Nothing;
parameter [7:0] HAZ_J = HAZ_Nothing;
parameter [7:0] HAZ_Jal = HAZ_Nothing;
parameter [7:0] HAZ_Jalr = HAZ_IDRs;
parameter [7:0] HAZ_Jr = HAZ_IDRs;
parameter [7:0] HAZ_Lb = HAZ_EXRs;
parameter [7:0] HAZ_Lbu = HAZ_EXRs;
parameter [7:0] HAZ_Lh = HAZ_EXRs;
parameter [7:0] HAZ_Lhu = HAZ_EXRs;
parameter [7:0] HAZ_Ll = HAZ_EXRs;
parameter [7:0] HAZ_Lui = HAZ_Nothing;
parameter [7:0] HAZ_Lw = HAZ_EXRs;
parameter [7:0] HAZ_Lwl = HAZ_EXRsEXRt;
parameter [7:0] HAZ_Lwr = HAZ_EXRsEXRt;
parameter [7:0] HAZ_Madd = HAZ_EXRsEXRt;
parameter [7:0] HAZ_Maddu = HAZ_EXRsEXRt;
parameter [7:0] HAZ_Mfc0 = HAZ_Nothing;
parameter [7:0] HAZ_Mfhi = HAZ_Nothing;
parameter [7:0] HAZ_Mflo = HAZ_Nothing;
parameter [7:0] HAZ_Movn = HAZ_IDRtEXRs;
parameter [7:0] HAZ_Movz = HAZ_IDRtEXRs;
parameter [7:0] HAZ_Msub = HAZ_EXRsEXRt;
parameter [7:0] HAZ_Msubu = HAZ_EXRsEXRt;
parameter [7:0] HAZ_Mtc0 = HAZ_IDRt;
parameter [7:0] HAZ_Mthi = HAZ_EXRs;
parameter [7:0] HAZ_Mtlo = HAZ_EXRs;
parameter [7:0] HAZ_Mul = HAZ_EXRsEXRt;
parameter [7:0] HAZ_Mult = HAZ_EXRsEXRt;
parameter [7:0] HAZ_Multu = HAZ_EXRsEXRt;
parameter [7:0] HAZ_Nor = HAZ_EXRsEXRt;
parameter [7:0] HAZ_Or = HAZ_EXRsEXRt;
parameter [7:0] HAZ_Ori = HAZ_EXRs;
parameter [7:0] HAZ_Pref = HAZ_Nothing; // XXX
parameter [7:0] HAZ_Sb = HAZ_EXRsWRt;
parameter [7:0] HAZ_Sc = HAZ_EXRsWRt;
parameter [7:0] HAZ_Sh = HAZ_EXRsWRt;
parameter [7:0] HAZ_Sll = HAZ_EXRt;
parameter [7:0] HAZ_Sllv = HAZ_EXRsEXRt;
parameter [7:0] HAZ_Slt = HAZ_EXRsEXRt;
parameter [7:0] HAZ_Slti = HAZ_EXRs;
parameter [7:0] HAZ_Sltiu = HAZ_EXRs;
parameter [7:0] HAZ_Sltu = HAZ_EXRsEXRt;
parameter [7:0] HAZ_Sra = HAZ_EXRt;
parameter [7:0] HAZ_Srav = HAZ_EXRsEXRt;
parameter [7:0] HAZ_Srl = HAZ_EXRt;
parameter [7:0] HAZ_Srlv = HAZ_EXRsEXRt;
parameter [7:0] HAZ_Sub = HAZ_EXRsEXRt;
parameter [7:0] HAZ_Subu = HAZ_EXRsEXRt;
parameter [7:0] HAZ_Sw = HAZ_EXRsWRt;
parameter [7:0] HAZ_Swl = HAZ_EXRsWRt;
parameter [7:0] HAZ_Swr = HAZ_EXRsWRt;
parameter [7:0] HAZ_Syscall = HAZ_Nothing;
parameter [7:0] HAZ_Teq = HAZ_EXRsEXRt;
parameter [7:0] HAZ_Teqi = HAZ_EXRs;
parameter [7:0] HAZ_Tge = HAZ_EXRsEXRt;
parameter [7:0] HAZ_Tgei = HAZ_EXRs;
parameter [7:0] HAZ_Tgeiu = HAZ_EXRs;
parameter [7:0] HAZ_Tgeu = HAZ_EXRsEXRt;
parameter [7:0] HAZ_Tlt = HAZ_EXRsEXRt;
parameter [7:0] HAZ_Tlti = HAZ_EXRs;
parameter [7:0] HAZ_Tltiu = HAZ_EXRs;
parameter [7:0] HAZ_Tltu = HAZ_EXRsEXRt;
parameter [7:0] HAZ_Tne = HAZ_EXRsEXRt;
parameter [7:0] HAZ_Tnei = HAZ_EXRs;
parameter [7:0] HAZ_Xor = HAZ_EXRsEXRt;
parameter [7:0] HAZ_Xori = HAZ_EXRs;
 
/XUPV5-LX110T_SoC/MIPS32-Pipelined-Hw/src/MIPS32/EXMEM_Stage.v
16,27 → 16,27
* The Pipeline Register to bridge the Execute and Memory stages.
*/
module EXMEM_Stage(
input clock,
input reset,
input clock,
input reset,
input EX_Flush,
input EX_Stall,
input M_Stall,
// Control Signals
input EX_Stall,
input M_Stall,
// Control Signals
input EX_Movn,
input EX_Movz,
input EX_BZero,
input EX_RegWrite, // Future Control to WB
input EX_MemtoReg, // Future Control to WB
input EX_RegWrite, // Future Control to WB
input EX_MemtoReg, // Future Control to WB
input EX_ReverseEndian,
input EX_LLSC,
input EX_MemRead,
input EX_MemWrite,
input EX_MemByte,
input EX_MemHalf,
input EX_MemSignExtend,
input EX_MemRead,
input EX_MemWrite,
input EX_MemByte,
input EX_MemHalf,
input EX_MemSignExtend,
input EX_Left,
input EX_Right,
// Exception Control/Info
// Exception Control/Info
input EX_KernelMode,
input [31:0] EX_RestartPC,
input EX_IsBDS,
43,20 → 43,20
input EX_Trap,
input EX_TrapCond,
input EX_M_CanErr,
// Data Signals
input [31:0] EX_ALU_Result,
input [31:0] EX_ReadData2,
input [4:0] EX_RtRd,
// ------------------
output reg M_RegWrite,
output reg M_MemtoReg,
// Data Signals
input [31:0] EX_ALU_Result,
input [31:0] EX_ReadData2,
input [4:0] EX_RtRd,
// ------------------
output reg M_RegWrite,
output reg M_MemtoReg,
output reg M_ReverseEndian,
output reg M_LLSC,
output reg M_MemRead,
output reg M_MemWrite,
output reg M_MemByte,
output reg M_MemHalf,
output reg M_MemSignExtend,
output reg M_MemRead,
output reg M_MemWrite,
output reg M_MemByte,
output reg M_MemHalf,
output reg M_MemSignExtend,
output reg M_Left,
output reg M_Right,
output reg M_KernelMode,
65,10 → 65,10
output reg M_Trap,
output reg M_TrapCond,
output reg M_M_CanErr,
output reg [31:0] M_ALU_Result,
output reg [31:0] M_ReadData2,
output reg [4:0] M_RtRd
);
output reg [31:0] M_ALU_Result,
output reg [31:0] M_ReadData2,
output reg [4:0] M_RtRd
);
 
/***
The purpose of a pipeline register is to capture data from one pipeline stage
113,3 → 113,4
end
 
endmodule
 
/XUPV5-LX110T_SoC/MIPS32-Pipelined-Hw/src/MIPS32/IFID_Stage.v
17,25 → 17,25
* and Instruction Decode stages.
*/
module IFID_Stage(
input clock,
input reset,
input IF_Flush,
input clock,
input reset,
input IF_Flush,
input IF_Stall,
input ID_Stall,
// Control Signals
input [31:0] IF_Instruction,
// Data Signals
input [31:0] IF_PCAdd4,
input ID_Stall,
// Control Signals
input [31:0] IF_Instruction,
// Data Signals
input [31:0] IF_PCAdd4,
input [31:0] IF_PC,
input IF_IsBDS,
// ------------------
output reg [31:0] ID_Instruction,
output reg [31:0] ID_PCAdd4,
// ------------------
output reg [31:0] ID_Instruction,
output reg [31:0] ID_PCAdd4,
output reg [31:0] ID_RestartPC,
output reg ID_IsBDS,
output reg ID_IsFlushed
);
);
/***
The purpose of a pipeline register is to capture data from one pipeline stage
and provide it to the next pipeline stage. This creates at least one clock cycle
72,3 → 72,4
end
 
endmodule
 
/XUPV5-LX110T_SoC/MIPS32-Pipelined-Hw/src/MIPS32/TrapDetect.v
25,3 → 25,4
assign EXC_Tr = Trap & (TrapCond ^ ALUZero);
 
endmodule
 
/XUPV5-LX110T_SoC/MIPS32-Pipelined-Hw/src/MIPS32/CPZero.v
21,37 → 21,37
* is MIPS-32-compliant.
*/
module CPZero(
input clock,
//-- CP0 Functionality --//
input clock,
//-- CP0 Functionality --//
input Mfc0, // CPU instruction is Mfc0
input Mtc0, // CPU instruction is Mtc0
input Mtc0, // CPU instruction is Mtc0
input IF_Stall,
input ID_Stall, // Commits are not made during stalls
input COP1, // Instruction for Coprocessor 1
input COP2, // Instruction for Coprocessor 2
input COP3, // Instruction for Coprocessor 3
input COP1, // Instruction for Coprocessor 1
input COP2, // Instruction for Coprocessor 2
input COP3, // Instruction for Coprocessor 3
input ERET, // Instruction is ERET (Exception Return)
input [4:0] Rd, // Specifies Cp0 register
input [2:0] Sel, // Specifies Cp0 'select'
input [31:0] Reg_In, // Data from GP register to replace CP0 register
input [4:0] Rd, // Specifies Cp0 register
input [2:0] Sel, // Specifies Cp0 'select'
input [31:0] Reg_In, // Data from GP register to replace CP0 register
output reg [31:0] Reg_Out, // Data from CP0 register for GP register
output KernelMode, // Kernel mode indicator for pipeline transit
output ReverseEndian, // Reverse Endian memory indicator for User Mode
//-- Hw Interrupts --//
input [4:0] Int, // Five hardware interrupts external to the processor
//-- Exceptions --//
input reset, // Cold Reset (EXC_Reset)
//-- Hw Interrupts --//
input [4:0] Int, // Five hardware interrupts external to the processor
//-- Exceptions --//
input reset, // Cold Reset (EXC_Reset)
// input EXC_SReset, // Soft Reset (not implemented)
input EXC_NMI, // Non-Maskable Interrupt
input EXC_NMI, // Non-Maskable Interrupt
input EXC_AdIF, // Address Error Exception from i-fetch (mapped to AdEL)
input EXC_AdEL, // Address Error Exception from data memory load
input EXC_AdES, // Address Error Exception from data memory store
input EXC_Ov, // Integer Overflow Exception
input EXC_Tr, // Trap Exception
input EXC_Sys, // System Call Exception
input EXC_Bp, // Breakpoint Exception
input EXC_RI, // Reserved Instruction Exception
//-- Exception Data --//
input EXC_AdEL, // Address Error Exception from data memory load
input EXC_AdES, // Address Error Exception from data memory store
input EXC_Ov, // Integer Overflow Exception
input EXC_Tr, // Trap Exception
input EXC_Sys, // System Call Exception
input EXC_Bp, // Breakpoint Exception
input EXC_RI, // Reserved Instruction Exception
//-- Exception Data --//
input [31:0] ID_RestartPC, // PC for exception, whether PC of instruction or of branch (PC-4) if BDS
input [31:0] EX_RestartPC, // Same as 'ID_RestartPC' but in EX stage
input [31:0] M_RestartPC, // Same as 'ID_RestartPC' but in MEM stage
60,7 → 60,7
input ID_IsBD, // Indicator of ID exception being a branch delay slot instruction
input EX_IsBD, // Indicator of EX exception being a branch delay slot instruction
input M_IsBD, // Indicator of M exception being a branch delay slot instruction
input [31:0] BadAddr_M, // Bad 'Virtual' Address for exceptions AdEL, AdES in MEM stage
input [31:0] BadAddr_M, // Bad 'Virtual' Address for exceptions AdEL, AdES in MEM stage
input [31:0] BadAddr_IF, // Bad 'Virtual' Address for AdIF (i.e. AdEL) in IF stage
input ID_CanErr, // Cumulative signal, i.e. (ID_ID_CanErr | ID_EX_CanErr | ID_M_CanErr)
input EX_CanErr, // Cumulative signal, i.e. (EX_EX_CanErr | EX_M_CanErr)
77,9 → 77,9
output Exc_PC_Sel, // Mux selector for exception PC override
output reg [31:0] Exc_PC_Out, // Address for PC at the beginning of an exception
output [7:0] IP // Pending Interrupts from Cause register (for diagnostic purposes)
);
);
 
`include "MIPS_Parameters.v"
`include "MIPS_Parameters.v"
 
 
/***
118,18 → 118,18
until the interrupts has been processed.
 
Exception Name Short Name Pipeline Stage
Address Error Ex (AdEL, AdES) MEM, IF
Integer Overflow Ex (Ov) EX
Trap Ex (Tr) MEM
Syscall (Sys) ID
Breakpoint (Bp) ID
Reserved Instruction (RI) ID
Coprocessor Unusable (CpU) ID
Interrupt (Int) ID
Reset, SReset, NMI ID
Address Error Ex (AdEL, AdES) MEM, IF
Integer Overflow Ex (Ov) EX
Trap Ex (Tr) MEM
Syscall (Sys) ID
Breakpoint (Bp) ID
Reserved Instruction (RI) ID
Coprocessor Unusable (CpU) ID
Interrupt (Int) ID
Reset, SReset, NMI ID
***/
// Exceptions Generated Internally
wire EXC_CpU;
 
178,9 → 178,9
reg Status_RE; // Reverse Endian Memory for User Mode
wire Status_MX = 0;
wire Status_PX = 0;
reg Status_BEV; // Exception vector locations (0->Norm, 1->Bootstrap)
reg Status_BEV; // Exception vector locations (0->Norm, 1->Bootstrap)
wire Status_TS = 0;
wire Status_SR = 0; // Soft reset not implemented
wire Status_SR = 0; // Soft reset not implemented
reg Status_NMI; // Non-Maskable Interrupt
wire Status_RES = 0;
wire [1:0] Status_Custom = 2'b00;
188,9 → 188,9
wire Status_KX = 0;
wire Status_SX = 0;
wire Status_UX = 0;
reg Status_UM; // Base operating mode (0->Kernel, 1->User)
reg Status_UM; // Base operating mode (0->Kernel, 1->User)
wire Status_R0 = 0;
reg Status_ERL; // Error Level (0->Normal, 1->Error (reset, NMI))
reg Status_ERL; // Error Level (0->Normal, 1->Error (reset, NMI))
reg Status_EXL; // Exception level (0->Normal, 1->Exception)
reg Status_IE; // Interrupt Enable
wire [31:0] Status = {Status_CU_321, Status_CU_0, Status_RP, Status_FR, Status_RE, Status_MX,
199,11 → 199,11
Status_UM, Status_R0, Status_ERL, Status_EXL, Status_IE};
 
// Cause Register (Register 13, Select 0)
reg Cause_BD; // Exception occured in Branch Delay
reg [1:0] Cause_CE; // CP number for CP Unusable exception
reg Cause_IV; // Indicator of general IV (0->0x180) or special IV (1->0x200)
reg Cause_BD; // Exception occured in Branch Delay
reg [1:0] Cause_CE; // CP number for CP Unusable exception
reg Cause_IV; // Indicator of general IV (0->0x180) or special IV (1->0x200)
wire Cause_WP = 0;
reg [7:0] Cause_IP; // Pending HW Interrupt indicator.
reg [7:0] Cause_IP; // Pending HW Interrupt indicator.
wire Cause_ExcCode4 = 0; // Can be made into a register when this bit is needed.
reg [3:0] Cause_ExcCode30; // Description of Exception (only lower 4 bits currently used; see above)
wire [31:0] Cause = {Cause_BD, 1'b0, Cause_CE, 4'b0000, Cause_IV, Cause_WP,
222,7 → 222,7
// Configuration Register (Register 16, Select 0)
wire Config_M = 1;
wire [14:0] Config_Impl = 15'b000_0000_0000_0000;
wire Config_BE = Big_Endian; // From parameters file
wire Config_BE = Big_Endian; // From parameters file
wire [1:0] Config_AT = 2'b00;
wire [2:0] Config_AR = 3'b000;
wire [2:0] Config_MT = 3'b000;
241,8 → 241,8
wire [2:0] Config1_DA = 3'b000;
wire Config1_C2 = 0;
wire Config1_MD = 0;
wire Config1_PC = 0; // XXX Performance Counters
wire Config1_WR = 0; // XXX Watch Registers
wire Config1_PC = 0; // XXX Performance Counters
wire Config1_WR = 0; // XXX Watch Registers
wire Config1_CA = 0;
wire Config1_EP = 0;
wire Config1_FP = 0;
524,6 → 524,6
else if (EXC_Int) Cause_ExcCode_bits <= 4'h0; // 00000 // OK that NMI writes this.
else Cause_ExcCode_bits <= 4'bxxxx;
end
 
endmodule
 
/XUPV5-LX110T_SoC/MIPS32-Pipelined-Hw/src/MIPS32/Hazard_Detection.v
22,71 → 22,71
* This module is heavily commented. Read below for more information.
*/
module Hazard_Detection(
input [7:0] DP_Hazards,
input [4:0] ID_Rs,
input [4:0] ID_Rt,
input [4:0] EX_Rs,
input [4:0] EX_Rt,
input [4:0] EX_RtRd,
input [4:0] MEM_RtRd,
input [4:0] WB_RtRd,
input [7:0] DP_Hazards,
input [4:0] ID_Rs,
input [4:0] ID_Rt,
input [4:0] EX_Rs,
input [4:0] EX_Rt,
input [4:0] EX_RtRd,
input [4:0] MEM_RtRd,
input [4:0] WB_RtRd,
input ID_Link,
input EX_Link,
input EX_RegWrite,
input MEM_RegWrite,
input WB_RegWrite,
input MEM_MemRead,
input EX_Link,
input EX_RegWrite,
input MEM_RegWrite,
input WB_RegWrite,
input MEM_MemRead,
input MEM_MemWrite, // Needed for Store Conditional which writes to a register
input InstMem_Read,
input InstMem_Ready,
input Mfc0, // Using fwd mux; not part of haz/fwd.
input InstMem_Ready,
input Mfc0, // Using fwd mux; not part of haz/fwd.
input IF_Exception_Stall,
input ID_Exception_Stall,
input EX_Exception_Stall,
input M_Stall_Controller, // Determined by data memory controller
output IF_Stall,
output ID_Stall,
output EX_Stall,
output IF_Stall,
output ID_Stall,
output EX_Stall,
output M_Stall,
output WB_Stall,
output [1:0] ID_RsFwdSel,
output [1:0] ID_RtFwdSel,
output [1:0] EX_RsFwdSel,
output [1:0] EX_RtFwdSel,
output M_WriteDataFwdSel
);
/* Hazard and Forward Detection
*
* Most instructions read from one or more registers. Normally this occurs in
* the ID stage. However, frequently the register file in the ID stage is stale
* when one or more forward stages in the pipeline (EX, MEM, or WB) contains
* an instruction which will eventually update it but has not yet done so.
*
* A hazard condition is created when a forward pipeline stage is set to write
* the same register that a current pipeline stage (e.g. in ID) needs to read.
* The solution is to stall the current stage (and effectively all stages behind
* it) or bypass (forward) the data from forward stages. Fortunately forwarding
* works for most combinations of instructions.
*
* Hazard and Forward conditions are handled based on two simple rules:
* "Wants" and "Needs." If an instruction "wants" data in a certain pipeline
* stage, and that data is available further along in the pipeline, it will
* be forwarded. If it "needs" data and the data is not yet available for forwarding,
* the pipeline stage stalls. If it does not want or need data in a certain
* stage, forwarding is disabled and a stall will not occur. This is important
* for instructions which insert custom data, such as jal or movz.
*
* Currently, "Want" and "Need" conditions are defined for both Rs data and Rt
* data (the two read registers in MIPS), and these conditions exist in the
* ID and EX pipeline stages. This is a total of eight condition bits.
*
* A unique exception exists with Store instructions, which don't need the
* "Rt" data until the MEM stage. Because data doesn't change in WB, and WB
* is the only stage following MEM, forwarding is *always* possible from
* WB to Mem. This unit handles this situation, and a condition bit is not
* needed.
*
output [1:0] ID_RsFwdSel,
output [1:0] ID_RtFwdSel,
output [1:0] EX_RsFwdSel,
output [1:0] EX_RtFwdSel,
output M_WriteDataFwdSel
);
/* Hazard and Forward Detection
*
* Most instructions read from one or more registers. Normally this occurs in
* the ID stage. However, frequently the register file in the ID stage is stale
* when one or more forward stages in the pipeline (EX, MEM, or WB) contains
* an instruction which will eventually update it but has not yet done so.
*
* A hazard condition is created when a forward pipeline stage is set to write
* the same register that a current pipeline stage (e.g. in ID) needs to read.
* The solution is to stall the current stage (and effectively all stages behind
* it) or bypass (forward) the data from forward stages. Fortunately forwarding
* works for most combinations of instructions.
*
* Hazard and Forward conditions are handled based on two simple rules:
* "Wants" and "Needs." If an instruction "wants" data in a certain pipeline
* stage, and that data is available further along in the pipeline, it will
* be forwarded. If it "needs" data and the data is not yet available for forwarding,
* the pipeline stage stalls. If it does not want or need data in a certain
* stage, forwarding is disabled and a stall will not occur. This is important
* for instructions which insert custom data, such as jal or movz.
*
* Currently, "Want" and "Need" conditions are defined for both Rs data and Rt
* data (the two read registers in MIPS), and these conditions exist in the
* ID and EX pipeline stages. This is a total of eight condition bits.
*
* A unique exception exists with Store instructions, which don't need the
* "Rt" data until the MEM stage. Because data doesn't change in WB, and WB
* is the only stage following MEM, forwarding is *always* possible from
* WB to Mem. This unit handles this situation, and a condition bit is not
* needed.
*
* When data is needed from the MEM stage by a previous stage (ID or EX), the
* decision to forward or stall is based on whether MEM is accessing memory
* (stall) or not (forward). Normally store instructions don't write to registers
94,69 → 94,69
* is sufficient to determine. Because of the Store Conditional instruction,
* however, 'MEM_MemWrite' must also be considered because it writes to a register.
*
*/
wire WantRsByID, NeedRsByID, WantRtByID, NeedRtByID, WantRsByEX, NeedRsByEX, WantRtByEX, NeedRtByEX;
assign WantRsByID = DP_Hazards[7];
assign NeedRsByID = DP_Hazards[6];
assign WantRtByID = DP_Hazards[5];
assign NeedRtByID = DP_Hazards[4];
assign WantRsByEX = DP_Hazards[3];
assign NeedRsByEX = DP_Hazards[2];
assign WantRtByEX = DP_Hazards[1];
assign NeedRtByEX = DP_Hazards[0];
*/
wire WantRsByID, NeedRsByID, WantRtByID, NeedRtByID, WantRsByEX, NeedRsByEX, WantRtByEX, NeedRtByEX;
assign WantRsByID = DP_Hazards[7];
assign NeedRsByID = DP_Hazards[6];
assign WantRtByID = DP_Hazards[5];
assign NeedRtByID = DP_Hazards[4];
assign WantRsByEX = DP_Hazards[3];
assign NeedRsByEX = DP_Hazards[2];
assign WantRtByEX = DP_Hazards[1];
assign NeedRtByEX = DP_Hazards[0];
 
// Trick allowed by RegDst = 0 which gives Rt. MEM_Rt is only used on
// Data Memory write operations (stores), and RegWrite is always 0 in this case.
wire [4:0] MEM_Rt = MEM_RtRd;
// Forwarding should not happen when the src/dst register is $zero
wire EX_RtRd_NZ = (EX_RtRd != 5'b00000);
wire MEM_RtRd_NZ = (MEM_RtRd != 5'b00000);
wire WB_RtRd_NZ = (WB_RtRd != 5'b00000);
// ID Dependencies
wire Rs_IDEX_Match = (ID_Rs == EX_RtRd) & EX_RtRd_NZ & (WantRsByID | NeedRsByID) & EX_RegWrite;
wire Rt_IDEX_Match = (ID_Rt == EX_RtRd) & EX_RtRd_NZ & (WantRtByID | NeedRtByID) & EX_RegWrite;
wire Rs_IDMEM_Match = (ID_Rs == MEM_RtRd) & MEM_RtRd_NZ & (WantRsByID | NeedRsByID) & MEM_RegWrite;
wire Rt_IDMEM_Match = (ID_Rt == MEM_RtRd) & MEM_RtRd_NZ & (WantRtByID | NeedRtByID) & MEM_RegWrite;
wire Rs_IDWB_Match = (ID_Rs == WB_RtRd) & WB_RtRd_NZ & (WantRsByID | NeedRsByID) & WB_RegWrite;
wire Rt_IDWB_Match = (ID_Rt == WB_RtRd) & WB_RtRd_NZ & (WantRtByID | NeedRtByID) & WB_RegWrite;
// EX Dependencies
wire Rs_EXMEM_Match = (EX_Rs == MEM_RtRd) & MEM_RtRd_NZ & (WantRsByEX | NeedRsByEX) & MEM_RegWrite;
wire Rt_EXMEM_Match = (EX_Rt == MEM_RtRd) & MEM_RtRd_NZ & (WantRtByEX | NeedRtByEX) & MEM_RegWrite;
wire Rs_EXWB_Match = (EX_Rs == WB_RtRd) & WB_RtRd_NZ & (WantRsByEX | NeedRsByEX) & WB_RegWrite;
wire Rt_EXWB_Match = (EX_Rt == WB_RtRd) & WB_RtRd_NZ & (WantRtByEX | NeedRtByEX) & WB_RegWrite;
// MEM Dependencies
wire Rt_MEMWB_Match = (MEM_Rt == WB_RtRd) & WB_RtRd_NZ & WB_RegWrite;
// Trick allowed by RegDst = 0 which gives Rt. MEM_Rt is only used on
// Data Memory write operations (stores), and RegWrite is always 0 in this case.
wire [4:0] MEM_Rt = MEM_RtRd;
// Forwarding should not happen when the src/dst register is $zero
wire EX_RtRd_NZ = (EX_RtRd != 5'b00000);
wire MEM_RtRd_NZ = (MEM_RtRd != 5'b00000);
wire WB_RtRd_NZ = (WB_RtRd != 5'b00000);
// ID Dependencies
wire Rs_IDEX_Match = (ID_Rs == EX_RtRd) & EX_RtRd_NZ & (WantRsByID | NeedRsByID) & EX_RegWrite;
wire Rt_IDEX_Match = (ID_Rt == EX_RtRd) & EX_RtRd_NZ & (WantRtByID | NeedRtByID) & EX_RegWrite;
wire Rs_IDMEM_Match = (ID_Rs == MEM_RtRd) & MEM_RtRd_NZ & (WantRsByID | NeedRsByID) & MEM_RegWrite;
wire Rt_IDMEM_Match = (ID_Rt == MEM_RtRd) & MEM_RtRd_NZ & (WantRtByID | NeedRtByID) & MEM_RegWrite;
wire Rs_IDWB_Match = (ID_Rs == WB_RtRd) & WB_RtRd_NZ & (WantRsByID | NeedRsByID) & WB_RegWrite;
wire Rt_IDWB_Match = (ID_Rt == WB_RtRd) & WB_RtRd_NZ & (WantRtByID | NeedRtByID) & WB_RegWrite;
// EX Dependencies
wire Rs_EXMEM_Match = (EX_Rs == MEM_RtRd) & MEM_RtRd_NZ & (WantRsByEX | NeedRsByEX) & MEM_RegWrite;
wire Rt_EXMEM_Match = (EX_Rt == MEM_RtRd) & MEM_RtRd_NZ & (WantRtByEX | NeedRtByEX) & MEM_RegWrite;
wire Rs_EXWB_Match = (EX_Rs == WB_RtRd) & WB_RtRd_NZ & (WantRsByEX | NeedRsByEX) & WB_RegWrite;
wire Rt_EXWB_Match = (EX_Rt == WB_RtRd) & WB_RtRd_NZ & (WantRtByEX | NeedRtByEX) & WB_RegWrite;
// MEM Dependencies
wire Rt_MEMWB_Match = (MEM_Rt == WB_RtRd) & WB_RtRd_NZ & WB_RegWrite;
 
 
// ID needs data from EX : Stall
wire ID_Stall_1 = (Rs_IDEX_Match & NeedRsByID);
wire ID_Stall_2 = (Rt_IDEX_Match & NeedRtByID);
// ID needs data from MEM : Stall if mem access
wire ID_Stall_3 = (Rs_IDMEM_Match & (MEM_MemRead | MEM_MemWrite) & NeedRsByID);
wire ID_Stall_4 = (Rt_IDMEM_Match & (MEM_MemRead | MEM_MemWrite) & NeedRtByID);
// ID wants data from MEM : Forward if not mem access
wire ID_Fwd_1 = (Rs_IDMEM_Match & ~(MEM_MemRead | MEM_MemWrite));
wire ID_Fwd_2 = (Rt_IDMEM_Match & ~(MEM_MemRead | MEM_MemWrite));
// ID wants/needs data from WB : Forward
wire ID_Fwd_3 = (Rs_IDWB_Match);
wire ID_Fwd_4 = (Rt_IDWB_Match);
// EX needs data from MEM : Stall if mem access
wire EX_Stall_1 = (Rs_EXMEM_Match & (MEM_MemRead | MEM_MemWrite) & NeedRsByEX);
wire EX_Stall_2 = (Rt_EXMEM_Match & (MEM_MemRead | MEM_MemWrite) & NeedRtByEX);
// EX wants data from MEM : Forward if not mem access
wire EX_Fwd_1 = (Rs_EXMEM_Match & ~(MEM_MemRead | MEM_MemWrite));
wire EX_Fwd_2 = (Rt_EXMEM_Match & ~(MEM_MemRead | MEM_MemWrite));
// EX wants/needs data from WB : Forward
wire EX_Fwd_3 = (Rs_EXWB_Match);
wire EX_Fwd_4 = (Rt_EXWB_Match);
// MEM needs data from WB : Forward
wire MEM_Fwd_1 = (Rt_MEMWB_Match);
// ID needs data from EX : Stall
wire ID_Stall_1 = (Rs_IDEX_Match & NeedRsByID);
wire ID_Stall_2 = (Rt_IDEX_Match & NeedRtByID);
// ID needs data from MEM : Stall if mem access
wire ID_Stall_3 = (Rs_IDMEM_Match & (MEM_MemRead | MEM_MemWrite) & NeedRsByID);
wire ID_Stall_4 = (Rt_IDMEM_Match & (MEM_MemRead | MEM_MemWrite) & NeedRtByID);
// ID wants data from MEM : Forward if not mem access
wire ID_Fwd_1 = (Rs_IDMEM_Match & ~(MEM_MemRead | MEM_MemWrite));
wire ID_Fwd_2 = (Rt_IDMEM_Match & ~(MEM_MemRead | MEM_MemWrite));
// ID wants/needs data from WB : Forward
wire ID_Fwd_3 = (Rs_IDWB_Match);
wire ID_Fwd_4 = (Rt_IDWB_Match);
// EX needs data from MEM : Stall if mem access
wire EX_Stall_1 = (Rs_EXMEM_Match & (MEM_MemRead | MEM_MemWrite) & NeedRsByEX);
wire EX_Stall_2 = (Rt_EXMEM_Match & (MEM_MemRead | MEM_MemWrite) & NeedRtByEX);
// EX wants data from MEM : Forward if not mem access
wire EX_Fwd_1 = (Rs_EXMEM_Match & ~(MEM_MemRead | MEM_MemWrite));
wire EX_Fwd_2 = (Rt_EXMEM_Match & ~(MEM_MemRead | MEM_MemWrite));
// EX wants/needs data from WB : Forward
wire EX_Fwd_3 = (Rs_EXWB_Match);
wire EX_Fwd_4 = (Rt_EXWB_Match);
// MEM needs data from WB : Forward
wire MEM_Fwd_1 = (Rt_MEMWB_Match);
 
// Stalls and Control Flow Final Assignments
// Stalls and Control Flow Final Assignments
assign WB_Stall = M_Stall;
assign M_Stall = IF_Stall | M_Stall_Controller;
assign EX_Stall = (EX_Stall_1 | EX_Stall_2 | EX_Exception_Stall) | M_Stall;
163,11 → 163,12
assign ID_Stall = (ID_Stall_1 | ID_Stall_2 | ID_Stall_3 | ID_Stall_4 | ID_Exception_Stall) | EX_Stall;
assign IF_Stall = InstMem_Read | InstMem_Ready | IF_Exception_Stall;
// Forwarding Control Final Assignments
assign ID_RsFwdSel = (ID_Link) ? 2'b11 : ((ID_Fwd_1) ? 2'b01 : ((ID_Fwd_3) ? 2'b10 : 2'b00));
assign ID_RtFwdSel = (Mfc0) ? 2'b11 : ((ID_Fwd_2) ? 2'b01 : ((ID_Fwd_4) ? 2'b10 : 2'b00));
// Forwarding Control Final Assignments
assign ID_RsFwdSel = (ID_Link) ? 2'b11 : ((ID_Fwd_1) ? 2'b01 : ((ID_Fwd_3) ? 2'b10 : 2'b00));
assign ID_RtFwdSel = (Mfc0) ? 2'b11 : ((ID_Fwd_2) ? 2'b01 : ((ID_Fwd_4) ? 2'b10 : 2'b00));
assign EX_RsFwdSel = (EX_Fwd_1) ? 2'b01 : ((EX_Fwd_3) ? 2'b10 : 2'b00);
assign EX_RtFwdSel = (EX_Link) ? 2'b11 : ((EX_Fwd_2) ? 2'b01 : ((EX_Fwd_4) ? 2'b10 : 2'b00));
assign M_WriteDataFwdSel = MEM_Fwd_1;
assign EX_RtFwdSel = (EX_Link) ? 2'b11 : ((EX_Fwd_2) ? 2'b01 : ((EX_Fwd_4) ? 2'b10 : 2'b00));
assign M_WriteDataFwdSel = MEM_Fwd_1;
endmodule
 
/XUPV5-LX110T_SoC/MIPS32-Pipelined-Hw/src/Top.ucf
1,15 → 1,15
 
# Clock and Reset
NET "clock_100Mhz" LOC = AH15 | IOSTANDARD = LVCMOS33; # 100 MHz
NET "clock_100MHz" TNM_NET = "BOARD_CLK";
 
# Clock and Reset
NET "clock_100Mhz" LOC = AH15 | IOSTANDARD = LVCMOS33; # 100 MHz
NET "clock_100MHz" TNM_NET = "BOARD_CLK";
TIMESPEC "TS_BOARD_CLK" = PERIOD "BOARD_CLK" 10 ns HIGH 50 %;
NET "reset_n" LOC = E9 | IOSTANDARD = LVCMOS33;
 
# UART
 
# UART
NET "UART_Rx" LOC = AG15 | IOSTANDARD = LVCMOS33;
NET "UART_Tx" LOC = AG20 | IOSTANDARD = LVCMOS33;
 
# LCD Screen
 
# LCD Screen
NET "lcd[6]" LOC = T11 | IOSTANDARD = LVCMOS33; #D_4
NET "lcd[5]" LOC = G6 | IOSTANDARD = LVCMOS33; #D_3
NET "lcd[4]" LOC = G7 | IOSTANDARD = LVCMOS33; #D_2
16,38 → 16,38
NET "lcd[3]" LOC = T9 | IOSTANDARD = LVCMOS33; #D_1
NET "lcd[2]" LOC = AC9 | IOSTANDARD = LVCMOS33; #E
NET "lcd[1]" LOC = J17 | IOSTANDARD = LVCMOS25; #RS
NET "lcd[0]" LOC = AC10 | IOSTANDARD = LVCMOS33; #RW
 
# General-Purpose LEDs
NET "LED[0]" LOC = AE24 | IOSTANDARD = SSTL18_I; # LED 7
NET "LED[1]" LOC = AD24 | IOSTANDARD = SSTL18_I; # LED 6
NET "LED[2]" LOC = AD25 | IOSTANDARD = SSTL18_I; # LED 5
NET "LED[3]" LOC = G16 | IOSTANDARD = LVCMOS25; # LED 4
NET "LED[4]" LOC = AD26 | IOSTANDARD = SSTL18_I; # LED 3
NET "LED[5]" LOC = G15 | IOSTANDARD = LVCMOS25; # LED 2
NET "LED[6]" LOC = L18 | IOSTANDARD = LVCMOS25; # LED 1
NET "LED[7]" LOC = H18 | IOSTANDARD = LVCMOS25; # LED 0
NET "LED[8]" LOC = E8 | IOSTANDARD = LVCMOS33; # LED Center
NET "LED[9]" LOC = AF23 | IOSTANDARD = LVCMOS33; # LED West
NET "LED[10]" LOC = AG12 | IOSTANDARD = LVCMOS33; # LED South
NET "LED[11]" LOC = AG23 | IOSTANDARD = LVCMOS33; # LED East
NET "LED[12]" LOC = AF13 | IOSTANDARD = LVCMOS33; # LED North
NET "LED[13]" LOC = F6 | IOSTANDARD = LVCMOS33; # LED Error 1
NET "LED[14]" LOC = T10 | IOSTANDARD = LVCMOS33; # LED Error 2
 
# Piezo Transducer
NET "Piezo" LOC = G30 | IOSTANDARD = SSTL18_I;
 
# General Purpose Switches
NET "Switch[7]" LOC = U25 | IOSTANDARD = SSTL18_I; # DIP 1
NET "Switch[6]" LOC = AG27 | IOSTANDARD = SSTL18_I; # DIP 2
NET "Switch[5]" LOC = AF25 | IOSTANDARD = SSTL18_I; # DIP 3
NET "Switch[4]" LOC = AF26 | IOSTANDARD = SSTL18_I; # DIP 4
NET "Switch[3]" LOC = AE27 | IOSTANDARD = SSTL18_I; # DIP 5
NET "Switch[2]" LOC = AE26 | IOSTANDARD = SSTL18_I; # DIP 6
NET "Switch[1]" LOC = AC25 | IOSTANDARD = SSTL18_I; # DIP 7
NET "Switch[0]" LOC = AC24 | IOSTANDARD = SSTL18_I; # DIP 8
 
# Main IIC Bus
NET "i2c_scl" LOC = F9 | IOSTANDARD = LVCMOS33; # IIC_Main SCL
NET "i2c_sda" LOC = F8 | IOSTANDARD = LVCMOS33; # IIC_Main SDA
NET "lcd[0]" LOC = AC10 | IOSTANDARD = LVCMOS33; #RW
 
# General-Purpose LEDs
NET "LED[0]" LOC = AE24 | IOSTANDARD = SSTL18_I; # LED 7
NET "LED[1]" LOC = AD24 | IOSTANDARD = SSTL18_I; # LED 6
NET "LED[2]" LOC = AD25 | IOSTANDARD = SSTL18_I; # LED 5
NET "LED[3]" LOC = G16 | IOSTANDARD = LVCMOS25; # LED 4
NET "LED[4]" LOC = AD26 | IOSTANDARD = SSTL18_I; # LED 3
NET "LED[5]" LOC = G15 | IOSTANDARD = LVCMOS25; # LED 2
NET "LED[6]" LOC = L18 | IOSTANDARD = LVCMOS25; # LED 1
NET "LED[7]" LOC = H18 | IOSTANDARD = LVCMOS25; # LED 0
NET "LED[8]" LOC = E8 | IOSTANDARD = LVCMOS33; # LED Center
NET "LED[9]" LOC = AF23 | IOSTANDARD = LVCMOS33; # LED West
NET "LED[10]" LOC = AG12 | IOSTANDARD = LVCMOS33; # LED South
NET "LED[11]" LOC = AG23 | IOSTANDARD = LVCMOS33; # LED East
NET "LED[12]" LOC = AF13 | IOSTANDARD = LVCMOS33; # LED North
NET "LED[13]" LOC = F6 | IOSTANDARD = LVCMOS33; # LED Error 1
NET "LED[14]" LOC = T10 | IOSTANDARD = LVCMOS33; # LED Error 2
 
# Piezo Transducer
NET "Piezo" LOC = G30 | IOSTANDARD = SSTL18_I;
 
# General Purpose Switches
NET "Switch[7]" LOC = U25 | IOSTANDARD = SSTL18_I; # DIP 1
NET "Switch[6]" LOC = AG27 | IOSTANDARD = SSTL18_I; # DIP 2
NET "Switch[5]" LOC = AF25 | IOSTANDARD = SSTL18_I; # DIP 3
NET "Switch[4]" LOC = AF26 | IOSTANDARD = SSTL18_I; # DIP 4
NET "Switch[3]" LOC = AE27 | IOSTANDARD = SSTL18_I; # DIP 5
NET "Switch[2]" LOC = AE26 | IOSTANDARD = SSTL18_I; # DIP 6
NET "Switch[1]" LOC = AC25 | IOSTANDARD = SSTL18_I; # DIP 7
NET "Switch[0]" LOC = AC24 | IOSTANDARD = SSTL18_I; # DIP 8
 
# Main IIC Bus
NET "i2c_scl" LOC = F9 | IOSTANDARD = LVCMOS33; # IIC_Main SCL
NET "i2c_sda" LOC = F8 | IOSTANDARD = LVCMOS33; # IIC_Main SDA
/MIPS32_Standalone/IDEX_Stage.v
114,7 → 114,7
reg [16:0] EX_SignExtImm_pre;
reg EX_RegDst;
assign EX_LinkRegDst = (EX_Link) ? 2'b10 : ((EX_RegDst) ? 2'b01 : 2'b00);
assign EX_LinkRegDst = (EX_Link) ? 2'b10 : ((EX_RegDst) ? 2'b01 : 2'b00);
assign EX_Rd = EX_SignExtImm[15:11];
assign EX_Shamt = EX_SignExtImm[10:6];
assign EX_SignExtImm = (EX_SignExtImm_pre[16]) ? {15'h7fff, EX_SignExtImm_pre[16:0]} : {15'h0000, EX_SignExtImm_pre[16:0]};
156,3 → 156,4
end
 
endmodule
 
/MIPS32_Standalone/MemControl.v
230,3 → 230,4
end
endmodule
 
/MIPS32_Standalone/Processor.v
18,24 → 18,24
* hardware design diagram. It contains very little logic itself.
*/
module Processor(
input clock,
input reset,
input clock,
input reset,
input [4:0] Interrupts, // 5 general-purpose hardware interrupts
input NMI, // Non-maskable interrupt
// Data Memory Interface
input [31:0] DataMem_In,
input DataMem_Ready,
output DataMem_Read,
// Data Memory Interface
input [31:0] DataMem_In,
input DataMem_Ready,
output DataMem_Read,
output [3:0] DataMem_Write, // 4-bit Write, one for each byte in word.
output [29:0] DataMem_Address, // Addresses are words, not bytes.
output [31:0] DataMem_Out,
// Instruction Memory Interface
input [31:0] InstMem_In,
output [29:0] InstMem_Address, // Addresses are words, not bytes.
input InstMem_Ready,
output InstMem_Read,
output [29:0] DataMem_Address, // Addresses are words, not bytes.
output [31:0] DataMem_Out,
// Instruction Memory Interface
input [31:0] InstMem_In,
output [29:0] InstMem_Address, // Addresses are words, not bytes.
input InstMem_Ready,
output InstMem_Read,
output [7:0] IP // Pending interrupts (diagnostic)
);
);
 
`include "MIPS_Parameters.v"
 
674,3 → 674,4
);
 
endmodule
 
/MIPS32_Standalone/Control.v
1,4 → 1,4
`timescale 1ns / 1ps
`timescale 1ns / 1ps
/*
* File : Control.v
* Project : University of Utah, XUM Project MIPS32 core
19,26 → 19,26
* the effective operation of the processor through each pipeline stage.
*/
module Control(
input ID_Stall,
input [5:0] OpCode,
input [5:0] Funct,
input [4:0] Rs, // used to differentiate mfc0 and mtc0
input [4:0] Rt, // used to differentiate bgez,bgezal,bltz,bltzal,teqi,tgei,tgeiu,tlti,tltiu,tnei
input Cmp_EQ,
input Cmp_GZ,
input Cmp_GEZ,
input Cmp_LZ,
input Cmp_LEZ,
//------------
output IF_Flush,
output reg [7:0] DP_Hazards,
output [1:0] PCSrc,
output SignExtend,
output Link,
output Movn,
input ID_Stall,
input [5:0] OpCode,
input [5:0] Funct,
input [4:0] Rs, // used to differentiate mfc0 and mtc0
input [4:0] Rt, // used to differentiate bgez,bgezal,bltz,bltzal,teqi,tgei,tgeiu,tlti,tltiu,tnei
input Cmp_EQ,
input Cmp_GZ,
input Cmp_GEZ,
input Cmp_LZ,
input Cmp_LEZ,
//------------
output IF_Flush,
output reg [7:0] DP_Hazards,
output [1:0] PCSrc,
output SignExtend,
output Link,
output Movn,
output Movz,
output Mfc0,
output Mtc0,
output Mfc0,
output Mtc0,
output CP1,
output CP2,
output CP3,
51,28 → 51,28
output ID_CanErr,
output EX_CanErr,
output M_CanErr,
output NextIsDelay,
output RegDst,
output ALUSrcImm,
output reg [4:0] ALUOp,
output NextIsDelay,
output RegDst,
output ALUSrcImm,
output reg [4:0] ALUOp,
output LLSC,
output MemWrite,
output MemRead,
output MemByte,
output MemHalf,
output MemSignExtend,
output MemWrite,
output MemRead,
output MemByte,
output MemHalf,
output MemSignExtend,
output Left,
output Right,
output RegWrite,
output MemtoReg
);
`include "MIPS_Parameters.v"
output RegWrite,
output MemtoReg
);
`include "MIPS_Parameters.v"
 
wire Movc;
wire Branch, Branch_EQ, Branch_GTZ, Branch_LEZ, Branch_NEQ, Branch_GEZ, Branch_LTZ;
wire Movc;
wire Branch, Branch_EQ, Branch_GTZ, Branch_LEZ, Branch_NEQ, Branch_GEZ, Branch_LTZ;
wire Unaligned_Mem;
reg [15:0] Datapath;
assign PCSrc[0] = Datapath[14];
assign Link = Datapath[13];
94,356 → 94,356
assign ID_CanErr = DP_Exceptions[2];
assign EX_CanErr = DP_Exceptions[1];
assign M_CanErr = DP_Exceptions[0];
// Set the main datapath control signals based on the Op Code
always @(*) begin
if (ID_Stall)
Datapath <= DP_None;
else begin
case (OpCode)
// R-Type
Op_Type_R :
begin
case (Funct)
Funct_Add : Datapath <= DP_Add;
Funct_Addu : Datapath <= DP_Addu;
Funct_And : Datapath <= DP_And;
Funct_Break : Datapath <= DP_Break;
Funct_Div : Datapath <= DP_Div;
Funct_Divu : Datapath <= DP_Divu;
Funct_Jalr : Datapath <= DP_Jalr;
Funct_Jr : Datapath <= DP_Jr;
Funct_Mfhi : Datapath <= DP_Mfhi;
Funct_Mflo : Datapath <= DP_Mflo;
Funct_Movn : Datapath <= DP_Movn;
Funct_Movz : Datapath <= DP_Movz;
Funct_Mthi : Datapath <= DP_Mthi;
Funct_Mtlo : Datapath <= DP_Mtlo;
Funct_Mult : Datapath <= DP_Mult;
Funct_Multu : Datapath <= DP_Multu;
Funct_Nor : Datapath <= DP_Nor;
Funct_Or : Datapath <= DP_Or;
Funct_Sll : Datapath <= DP_Sll;
Funct_Sllv : Datapath <= DP_Sllv;
Funct_Slt : Datapath <= DP_Slt;
Funct_Sltu : Datapath <= DP_Sltu;
Funct_Sra : Datapath <= DP_Sra;
Funct_Srav : Datapath <= DP_Srav;
Funct_Srl : Datapath <= DP_Srl;
Funct_Srlv : Datapath <= DP_Srlv;
Funct_Sub : Datapath <= DP_Sub;
Funct_Subu : Datapath <= DP_Subu;
Funct_Syscall : Datapath <= DP_Syscall;
Funct_Teq : Datapath <= DP_Teq;
Funct_Tge : Datapath <= DP_Tge;
Funct_Tgeu : Datapath <= DP_Tgeu;
Funct_Tlt : Datapath <= DP_Tlt;
Funct_Tltu : Datapath <= DP_Tltu;
Funct_Tne : Datapath <= DP_Tne;
Funct_Xor : Datapath <= DP_Xor;
default : Datapath <= DP_None;
endcase
end
// R2-Type
Op_Type_R2 :
begin
case (Funct)
Funct_Clo : Datapath <= DP_Clo;
Funct_Clz : Datapath <= DP_Clz;
Funct_Madd : Datapath <= DP_Madd;
Funct_Maddu : Datapath <= DP_Maddu;
Funct_Msub : Datapath <= DP_Msub;
Funct_Msubu : Datapath <= DP_Msubu;
Funct_Mul : Datapath <= DP_Mul;
default : Datapath <= DP_None;
endcase
end
// I-Type
Op_Addi : Datapath <= DP_Addi;
Op_Addiu : Datapath <= DP_Addiu;
Op_Andi : Datapath <= DP_Andi;
Op_Ori : Datapath <= DP_Ori;
Op_Pref : Datapath <= DP_Pref;
Op_Slti : Datapath <= DP_Slti;
Op_Sltiu : Datapath <= DP_Sltiu;
Op_Xori : Datapath <= DP_Xori;
// Jumps (using immediates)
Op_J : Datapath <= DP_J;
Op_Jal : Datapath <= DP_Jal;
// Branches and Traps
Op_Type_BI :
begin
case (Rt)
OpRt_Bgez : Datapath <= DP_Bgez;
OpRt_Bgezal : Datapath <= DP_Bgezal;
OpRt_Bltz : Datapath <= DP_Bltz;
OpRt_Bltzal : Datapath <= DP_Bltzal;
OpRt_Teqi : Datapath <= DP_Teqi;
OpRt_Tgei : Datapath <= DP_Tgei;
OpRt_Tgeiu : Datapath <= DP_Tgeiu;
OpRt_Tlti : Datapath <= DP_Tlti;
OpRt_Tltiu : Datapath <= DP_Tltiu;
OpRt_Tnei : Datapath <= DP_Tnei;
default : Datapath <= DP_None;
endcase
end
Op_Beq : Datapath <= DP_Beq;
Op_Bgtz : Datapath <= DP_Bgtz;
Op_Blez : Datapath <= DP_Blez;
Op_Bne : Datapath <= DP_Bne;
// Coprocessor 0
Op_Type_CP0 :
begin
case (Rs)
OpRs_MF : Datapath <= DP_Mfc0;
OpRs_MT : Datapath <= DP_Mtc0;
// Set the main datapath control signals based on the Op Code
always @(*) begin
if (ID_Stall)
Datapath <= DP_None;
else begin
case (OpCode)
// R-Type
Op_Type_R :
begin
case (Funct)
Funct_Add : Datapath <= DP_Add;
Funct_Addu : Datapath <= DP_Addu;
Funct_And : Datapath <= DP_And;
Funct_Break : Datapath <= DP_Break;
Funct_Div : Datapath <= DP_Div;
Funct_Divu : Datapath <= DP_Divu;
Funct_Jalr : Datapath <= DP_Jalr;
Funct_Jr : Datapath <= DP_Jr;
Funct_Mfhi : Datapath <= DP_Mfhi;
Funct_Mflo : Datapath <= DP_Mflo;
Funct_Movn : Datapath <= DP_Movn;
Funct_Movz : Datapath <= DP_Movz;
Funct_Mthi : Datapath <= DP_Mthi;
Funct_Mtlo : Datapath <= DP_Mtlo;
Funct_Mult : Datapath <= DP_Mult;
Funct_Multu : Datapath <= DP_Multu;
Funct_Nor : Datapath <= DP_Nor;
Funct_Or : Datapath <= DP_Or;
Funct_Sll : Datapath <= DP_Sll;
Funct_Sllv : Datapath <= DP_Sllv;
Funct_Slt : Datapath <= DP_Slt;
Funct_Sltu : Datapath <= DP_Sltu;
Funct_Sra : Datapath <= DP_Sra;
Funct_Srav : Datapath <= DP_Srav;
Funct_Srl : Datapath <= DP_Srl;
Funct_Srlv : Datapath <= DP_Srlv;
Funct_Sub : Datapath <= DP_Sub;
Funct_Subu : Datapath <= DP_Subu;
Funct_Syscall : Datapath <= DP_Syscall;
Funct_Teq : Datapath <= DP_Teq;
Funct_Tge : Datapath <= DP_Tge;
Funct_Tgeu : Datapath <= DP_Tgeu;
Funct_Tlt : Datapath <= DP_Tlt;
Funct_Tltu : Datapath <= DP_Tltu;
Funct_Tne : Datapath <= DP_Tne;
Funct_Xor : Datapath <= DP_Xor;
default : Datapath <= DP_None;
endcase
end
// R2-Type
Op_Type_R2 :
begin
case (Funct)
Funct_Clo : Datapath <= DP_Clo;
Funct_Clz : Datapath <= DP_Clz;
Funct_Madd : Datapath <= DP_Madd;
Funct_Maddu : Datapath <= DP_Maddu;
Funct_Msub : Datapath <= DP_Msub;
Funct_Msubu : Datapath <= DP_Msubu;
Funct_Mul : Datapath <= DP_Mul;
default : Datapath <= DP_None;
endcase
end
// I-Type
Op_Addi : Datapath <= DP_Addi;
Op_Addiu : Datapath <= DP_Addiu;
Op_Andi : Datapath <= DP_Andi;
Op_Ori : Datapath <= DP_Ori;
Op_Pref : Datapath <= DP_Pref;
Op_Slti : Datapath <= DP_Slti;
Op_Sltiu : Datapath <= DP_Sltiu;
Op_Xori : Datapath <= DP_Xori;
// Jumps (using immediates)
Op_J : Datapath <= DP_J;
Op_Jal : Datapath <= DP_Jal;
// Branches and Traps
Op_Type_BI :
begin
case (Rt)
OpRt_Bgez : Datapath <= DP_Bgez;
OpRt_Bgezal : Datapath <= DP_Bgezal;
OpRt_Bltz : Datapath <= DP_Bltz;
OpRt_Bltzal : Datapath <= DP_Bltzal;
OpRt_Teqi : Datapath <= DP_Teqi;
OpRt_Tgei : Datapath <= DP_Tgei;
OpRt_Tgeiu : Datapath <= DP_Tgeiu;
OpRt_Tlti : Datapath <= DP_Tlti;
OpRt_Tltiu : Datapath <= DP_Tltiu;
OpRt_Tnei : Datapath <= DP_Tnei;
default : Datapath <= DP_None;
endcase
end
Op_Beq : Datapath <= DP_Beq;
Op_Bgtz : Datapath <= DP_Bgtz;
Op_Blez : Datapath <= DP_Blez;
Op_Bne : Datapath <= DP_Bne;
// Coprocessor 0
Op_Type_CP0 :
begin
case (Rs)
OpRs_MF : Datapath <= DP_Mfc0;
OpRs_MT : Datapath <= DP_Mtc0;
OpRs_ERET : Datapath <= (Funct == Funct_ERET) ? DP_Eret : DP_None;
default : Datapath <= DP_None;
endcase
end
// Memory
Op_Lb : Datapath <= DP_Lb;
Op_Lbu : Datapath <= DP_Lbu;
Op_Lh : Datapath <= DP_Lh;
Op_Lhu : Datapath <= DP_Lhu;
Op_Ll : Datapath <= DP_Ll;
Op_Lui : Datapath <= DP_Lui;
Op_Lw : Datapath <= DP_Lw;
Op_Lwl : Datapath <= DP_Lwl;
Op_Lwr : Datapath <= DP_Lwr;
Op_Sb : Datapath <= DP_Sb;
Op_Sc : Datapath <= DP_Sc;
Op_Sh : Datapath <= DP_Sh;
Op_Sw : Datapath <= DP_Sw;
Op_Swl : Datapath <= DP_Swl;
Op_Swr : Datapath <= DP_Swr;
default : Datapath <= DP_None;
endcase
end
end
default : Datapath <= DP_None;
endcase
end
// Memory
Op_Lb : Datapath <= DP_Lb;
Op_Lbu : Datapath <= DP_Lbu;
Op_Lh : Datapath <= DP_Lh;
Op_Lhu : Datapath <= DP_Lhu;
Op_Ll : Datapath <= DP_Ll;
Op_Lui : Datapath <= DP_Lui;
Op_Lw : Datapath <= DP_Lw;
Op_Lwl : Datapath <= DP_Lwl;
Op_Lwr : Datapath <= DP_Lwr;
Op_Sb : Datapath <= DP_Sb;
Op_Sc : Datapath <= DP_Sc;
Op_Sh : Datapath <= DP_Sh;
Op_Sw : Datapath <= DP_Sw;
Op_Swl : Datapath <= DP_Swl;
Op_Swr : Datapath <= DP_Swr;
default : Datapath <= DP_None;
endcase
end
end
 
// Set the Hazard Control Signals and Exception Indicators based on the Op Code
always @(*) begin
case (OpCode)
// R-Type
Op_Type_R :
begin
case (Funct)
Funct_Add : begin DP_Hazards <= HAZ_Add; DP_Exceptions <= EXC_Add; end
Funct_Addu : begin DP_Hazards <= HAZ_Addu; DP_Exceptions <= EXC_Addu; end
Funct_And : begin DP_Hazards <= HAZ_And; DP_Exceptions <= EXC_And; end
Funct_Break : begin DP_Hazards <= HAZ_Break; DP_Exceptions <= EXC_Break; end
Funct_Div : begin DP_Hazards <= HAZ_Div; DP_Exceptions <= EXC_Div; end
Funct_Divu : begin DP_Hazards <= HAZ_Divu; DP_Exceptions <= EXC_Divu; end
Funct_Jalr : begin DP_Hazards <= HAZ_Jalr; DP_Exceptions <= EXC_Jalr; end
Funct_Jr : begin DP_Hazards <= HAZ_Jr; DP_Exceptions <= EXC_Jr; end
Funct_Mfhi : begin DP_Hazards <= HAZ_Mfhi; DP_Exceptions <= EXC_Mfhi; end
Funct_Mflo : begin DP_Hazards <= HAZ_Mflo; DP_Exceptions <= EXC_Mflo; end
Funct_Movn : begin DP_Hazards <= HAZ_Movn; DP_Exceptions <= EXC_Movn; end
Funct_Movz : begin DP_Hazards <= HAZ_Movz; DP_Exceptions <= EXC_Movz; end
Funct_Mthi : begin DP_Hazards <= HAZ_Mthi; DP_Exceptions <= EXC_Mthi; end
Funct_Mtlo : begin DP_Hazards <= HAZ_Mtlo; DP_Exceptions <= EXC_Mtlo; end
Funct_Mult : begin DP_Hazards <= HAZ_Mult; DP_Exceptions <= EXC_Mult; end
Funct_Multu : begin DP_Hazards <= HAZ_Multu; DP_Exceptions <= EXC_Multu; end
Funct_Nor : begin DP_Hazards <= HAZ_Nor; DP_Exceptions <= EXC_Nor; end
Funct_Or : begin DP_Hazards <= HAZ_Or; DP_Exceptions <= EXC_Or; end
Funct_Sll : begin DP_Hazards <= HAZ_Sll; DP_Exceptions <= EXC_Sll; end
Funct_Sllv : begin DP_Hazards <= HAZ_Sllv; DP_Exceptions <= EXC_Sllv; end
Funct_Slt : begin DP_Hazards <= HAZ_Slt; DP_Exceptions <= EXC_Slt; end
Funct_Sltu : begin DP_Hazards <= HAZ_Sltu; DP_Exceptions <= EXC_Sltu; end
Funct_Sra : begin DP_Hazards <= HAZ_Sra; DP_Exceptions <= EXC_Sra; end
Funct_Srav : begin DP_Hazards <= HAZ_Srav; DP_Exceptions <= EXC_Srav; end
Funct_Srl : begin DP_Hazards <= HAZ_Srl; DP_Exceptions <= EXC_Srl; end
Funct_Srlv : begin DP_Hazards <= HAZ_Srlv; DP_Exceptions <= EXC_Srlv; end
Funct_Sub : begin DP_Hazards <= HAZ_Sub; DP_Exceptions <= EXC_Sub; end
Funct_Subu : begin DP_Hazards <= HAZ_Subu; DP_Exceptions <= EXC_Subu; end
Funct_Syscall : begin DP_Hazards <= HAZ_Syscall; DP_Exceptions <= EXC_Syscall; end
Funct_Teq : begin DP_Hazards <= HAZ_Teq; DP_Exceptions <= EXC_Teq; end
Funct_Tge : begin DP_Hazards <= HAZ_Tge; DP_Exceptions <= EXC_Tge; end
Funct_Tgeu : begin DP_Hazards <= HAZ_Tgeu; DP_Exceptions <= EXC_Tgeu; end
Funct_Tlt : begin DP_Hazards <= HAZ_Tlt; DP_Exceptions <= EXC_Tlt; end
Funct_Tltu : begin DP_Hazards <= HAZ_Tltu; DP_Exceptions <= EXC_Tltu; end
Funct_Tne : begin DP_Hazards <= HAZ_Tne; DP_Exceptions <= EXC_Tne; end
Funct_Xor : begin DP_Hazards <= HAZ_Xor; DP_Exceptions <= EXC_Xor; end
default : begin DP_Hazards <= 8'hxx; DP_Exceptions <= 3'bxxx; end
endcase
end
// R2-Type
Op_Type_R2 :
begin
case (Funct)
Funct_Clo : begin DP_Hazards <= HAZ_Clo; DP_Exceptions <= EXC_Clo; end
Funct_Clz : begin DP_Hazards <= HAZ_Clz; DP_Exceptions <= EXC_Clz; end
Funct_Madd : begin DP_Hazards <= HAZ_Madd; DP_Exceptions <= EXC_Madd; end
Funct_Maddu : begin DP_Hazards <= HAZ_Maddu; DP_Exceptions <= EXC_Maddu; end
Funct_Msub : begin DP_Hazards <= HAZ_Msub; DP_Exceptions <= EXC_Msub; end
Funct_Msubu : begin DP_Hazards <= HAZ_Msubu; DP_Exceptions <= EXC_Msubu; end
Funct_Mul : begin DP_Hazards <= HAZ_Mul; DP_Exceptions <= EXC_Mul; end
default : begin DP_Hazards <= 8'hxx; DP_Exceptions <= 3'bxxx; end
endcase
end
// I-Type
Op_Addi : begin DP_Hazards <= HAZ_Addi; DP_Exceptions <= EXC_Addi; end
Op_Addiu : begin DP_Hazards <= HAZ_Addiu; DP_Exceptions <= EXC_Addiu; end
Op_Andi : begin DP_Hazards <= HAZ_Andi; DP_Exceptions <= EXC_Andi; end
Op_Ori : begin DP_Hazards <= HAZ_Ori; DP_Exceptions <= EXC_Ori; end
Op_Pref : begin DP_Hazards <= HAZ_Pref; DP_Exceptions <= EXC_Pref; end
Op_Slti : begin DP_Hazards <= HAZ_Slti; DP_Exceptions <= EXC_Slti; end
Op_Sltiu : begin DP_Hazards <= HAZ_Sltiu; DP_Exceptions <= EXC_Sltiu; end
Op_Xori : begin DP_Hazards <= HAZ_Xori; DP_Exceptions <= EXC_Xori; end
// Jumps
Op_J : begin DP_Hazards <= HAZ_J; DP_Exceptions <= EXC_J; end
Op_Jal : begin DP_Hazards <= HAZ_Jal; DP_Exceptions <= EXC_Jal; end
// Branches and Traps
Op_Type_BI :
begin
case (Rt)
OpRt_Bgez : begin DP_Hazards <= HAZ_Bgez; DP_Exceptions <= EXC_Bgez; end
OpRt_Bgezal : begin DP_Hazards <= HAZ_Bgezal; DP_Exceptions <= EXC_Bgezal; end
OpRt_Bltz : begin DP_Hazards <= HAZ_Bltz; DP_Exceptions <= EXC_Bltz; end
OpRt_Bltzal : begin DP_Hazards <= HAZ_Bltzal; DP_Exceptions <= EXC_Bltzal; end
OpRt_Teqi : begin DP_Hazards <= HAZ_Teqi; DP_Exceptions <= EXC_Teqi; end
OpRt_Tgei : begin DP_Hazards <= HAZ_Tgei; DP_Exceptions <= EXC_Tgei; end
OpRt_Tgeiu : begin DP_Hazards <= HAZ_Tgeiu; DP_Exceptions <= EXC_Tgeiu; end
OpRt_Tlti : begin DP_Hazards <= HAZ_Tlti; DP_Exceptions <= EXC_Tlti; end
OpRt_Tltiu : begin DP_Hazards <= HAZ_Tltiu; DP_Exceptions <= EXC_Tltiu; end
OpRt_Tnei : begin DP_Hazards <= HAZ_Tnei; DP_Exceptions <= EXC_Tnei; end
default : begin DP_Hazards <= 8'hxx; DP_Exceptions <= 3'bxxx; end
endcase
end
Op_Beq : begin DP_Hazards <= HAZ_Beq; DP_Exceptions <= EXC_Beq; end
Op_Bgtz : begin DP_Hazards <= HAZ_Bgtz; DP_Exceptions <= EXC_Bgtz; end
Op_Blez : begin DP_Hazards <= HAZ_Blez; DP_Exceptions <= EXC_Blez; end
Op_Bne : begin DP_Hazards <= HAZ_Bne; DP_Exceptions <= EXC_Bne; end
// Coprocessor 0
Op_Type_CP0 :
begin
case (Rs)
OpRs_MF : begin DP_Hazards <= HAZ_Mfc0; DP_Exceptions <= EXC_Mfc0; end
OpRs_MT : begin DP_Hazards <= HAZ_Mtc0; DP_Exceptions <= EXC_Mtc0; end
// Set the Hazard Control Signals and Exception Indicators based on the Op Code
always @(*) begin
case (OpCode)
// R-Type
Op_Type_R :
begin
case (Funct)
Funct_Add : begin DP_Hazards <= HAZ_Add; DP_Exceptions <= EXC_Add; end
Funct_Addu : begin DP_Hazards <= HAZ_Addu; DP_Exceptions <= EXC_Addu; end
Funct_And : begin DP_Hazards <= HAZ_And; DP_Exceptions <= EXC_And; end
Funct_Break : begin DP_Hazards <= HAZ_Break; DP_Exceptions <= EXC_Break; end
Funct_Div : begin DP_Hazards <= HAZ_Div; DP_Exceptions <= EXC_Div; end
Funct_Divu : begin DP_Hazards <= HAZ_Divu; DP_Exceptions <= EXC_Divu; end
Funct_Jalr : begin DP_Hazards <= HAZ_Jalr; DP_Exceptions <= EXC_Jalr; end
Funct_Jr : begin DP_Hazards <= HAZ_Jr; DP_Exceptions <= EXC_Jr; end
Funct_Mfhi : begin DP_Hazards <= HAZ_Mfhi; DP_Exceptions <= EXC_Mfhi; end
Funct_Mflo : begin DP_Hazards <= HAZ_Mflo; DP_Exceptions <= EXC_Mflo; end
Funct_Movn : begin DP_Hazards <= HAZ_Movn; DP_Exceptions <= EXC_Movn; end
Funct_Movz : begin DP_Hazards <= HAZ_Movz; DP_Exceptions <= EXC_Movz; end
Funct_Mthi : begin DP_Hazards <= HAZ_Mthi; DP_Exceptions <= EXC_Mthi; end
Funct_Mtlo : begin DP_Hazards <= HAZ_Mtlo; DP_Exceptions <= EXC_Mtlo; end
Funct_Mult : begin DP_Hazards <= HAZ_Mult; DP_Exceptions <= EXC_Mult; end
Funct_Multu : begin DP_Hazards <= HAZ_Multu; DP_Exceptions <= EXC_Multu; end
Funct_Nor : begin DP_Hazards <= HAZ_Nor; DP_Exceptions <= EXC_Nor; end
Funct_Or : begin DP_Hazards <= HAZ_Or; DP_Exceptions <= EXC_Or; end
Funct_Sll : begin DP_Hazards <= HAZ_Sll; DP_Exceptions <= EXC_Sll; end
Funct_Sllv : begin DP_Hazards <= HAZ_Sllv; DP_Exceptions <= EXC_Sllv; end
Funct_Slt : begin DP_Hazards <= HAZ_Slt; DP_Exceptions <= EXC_Slt; end
Funct_Sltu : begin DP_Hazards <= HAZ_Sltu; DP_Exceptions <= EXC_Sltu; end
Funct_Sra : begin DP_Hazards <= HAZ_Sra; DP_Exceptions <= EXC_Sra; end
Funct_Srav : begin DP_Hazards <= HAZ_Srav; DP_Exceptions <= EXC_Srav; end
Funct_Srl : begin DP_Hazards <= HAZ_Srl; DP_Exceptions <= EXC_Srl; end
Funct_Srlv : begin DP_Hazards <= HAZ_Srlv; DP_Exceptions <= EXC_Srlv; end
Funct_Sub : begin DP_Hazards <= HAZ_Sub; DP_Exceptions <= EXC_Sub; end
Funct_Subu : begin DP_Hazards <= HAZ_Subu; DP_Exceptions <= EXC_Subu; end
Funct_Syscall : begin DP_Hazards <= HAZ_Syscall; DP_Exceptions <= EXC_Syscall; end
Funct_Teq : begin DP_Hazards <= HAZ_Teq; DP_Exceptions <= EXC_Teq; end
Funct_Tge : begin DP_Hazards <= HAZ_Tge; DP_Exceptions <= EXC_Tge; end
Funct_Tgeu : begin DP_Hazards <= HAZ_Tgeu; DP_Exceptions <= EXC_Tgeu; end
Funct_Tlt : begin DP_Hazards <= HAZ_Tlt; DP_Exceptions <= EXC_Tlt; end
Funct_Tltu : begin DP_Hazards <= HAZ_Tltu; DP_Exceptions <= EXC_Tltu; end
Funct_Tne : begin DP_Hazards <= HAZ_Tne; DP_Exceptions <= EXC_Tne; end
Funct_Xor : begin DP_Hazards <= HAZ_Xor; DP_Exceptions <= EXC_Xor; end
default : begin DP_Hazards <= 8'hxx; DP_Exceptions <= 3'bxxx; end
endcase
end
// R2-Type
Op_Type_R2 :
begin
case (Funct)
Funct_Clo : begin DP_Hazards <= HAZ_Clo; DP_Exceptions <= EXC_Clo; end
Funct_Clz : begin DP_Hazards <= HAZ_Clz; DP_Exceptions <= EXC_Clz; end
Funct_Madd : begin DP_Hazards <= HAZ_Madd; DP_Exceptions <= EXC_Madd; end
Funct_Maddu : begin DP_Hazards <= HAZ_Maddu; DP_Exceptions <= EXC_Maddu; end
Funct_Msub : begin DP_Hazards <= HAZ_Msub; DP_Exceptions <= EXC_Msub; end
Funct_Msubu : begin DP_Hazards <= HAZ_Msubu; DP_Exceptions <= EXC_Msubu; end
Funct_Mul : begin DP_Hazards <= HAZ_Mul; DP_Exceptions <= EXC_Mul; end
default : begin DP_Hazards <= 8'hxx; DP_Exceptions <= 3'bxxx; end
endcase
end
// I-Type
Op_Addi : begin DP_Hazards <= HAZ_Addi; DP_Exceptions <= EXC_Addi; end
Op_Addiu : begin DP_Hazards <= HAZ_Addiu; DP_Exceptions <= EXC_Addiu; end
Op_Andi : begin DP_Hazards <= HAZ_Andi; DP_Exceptions <= EXC_Andi; end
Op_Ori : begin DP_Hazards <= HAZ_Ori; DP_Exceptions <= EXC_Ori; end
Op_Pref : begin DP_Hazards <= HAZ_Pref; DP_Exceptions <= EXC_Pref; end
Op_Slti : begin DP_Hazards <= HAZ_Slti; DP_Exceptions <= EXC_Slti; end
Op_Sltiu : begin DP_Hazards <= HAZ_Sltiu; DP_Exceptions <= EXC_Sltiu; end
Op_Xori : begin DP_Hazards <= HAZ_Xori; DP_Exceptions <= EXC_Xori; end
// Jumps
Op_J : begin DP_Hazards <= HAZ_J; DP_Exceptions <= EXC_J; end
Op_Jal : begin DP_Hazards <= HAZ_Jal; DP_Exceptions <= EXC_Jal; end
// Branches and Traps
Op_Type_BI :
begin
case (Rt)
OpRt_Bgez : begin DP_Hazards <= HAZ_Bgez; DP_Exceptions <= EXC_Bgez; end
OpRt_Bgezal : begin DP_Hazards <= HAZ_Bgezal; DP_Exceptions <= EXC_Bgezal; end
OpRt_Bltz : begin DP_Hazards <= HAZ_Bltz; DP_Exceptions <= EXC_Bltz; end
OpRt_Bltzal : begin DP_Hazards <= HAZ_Bltzal; DP_Exceptions <= EXC_Bltzal; end
OpRt_Teqi : begin DP_Hazards <= HAZ_Teqi; DP_Exceptions <= EXC_Teqi; end
OpRt_Tgei : begin DP_Hazards <= HAZ_Tgei; DP_Exceptions <= EXC_Tgei; end
OpRt_Tgeiu : begin DP_Hazards <= HAZ_Tgeiu; DP_Exceptions <= EXC_Tgeiu; end
OpRt_Tlti : begin DP_Hazards <= HAZ_Tlti; DP_Exceptions <= EXC_Tlti; end
OpRt_Tltiu : begin DP_Hazards <= HAZ_Tltiu; DP_Exceptions <= EXC_Tltiu; end
OpRt_Tnei : begin DP_Hazards <= HAZ_Tnei; DP_Exceptions <= EXC_Tnei; end
default : begin DP_Hazards <= 8'hxx; DP_Exceptions <= 3'bxxx; end
endcase
end
Op_Beq : begin DP_Hazards <= HAZ_Beq; DP_Exceptions <= EXC_Beq; end
Op_Bgtz : begin DP_Hazards <= HAZ_Bgtz; DP_Exceptions <= EXC_Bgtz; end
Op_Blez : begin DP_Hazards <= HAZ_Blez; DP_Exceptions <= EXC_Blez; end
Op_Bne : begin DP_Hazards <= HAZ_Bne; DP_Exceptions <= EXC_Bne; end
// Coprocessor 0
Op_Type_CP0 :
begin
case (Rs)
OpRs_MF : begin DP_Hazards <= HAZ_Mfc0; DP_Exceptions <= EXC_Mfc0; end
OpRs_MT : begin DP_Hazards <= HAZ_Mtc0; DP_Exceptions <= EXC_Mtc0; end
OpRs_ERET : begin DP_Hazards <= (Funct == Funct_ERET) ? DP_Eret : 8'hxx; DP_Exceptions <= EXC_Eret; end
default : begin DP_Hazards <= 8'hxx; DP_Exceptions <= 3'bxxx; end
endcase
end
// Memory
Op_Lb : begin DP_Hazards <= HAZ_Lb; DP_Exceptions <= EXC_Lb; end
Op_Lbu : begin DP_Hazards <= HAZ_Lbu; DP_Exceptions <= EXC_Lbu; end
Op_Lh : begin DP_Hazards <= HAZ_Lh; DP_Exceptions <= EXC_Lh; end
Op_Lhu : begin DP_Hazards <= HAZ_Lhu; DP_Exceptions <= EXC_Lhu; end
Op_Ll : begin DP_Hazards <= HAZ_Ll; DP_Exceptions <= EXC_Ll; end
Op_Lui : begin DP_Hazards <= HAZ_Lui; DP_Exceptions <= EXC_Lui; end
Op_Lw : begin DP_Hazards <= HAZ_Lw; DP_Exceptions <= EXC_Lw; end
Op_Lwl : begin DP_Hazards <= HAZ_Lwl; DP_Exceptions <= EXC_Lwl; end
Op_Lwr : begin DP_Hazards <= HAZ_Lwr; DP_Exceptions <= EXC_Lwr; end
Op_Sb : begin DP_Hazards <= HAZ_Sb; DP_Exceptions <= EXC_Sb; end
Op_Sc : begin DP_Hazards <= HAZ_Sc; DP_Exceptions <= EXC_Sc; end
Op_Sh : begin DP_Hazards <= HAZ_Sh; DP_Exceptions <= EXC_Sh; end
Op_Sw : begin DP_Hazards <= HAZ_Sw; DP_Exceptions <= EXC_Sw; end
Op_Swl : begin DP_Hazards <= HAZ_Swl; DP_Exceptions <= EXC_Swl; end
Op_Swr : begin DP_Hazards <= HAZ_Swr; DP_Exceptions <= EXC_Swr; end
default : begin DP_Hazards <= 8'hxx; DP_Exceptions <= 3'bxxx; end
endcase
end
default : begin DP_Hazards <= 8'hxx; DP_Exceptions <= 3'bxxx; end
endcase
end
// Memory
Op_Lb : begin DP_Hazards <= HAZ_Lb; DP_Exceptions <= EXC_Lb; end
Op_Lbu : begin DP_Hazards <= HAZ_Lbu; DP_Exceptions <= EXC_Lbu; end
Op_Lh : begin DP_Hazards <= HAZ_Lh; DP_Exceptions <= EXC_Lh; end
Op_Lhu : begin DP_Hazards <= HAZ_Lhu; DP_Exceptions <= EXC_Lhu; end
Op_Ll : begin DP_Hazards <= HAZ_Ll; DP_Exceptions <= EXC_Ll; end
Op_Lui : begin DP_Hazards <= HAZ_Lui; DP_Exceptions <= EXC_Lui; end
Op_Lw : begin DP_Hazards <= HAZ_Lw; DP_Exceptions <= EXC_Lw; end
Op_Lwl : begin DP_Hazards <= HAZ_Lwl; DP_Exceptions <= EXC_Lwl; end
Op_Lwr : begin DP_Hazards <= HAZ_Lwr; DP_Exceptions <= EXC_Lwr; end
Op_Sb : begin DP_Hazards <= HAZ_Sb; DP_Exceptions <= EXC_Sb; end
Op_Sc : begin DP_Hazards <= HAZ_Sc; DP_Exceptions <= EXC_Sc; end
Op_Sh : begin DP_Hazards <= HAZ_Sh; DP_Exceptions <= EXC_Sh; end
Op_Sw : begin DP_Hazards <= HAZ_Sw; DP_Exceptions <= EXC_Sw; end
Op_Swl : begin DP_Hazards <= HAZ_Swl; DP_Exceptions <= EXC_Swl; end
Op_Swr : begin DP_Hazards <= HAZ_Swr; DP_Exceptions <= EXC_Swr; end
default : begin DP_Hazards <= 8'hxx; DP_Exceptions <= 3'bxxx; end
endcase
end
 
// ALU Assignment
always @(*) begin
if (ID_Stall)
ALUOp <= AluOp_Addu; // Any Op that doesn't write HILO or cause exceptions
else begin
case (OpCode)
Op_Type_R :
begin
case (Funct)
Funct_Add : ALUOp <= AluOp_Add;
Funct_Addu : ALUOp <= AluOp_Addu;
Funct_And : ALUOp <= AluOp_And;
Funct_Div : ALUOp <= AluOp_Div;
Funct_Divu : ALUOp <= AluOp_Divu;
Funct_Jalr : ALUOp <= AluOp_Addu;
Funct_Mfhi : ALUOp <= AluOp_Mfhi;
Funct_Mflo : ALUOp <= AluOp_Mflo;
Funct_Movn : ALUOp <= AluOp_Addu;
Funct_Movz : ALUOp <= AluOp_Addu;
Funct_Mthi : ALUOp <= AluOp_Mthi;
Funct_Mtlo : ALUOp <= AluOp_Mtlo;
Funct_Mult : ALUOp <= AluOp_Mult;
Funct_Multu : ALUOp <= AluOp_Multu;
Funct_Nor : ALUOp <= AluOp_Nor;
Funct_Or : ALUOp <= AluOp_Or;
Funct_Sll : ALUOp <= AluOp_Sll;
Funct_Sllv : ALUOp <= AluOp_Sllv;
Funct_Slt : ALUOp <= AluOp_Slt;
Funct_Sltu : ALUOp <= AluOp_Sltu;
Funct_Sra : ALUOp <= AluOp_Sra;
Funct_Srav : ALUOp <= AluOp_Srav;
Funct_Srl : ALUOp <= AluOp_Srl;
Funct_Srlv : ALUOp <= AluOp_Srlv;
Funct_Sub : ALUOp <= AluOp_Sub;
Funct_Subu : ALUOp <= AluOp_Subu;
// ALU Assignment
always @(*) begin
if (ID_Stall)
ALUOp <= AluOp_Addu; // Any Op that doesn't write HILO or cause exceptions
else begin
case (OpCode)
Op_Type_R :
begin
case (Funct)
Funct_Add : ALUOp <= AluOp_Add;
Funct_Addu : ALUOp <= AluOp_Addu;
Funct_And : ALUOp <= AluOp_And;
Funct_Div : ALUOp <= AluOp_Div;
Funct_Divu : ALUOp <= AluOp_Divu;
Funct_Jalr : ALUOp <= AluOp_Addu;
Funct_Mfhi : ALUOp <= AluOp_Mfhi;
Funct_Mflo : ALUOp <= AluOp_Mflo;
Funct_Movn : ALUOp <= AluOp_Addu;
Funct_Movz : ALUOp <= AluOp_Addu;
Funct_Mthi : ALUOp <= AluOp_Mthi;
Funct_Mtlo : ALUOp <= AluOp_Mtlo;
Funct_Mult : ALUOp <= AluOp_Mult;
Funct_Multu : ALUOp <= AluOp_Multu;
Funct_Nor : ALUOp <= AluOp_Nor;
Funct_Or : ALUOp <= AluOp_Or;
Funct_Sll : ALUOp <= AluOp_Sll;
Funct_Sllv : ALUOp <= AluOp_Sllv;
Funct_Slt : ALUOp <= AluOp_Slt;
Funct_Sltu : ALUOp <= AluOp_Sltu;
Funct_Sra : ALUOp <= AluOp_Sra;
Funct_Srav : ALUOp <= AluOp_Srav;
Funct_Srl : ALUOp <= AluOp_Srl;
Funct_Srlv : ALUOp <= AluOp_Srlv;
Funct_Sub : ALUOp <= AluOp_Sub;
Funct_Subu : ALUOp <= AluOp_Subu;
Funct_Syscall : ALUOp <= AluOp_Addu;
Funct_Teq : ALUOp <= AluOp_Subu;
Funct_Tge : ALUOp <= AluOp_Slt;
Funct_Tgeu : ALUOp <= AluOp_Sltu;
Funct_Tlt : ALUOp <= AluOp_Slt;
Funct_Tltu : ALUOp <= AluOp_Sltu;
Funct_Tne : ALUOp <= AluOp_Subu;
Funct_Xor : ALUOp <= AluOp_Xor;
default : ALUOp <= AluOp_Addu;
endcase
end
Op_Type_R2 :
begin
case (Funct)
Funct_Clo : ALUOp <= AluOp_Clo;
Funct_Clz : ALUOp <= AluOp_Clz;
Funct_Madd : ALUOp <= AluOp_Madd;
Funct_Maddu : ALUOp <= AluOp_Maddu;
Funct_Msub : ALUOp <= AluOp_Msub;
Funct_Msubu : ALUOp <= AluOp_Msubu;
Funct_Mul : ALUOp <= AluOp_Mul;
default : ALUOp <= AluOp_Addu;
endcase
end
Funct_Tge : ALUOp <= AluOp_Slt;
Funct_Tgeu : ALUOp <= AluOp_Sltu;
Funct_Tlt : ALUOp <= AluOp_Slt;
Funct_Tltu : ALUOp <= AluOp_Sltu;
Funct_Tne : ALUOp <= AluOp_Subu;
Funct_Xor : ALUOp <= AluOp_Xor;
default : ALUOp <= AluOp_Addu;
endcase
end
Op_Type_R2 :
begin
case (Funct)
Funct_Clo : ALUOp <= AluOp_Clo;
Funct_Clz : ALUOp <= AluOp_Clz;
Funct_Madd : ALUOp <= AluOp_Madd;
Funct_Maddu : ALUOp <= AluOp_Maddu;
Funct_Msub : ALUOp <= AluOp_Msub;
Funct_Msubu : ALUOp <= AluOp_Msubu;
Funct_Mul : ALUOp <= AluOp_Mul;
default : ALUOp <= AluOp_Addu;
endcase
end
Op_Type_BI :
begin
case (Rt)
OpRt_Teqi : ALUOp <= AluOp_Subu;
OpRt_Tgei : ALUOp <= AluOp_Slt;
OpRt_Tgeiu : ALUOp <= AluOp_Sltu;
OpRt_Tlti : ALUOp <= AluOp_Slt;
OpRt_Tltiu : ALUOp <= AluOp_Sltu;
OpRt_Tnei : ALUOp <= AluOp_Subu;
default : ALUOp <= AluOp_Addu; // Branches don't matter.
endcase
OpRt_Teqi : ALUOp <= AluOp_Subu;
OpRt_Tgei : ALUOp <= AluOp_Slt;
OpRt_Tgeiu : ALUOp <= AluOp_Sltu;
OpRt_Tlti : ALUOp <= AluOp_Slt;
OpRt_Tltiu : ALUOp <= AluOp_Sltu;
OpRt_Tnei : ALUOp <= AluOp_Subu;
default : ALUOp <= AluOp_Addu; // Branches don't matter.
endcase
end
Op_Type_CP0 : ALUOp <= AluOp_Addu;
Op_Addi : ALUOp <= AluOp_Add;
Op_Addiu : ALUOp <= AluOp_Addu;
Op_Andi : ALUOp <= AluOp_And;
Op_Jal : ALUOp <= AluOp_Addu;
Op_Lb : ALUOp <= AluOp_Addu;
Op_Lbu : ALUOp <= AluOp_Addu;
Op_Lh : ALUOp <= AluOp_Addu;
Op_Lhu : ALUOp <= AluOp_Addu;
Op_Ll : ALUOp <= AluOp_Addu;
Op_Lui : ALUOp <= AluOp_Sllc;
Op_Lw : ALUOp <= AluOp_Addu;
Op_Lwl : ALUOp <= AluOp_Addu;
Op_Lwr : ALUOp <= AluOp_Addu;
Op_Ori : ALUOp <= AluOp_Or;
Op_Sb : ALUOp <= AluOp_Addu;
Op_Sc : ALUOp <= AluOp_Addu; // XXX Needs HW implement
Op_Sh : ALUOp <= AluOp_Addu;
Op_Slti : ALUOp <= AluOp_Slt;
Op_Sltiu : ALUOp <= AluOp_Sltu;
Op_Sw : ALUOp <= AluOp_Addu;
Op_Swl : ALUOp <= AluOp_Addu;
Op_Swr : ALUOp <= AluOp_Addu;
Op_Xori : ALUOp <= AluOp_Xor;
default : ALUOp <= AluOp_Addu;
endcase
end
end
Op_Addi : ALUOp <= AluOp_Add;
Op_Addiu : ALUOp <= AluOp_Addu;
Op_Andi : ALUOp <= AluOp_And;
Op_Jal : ALUOp <= AluOp_Addu;
Op_Lb : ALUOp <= AluOp_Addu;
Op_Lbu : ALUOp <= AluOp_Addu;
Op_Lh : ALUOp <= AluOp_Addu;
Op_Lhu : ALUOp <= AluOp_Addu;
Op_Ll : ALUOp <= AluOp_Addu;
Op_Lui : ALUOp <= AluOp_Sllc;
Op_Lw : ALUOp <= AluOp_Addu;
Op_Lwl : ALUOp <= AluOp_Addu;
Op_Lwr : ALUOp <= AluOp_Addu;
Op_Ori : ALUOp <= AluOp_Or;
Op_Sb : ALUOp <= AluOp_Addu;
Op_Sc : ALUOp <= AluOp_Addu; // XXX Needs HW implement
Op_Sh : ALUOp <= AluOp_Addu;
Op_Slti : ALUOp <= AluOp_Slt;
Op_Sltiu : ALUOp <= AluOp_Sltu;
Op_Sw : ALUOp <= AluOp_Addu;
Op_Swl : ALUOp <= AluOp_Addu;
Op_Swr : ALUOp <= AluOp_Addu;
Op_Xori : ALUOp <= AluOp_Xor;
default : ALUOp <= AluOp_Addu;
endcase
end
end
 
/***
These remaining options cover portions of the datapath that are not
465,15 → 465,15
assign PCSrc[1] = (Datapath[15] & ~Datapath[14]) ? Branch : Datapath[15];
/* In MIPS32, all Branch and Jump operations execute the Branch Delay Slot,
* or next instruction, regardless if the branch is taken or not. The exception
* is the "Branch Likely" instruction group. These are deprecated, however, and not
* implemented here. "IF_Flush" is defined to allow for the cancelation of a
* Branch Delay Slot should these be implemented later.
*/
assign IF_Flush = 0;
* or next instruction, regardless if the branch is taken or not. The exception
* is the "Branch Likely" instruction group. These are deprecated, however, and not
* implemented here. "IF_Flush" is defined to allow for the cancelation of a
* Branch Delay Slot should these be implemented later.
*/
assign IF_Flush = 0;
 
// Indicator that next instruction is a Branch Delay Slot.
assign NextIsDelay = Datapath[15] | Datapath[14];
// Indicator that next instruction is a Branch Delay Slot.
assign NextIsDelay = Datapath[15] | Datapath[14];
// Sign- or Zero-Extension Control. The only ops that require zero-extension are
// Andi, Ori, and Xori. The following also zero-extends 'lui', however it does not alter the effect of lui.
482,10 → 482,10
// Move Conditional
assign Movn = Movc & Funct[0];
assign Movz = Movc & ~Funct[0];
// Coprocessor 0 (Mfc0, Mtc0) control signals.
// Coprocessor 0 (Mfc0, Mtc0) control signals.
assign Mfc0 = ((OpCode == Op_Type_CP0) && (Rs == OpRs_MF));
assign Mtc0 = ((OpCode == Op_Type_CP0) && (Rs == OpRs_MT));
assign Mtc0 = ((OpCode == Op_Type_CP0) && (Rs == OpRs_MT));
assign Eret = ((OpCode == Op_Type_CP0) && (Rs == OpRs_ERET) && (Funct == Funct_ERET));
// Coprocessor 1,2,3 accesses (not implemented)
506,3 → 506,4
assign EXC_RI = 0;
endmodule
 
/MIPS32_Standalone/ALU.v
1,207 → 1,208
`timescale 1ns / 1ps
/*
* File : ALU.v
* Project : University of Utah, XUM Project MIPS32 core
* Creator(s) : Grant Ayers (ayers@cs.utah.edu)
*
* Modification History:
* Rev Date Initials Description of Change
* 1.0 7-Jun-2011 GEA Initial design.
* 2.0 26-Jul-2012 GEA Many changes have been made.
*
* Standards/Formatting:
* Verilog 2001, 4 soft tab, wide column.
*
* Description:
* An Arithmetic Logic Unit for a MIPS32 processor. This module computes all
* arithmetic operations, including the following:
*
* Add, Subtract, Multiply, And, Or, Nor, Xor, Shift, Count leading 1s/0s.
*/
module ALU(
input clock,
input reset,
input EX_Stall,
input EX_Flush,
input [31:0] A, B,
input [4:0] Operation,
input signed [4:0] Shamt,
output reg signed [31:0] Result,
output BZero, // Used for Movc
output reg EXC_Ov
);
 
`include "MIPS_Parameters.v"
/***
Performance Notes:
The ALU is the longest delay path in the Execute stage, and one of the longest
in the entire processor. This path varies based on the logic blocks that are
chosen to implement various functions, but there is certainly room to improve
the speed of arithmetic operations. The ALU could also be placed in a separate
pipeline stage after the Execute forwarding has completed.
***/
wire signed [31:0] As = A;
wire signed [31:0] Bs = B;
reg [63:0] HILO;
wire [31:0] HI = HILO[63:32];
wire [31:0] LO = HILO[31:0];
wire HILO_Commit = ~(EX_Stall | EX_Flush);
wire AddSub_Add = ((Operation == AluOp_Add) | (Operation == AluOp_Addu));
wire signed [31:0] AddSub_Result = (AddSub_Add) ? (A + B) : (A - B);
wire signed [63:0] Mult_Result = As * Bs;
wire [63:0] Multu_Result = A * B;
reg [5:0] CLO_Result, CLZ_Result;
assign BZero = (B == 32'h00000000);
always @(*) begin
case (Operation)
AluOp_Add : Result <= AddSub_Result;
AluOp_Addu : Result <= AddSub_Result;
AluOp_And : Result <= A & B;
AluOp_Clo : Result <= {26'b0, CLO_Result};
AluOp_Clz : Result <= {26'b0, CLZ_Result};
AluOp_Div : Result <= 32'hdeafbeef; // XXX implement division
AluOp_Divu : Result <= 32'hdeadbeef; // XXX implement division
AluOp_Mfhi : Result <= HI;
AluOp_Mflo : Result <= LO;
AluOp_Mul : Result <= Mult_Result[31:0];
AluOp_Nor : Result <= ~(A | B);
AluOp_Or : Result <= A | B;
AluOp_Sll : Result <= B << Shamt;
AluOp_Sllc : Result <= {B[15:0], 16'b0};
AluOp_Sllv : Result <= B << A[4:0];
AluOp_Slt : Result <= (As < Bs) ? 32'h00000001 : 32'h00000000;
AluOp_Sltu : Result <= (A < B) ? 32'h00000001 : 32'h00000000;
AluOp_Sra : Result <= Bs >>> Shamt;
AluOp_Srav : Result <= Bs >>> As[4:0];
AluOp_Srl : Result <= B >> Shamt;
AluOp_Srlv : Result <= B >> A[4:0];
AluOp_Sub : Result <= AddSub_Result;
AluOp_Subu : Result <= AddSub_Result;
AluOp_Xor : Result <= A ^ B;
default : Result <= 32'bx;
endcase
end
always @(posedge clock) begin
if (reset) begin
HILO <= 64'h00000000_00000000;
end
else if (HILO_Commit) begin
case (Operation)
AluOp_Mult : HILO <= Mult_Result;
AluOp_Multu : HILO <= Multu_Result;
AluOp_Madd : HILO <= HILO + Mult_Result;
AluOp_Maddu : HILO <= HILO + Multu_Result;
AluOp_Msub : HILO <= HILO - Mult_Result;
AluOp_Msubu : HILO <= HILO - Multu_Result;
AluOp_Mthi : HILO <= {A, LO};
AluOp_Mtlo : HILO <= {HI, B};
default : HILO <= HILO;
endcase
end
else begin
HILO <= HILO;
end
end
// Detect overflow for signed operations. Note that MIPS32 has no overflow
// detection for multiplication/division operations.
always @(*) begin
case (Operation)
`timescale 1ns / 1ps
/*
* File : ALU.v
* Project : University of Utah, XUM Project MIPS32 core
* Creator(s) : Grant Ayers (ayers@cs.utah.edu)
*
* Modification History:
* Rev Date Initials Description of Change
* 1.0 7-Jun-2011 GEA Initial design.
* 2.0 26-Jul-2012 GEA Many changes have been made.
*
* Standards/Formatting:
* Verilog 2001, 4 soft tab, wide column.
*
* Description:
* An Arithmetic Logic Unit for a MIPS32 processor. This module computes all
* arithmetic operations, including the following:
*
* Add, Subtract, Multiply, And, Or, Nor, Xor, Shift, Count leading 1s/0s.
*/
module ALU(
input clock,
input reset,
input EX_Stall,
input EX_Flush,
input [31:0] A, B,
input [4:0] Operation,
input signed [4:0] Shamt,
output reg signed [31:0] Result,
output BZero, // Used for Movc
output reg EXC_Ov
);
 
`include "MIPS_Parameters.v"
/***
Performance Notes:
The ALU is the longest delay path in the Execute stage, and one of the longest
in the entire processor. This path varies based on the logic blocks that are
chosen to implement various functions, but there is certainly room to improve
the speed of arithmetic operations. The ALU could also be placed in a separate
pipeline stage after the Execute forwarding has completed.
***/
wire signed [31:0] As = A;
wire signed [31:0] Bs = B;
reg [63:0] HILO;
wire [31:0] HI = HILO[63:32];
wire [31:0] LO = HILO[31:0];
wire HILO_Commit = ~(EX_Stall | EX_Flush);
wire AddSub_Add = ((Operation == AluOp_Add) | (Operation == AluOp_Addu));
wire signed [31:0] AddSub_Result = (AddSub_Add) ? (A + B) : (A - B);
wire signed [63:0] Mult_Result = As * Bs;
wire [63:0] Multu_Result = A * B;
reg [5:0] CLO_Result, CLZ_Result;
assign BZero = (B == 32'h00000000);
always @(*) begin
case (Operation)
AluOp_Add : Result <= AddSub_Result;
AluOp_Addu : Result <= AddSub_Result;
AluOp_And : Result <= A & B;
AluOp_Clo : Result <= {26'b0, CLO_Result};
AluOp_Clz : Result <= {26'b0, CLZ_Result};
AluOp_Div : Result <= 32'hdeafbeef; // XXX implement division
AluOp_Divu : Result <= 32'hdeadbeef; // XXX implement division
AluOp_Mfhi : Result <= HI;
AluOp_Mflo : Result <= LO;
AluOp_Mul : Result <= Mult_Result[31:0];
AluOp_Nor : Result <= ~(A | B);
AluOp_Or : Result <= A | B;
AluOp_Sll : Result <= B << Shamt;
AluOp_Sllc : Result <= {B[15:0], 16'b0};
AluOp_Sllv : Result <= B << A[4:0];
AluOp_Slt : Result <= (As < Bs) ? 32'h00000001 : 32'h00000000;
AluOp_Sltu : Result <= (A < B) ? 32'h00000001 : 32'h00000000;
AluOp_Sra : Result <= Bs >>> Shamt;
AluOp_Srav : Result <= Bs >>> As[4:0];
AluOp_Srl : Result <= B >> Shamt;
AluOp_Srlv : Result <= B >> A[4:0];
AluOp_Sub : Result <= AddSub_Result;
AluOp_Subu : Result <= AddSub_Result;
AluOp_Xor : Result <= A ^ B;
default : Result <= 32'bx;
endcase
end
always @(posedge clock) begin
if (reset) begin
HILO <= 64'h00000000_00000000;
end
else if (HILO_Commit) begin
case (Operation)
AluOp_Mult : HILO <= Mult_Result;
AluOp_Multu : HILO <= Multu_Result;
AluOp_Madd : HILO <= HILO + Mult_Result;
AluOp_Maddu : HILO <= HILO + Multu_Result;
AluOp_Msub : HILO <= HILO - Mult_Result;
AluOp_Msubu : HILO <= HILO - Multu_Result;
AluOp_Mthi : HILO <= {A, LO};
AluOp_Mtlo : HILO <= {HI, B};
default : HILO <= HILO;
endcase
end
else begin
HILO <= HILO;
end
end
// Detect overflow for signed operations. Note that MIPS32 has no overflow
// detection for multiplication/division operations.
always @(*) begin
case (Operation)
AluOp_Add : EXC_Ov <= ((A[31] ~^ B[31]) & (A[31] ^ AddSub_Result[31]));
AluOp_Sub : EXC_Ov <= ((A[31] ^ B[31]) & (A[31] ^ AddSub_Result[31]));
default : EXC_Ov <= 0;
endcase
end
// Count Leading Ones
always @(A) begin
casex (A)
32'b0xxx_xxxx_xxxx_xxxx_xxxx_xxxx_xxxx_xxxx : CLO_Result <= 6'd0;
32'b10xx_xxxx_xxxx_xxxx_xxxx_xxxx_xxxx_xxxx : CLO_Result <= 6'd1;
32'b110x_xxxx_xxxx_xxxx_xxxx_xxxx_xxxx_xxxx : CLO_Result <= 6'd2;
32'b1110_xxxx_xxxx_xxxx_xxxx_xxxx_xxxx_xxxx : CLO_Result <= 6'd3;
32'b1111_0xxx_xxxx_xxxx_xxxx_xxxx_xxxx_xxxx : CLO_Result <= 6'd4;
32'b1111_10xx_xxxx_xxxx_xxxx_xxxx_xxxx_xxxx : CLO_Result <= 6'd5;
32'b1111_110x_xxxx_xxxx_xxxx_xxxx_xxxx_xxxx : CLO_Result <= 6'd6;
32'b1111_1110_xxxx_xxxx_xxxx_xxxx_xxxx_xxxx : CLO_Result <= 6'd7;
32'b1111_1111_0xxx_xxxx_xxxx_xxxx_xxxx_xxxx : CLO_Result <= 6'd8;
32'b1111_1111_10xx_xxxx_xxxx_xxxx_xxxx_xxxx : CLO_Result <= 6'd9;
32'b1111_1111_110x_xxxx_xxxx_xxxx_xxxx_xxxx : CLO_Result <= 6'd10;
32'b1111_1111_1110_xxxx_xxxx_xxxx_xxxx_xxxx : CLO_Result <= 6'd11;
32'b1111_1111_1111_0xxx_xxxx_xxxx_xxxx_xxxx : CLO_Result <= 6'd12;
32'b1111_1111_1111_10xx_xxxx_xxxx_xxxx_xxxx : CLO_Result <= 6'd13;
32'b1111_1111_1111_110x_xxxx_xxxx_xxxx_xxxx : CLO_Result <= 6'd14;
32'b1111_1111_1111_1110_xxxx_xxxx_xxxx_xxxx : CLO_Result <= 6'd15;
32'b1111_1111_1111_1111_0xxx_xxxx_xxxx_xxxx : CLO_Result <= 6'd16;
32'b1111_1111_1111_1111_10xx_xxxx_xxxx_xxxx : CLO_Result <= 6'd17;
32'b1111_1111_1111_1111_110x_xxxx_xxxx_xxxx : CLO_Result <= 6'd18;
32'b1111_1111_1111_1111_1110_xxxx_xxxx_xxxx : CLO_Result <= 6'd19;
32'b1111_1111_1111_1111_1111_0xxx_xxxx_xxxx : CLO_Result <= 6'd20;
32'b1111_1111_1111_1111_1111_10xx_xxxx_xxxx : CLO_Result <= 6'd21;
32'b1111_1111_1111_1111_1111_110x_xxxx_xxxx : CLO_Result <= 6'd22;
32'b1111_1111_1111_1111_1111_1110_xxxx_xxxx : CLO_Result <= 6'd23;
32'b1111_1111_1111_1111_1111_1111_0xxx_xxxx : CLO_Result <= 6'd24;
32'b1111_1111_1111_1111_1111_1111_10xx_xxxx : CLO_Result <= 6'd25;
32'b1111_1111_1111_1111_1111_1111_110x_xxxx : CLO_Result <= 6'd26;
32'b1111_1111_1111_1111_1111_1111_1110_xxxx : CLO_Result <= 6'd27;
32'b1111_1111_1111_1111_1111_1111_1111_0xxx : CLO_Result <= 6'd28;
32'b1111_1111_1111_1111_1111_1111_1111_10xx : CLO_Result <= 6'd29;
32'b1111_1111_1111_1111_1111_1111_1111_110x : CLO_Result <= 6'd30;
32'b1111_1111_1111_1111_1111_1111_1111_1110 : CLO_Result <= 6'd31;
32'b1111_1111_1111_1111_1111_1111_1111_1111 : CLO_Result <= 6'd32;
default : CLO_Result <= 6'd0;
endcase
end
 
// Count Leading Zeros
always @(A) begin
casex (A)
32'b1xxx_xxxx_xxxx_xxxx_xxxx_xxxx_xxxx_xxxx : CLZ_Result <= 6'd0;
32'b01xx_xxxx_xxxx_xxxx_xxxx_xxxx_xxxx_xxxx : CLZ_Result <= 6'd1;
32'b001x_xxxx_xxxx_xxxx_xxxx_xxxx_xxxx_xxxx : CLZ_Result <= 6'd2;
32'b0001_xxxx_xxxx_xxxx_xxxx_xxxx_xxxx_xxxx : CLZ_Result <= 6'd3;
32'b0000_1xxx_xxxx_xxxx_xxxx_xxxx_xxxx_xxxx : CLZ_Result <= 6'd4;
32'b0000_01xx_xxxx_xxxx_xxxx_xxxx_xxxx_xxxx : CLZ_Result <= 6'd5;
32'b0000_001x_xxxx_xxxx_xxxx_xxxx_xxxx_xxxx : CLZ_Result <= 6'd6;
32'b0000_0001_xxxx_xxxx_xxxx_xxxx_xxxx_xxxx : CLZ_Result <= 6'd7;
32'b0000_0000_1xxx_xxxx_xxxx_xxxx_xxxx_xxxx : CLZ_Result <= 6'd8;
32'b0000_0000_01xx_xxxx_xxxx_xxxx_xxxx_xxxx : CLZ_Result <= 6'd9;
32'b0000_0000_001x_xxxx_xxxx_xxxx_xxxx_xxxx : CLZ_Result <= 6'd10;
32'b0000_0000_0001_xxxx_xxxx_xxxx_xxxx_xxxx : CLZ_Result <= 6'd11;
32'b0000_0000_0000_1xxx_xxxx_xxxx_xxxx_xxxx : CLZ_Result <= 6'd12;
32'b0000_0000_0000_01xx_xxxx_xxxx_xxxx_xxxx : CLZ_Result <= 6'd13;
32'b0000_0000_0000_001x_xxxx_xxxx_xxxx_xxxx : CLZ_Result <= 6'd14;
32'b0000_0000_0000_0001_xxxx_xxxx_xxxx_xxxx : CLZ_Result <= 6'd15;
32'b0000_0000_0000_0000_1xxx_xxxx_xxxx_xxxx : CLZ_Result <= 6'd16;
32'b0000_0000_0000_0000_01xx_xxxx_xxxx_xxxx : CLZ_Result <= 6'd17;
32'b0000_0000_0000_0000_001x_xxxx_xxxx_xxxx : CLZ_Result <= 6'd18;
32'b0000_0000_0000_0000_0001_xxxx_xxxx_xxxx : CLZ_Result <= 6'd19;
32'b0000_0000_0000_0000_0000_1xxx_xxxx_xxxx : CLZ_Result <= 6'd20;
32'b0000_0000_0000_0000_0000_01xx_xxxx_xxxx : CLZ_Result <= 6'd21;
32'b0000_0000_0000_0000_0000_001x_xxxx_xxxx : CLZ_Result <= 6'd22;
32'b0000_0000_0000_0000_0000_0001_xxxx_xxxx : CLZ_Result <= 6'd23;
32'b0000_0000_0000_0000_0000_0000_1xxx_xxxx : CLZ_Result <= 6'd24;
32'b0000_0000_0000_0000_0000_0000_01xx_xxxx : CLZ_Result <= 6'd25;
32'b0000_0000_0000_0000_0000_0000_001x_xxxx : CLZ_Result <= 6'd26;
32'b0000_0000_0000_0000_0000_0000_0001_xxxx : CLZ_Result <= 6'd27;
32'b0000_0000_0000_0000_0000_0000_0000_1xxx : CLZ_Result <= 6'd28;
32'b0000_0000_0000_0000_0000_0000_0000_01xx : CLZ_Result <= 6'd29;
32'b0000_0000_0000_0000_0000_0000_0000_001x : CLZ_Result <= 6'd30;
32'b0000_0000_0000_0000_0000_0000_0000_0001 : CLZ_Result <= 6'd31;
32'b0000_0000_0000_0000_0000_0000_0000_0000 : CLZ_Result <= 6'd32;
default : CLZ_Result <= 6'd0;
endcase
end
endmodule
AluOp_Sub : EXC_Ov <= ((A[31] ^ B[31]) & (A[31] ^ AddSub_Result[31]));
default : EXC_Ov <= 0;
endcase
end
// Count Leading Ones
always @(A) begin
casex (A)
32'b0xxx_xxxx_xxxx_xxxx_xxxx_xxxx_xxxx_xxxx : CLO_Result <= 6'd0;
32'b10xx_xxxx_xxxx_xxxx_xxxx_xxxx_xxxx_xxxx : CLO_Result <= 6'd1;
32'b110x_xxxx_xxxx_xxxx_xxxx_xxxx_xxxx_xxxx : CLO_Result <= 6'd2;
32'b1110_xxxx_xxxx_xxxx_xxxx_xxxx_xxxx_xxxx : CLO_Result <= 6'd3;
32'b1111_0xxx_xxxx_xxxx_xxxx_xxxx_xxxx_xxxx : CLO_Result <= 6'd4;
32'b1111_10xx_xxxx_xxxx_xxxx_xxxx_xxxx_xxxx : CLO_Result <= 6'd5;
32'b1111_110x_xxxx_xxxx_xxxx_xxxx_xxxx_xxxx : CLO_Result <= 6'd6;
32'b1111_1110_xxxx_xxxx_xxxx_xxxx_xxxx_xxxx : CLO_Result <= 6'd7;
32'b1111_1111_0xxx_xxxx_xxxx_xxxx_xxxx_xxxx : CLO_Result <= 6'd8;
32'b1111_1111_10xx_xxxx_xxxx_xxxx_xxxx_xxxx : CLO_Result <= 6'd9;
32'b1111_1111_110x_xxxx_xxxx_xxxx_xxxx_xxxx : CLO_Result <= 6'd10;
32'b1111_1111_1110_xxxx_xxxx_xxxx_xxxx_xxxx : CLO_Result <= 6'd11;
32'b1111_1111_1111_0xxx_xxxx_xxxx_xxxx_xxxx : CLO_Result <= 6'd12;
32'b1111_1111_1111_10xx_xxxx_xxxx_xxxx_xxxx : CLO_Result <= 6'd13;
32'b1111_1111_1111_110x_xxxx_xxxx_xxxx_xxxx : CLO_Result <= 6'd14;
32'b1111_1111_1111_1110_xxxx_xxxx_xxxx_xxxx : CLO_Result <= 6'd15;
32'b1111_1111_1111_1111_0xxx_xxxx_xxxx_xxxx : CLO_Result <= 6'd16;
32'b1111_1111_1111_1111_10xx_xxxx_xxxx_xxxx : CLO_Result <= 6'd17;
32'b1111_1111_1111_1111_110x_xxxx_xxxx_xxxx : CLO_Result <= 6'd18;
32'b1111_1111_1111_1111_1110_xxxx_xxxx_xxxx : CLO_Result <= 6'd19;
32'b1111_1111_1111_1111_1111_0xxx_xxxx_xxxx : CLO_Result <= 6'd20;
32'b1111_1111_1111_1111_1111_10xx_xxxx_xxxx : CLO_Result <= 6'd21;
32'b1111_1111_1111_1111_1111_110x_xxxx_xxxx : CLO_Result <= 6'd22;
32'b1111_1111_1111_1111_1111_1110_xxxx_xxxx : CLO_Result <= 6'd23;
32'b1111_1111_1111_1111_1111_1111_0xxx_xxxx : CLO_Result <= 6'd24;
32'b1111_1111_1111_1111_1111_1111_10xx_xxxx : CLO_Result <= 6'd25;
32'b1111_1111_1111_1111_1111_1111_110x_xxxx : CLO_Result <= 6'd26;
32'b1111_1111_1111_1111_1111_1111_1110_xxxx : CLO_Result <= 6'd27;
32'b1111_1111_1111_1111_1111_1111_1111_0xxx : CLO_Result <= 6'd28;
32'b1111_1111_1111_1111_1111_1111_1111_10xx : CLO_Result <= 6'd29;
32'b1111_1111_1111_1111_1111_1111_1111_110x : CLO_Result <= 6'd30;
32'b1111_1111_1111_1111_1111_1111_1111_1110 : CLO_Result <= 6'd31;
32'b1111_1111_1111_1111_1111_1111_1111_1111 : CLO_Result <= 6'd32;
default : CLO_Result <= 6'd0;
endcase
end
 
// Count Leading Zeros
always @(A) begin
casex (A)
32'b1xxx_xxxx_xxxx_xxxx_xxxx_xxxx_xxxx_xxxx : CLZ_Result <= 6'd0;
32'b01xx_xxxx_xxxx_xxxx_xxxx_xxxx_xxxx_xxxx : CLZ_Result <= 6'd1;
32'b001x_xxxx_xxxx_xxxx_xxxx_xxxx_xxxx_xxxx : CLZ_Result <= 6'd2;
32'b0001_xxxx_xxxx_xxxx_xxxx_xxxx_xxxx_xxxx : CLZ_Result <= 6'd3;
32'b0000_1xxx_xxxx_xxxx_xxxx_xxxx_xxxx_xxxx : CLZ_Result <= 6'd4;
32'b0000_01xx_xxxx_xxxx_xxxx_xxxx_xxxx_xxxx : CLZ_Result <= 6'd5;
32'b0000_001x_xxxx_xxxx_xxxx_xxxx_xxxx_xxxx : CLZ_Result <= 6'd6;
32'b0000_0001_xxxx_xxxx_xxxx_xxxx_xxxx_xxxx : CLZ_Result <= 6'd7;
32'b0000_0000_1xxx_xxxx_xxxx_xxxx_xxxx_xxxx : CLZ_Result <= 6'd8;
32'b0000_0000_01xx_xxxx_xxxx_xxxx_xxxx_xxxx : CLZ_Result <= 6'd9;
32'b0000_0000_001x_xxxx_xxxx_xxxx_xxxx_xxxx : CLZ_Result <= 6'd10;
32'b0000_0000_0001_xxxx_xxxx_xxxx_xxxx_xxxx : CLZ_Result <= 6'd11;
32'b0000_0000_0000_1xxx_xxxx_xxxx_xxxx_xxxx : CLZ_Result <= 6'd12;
32'b0000_0000_0000_01xx_xxxx_xxxx_xxxx_xxxx : CLZ_Result <= 6'd13;
32'b0000_0000_0000_001x_xxxx_xxxx_xxxx_xxxx : CLZ_Result <= 6'd14;
32'b0000_0000_0000_0001_xxxx_xxxx_xxxx_xxxx : CLZ_Result <= 6'd15;
32'b0000_0000_0000_0000_1xxx_xxxx_xxxx_xxxx : CLZ_Result <= 6'd16;
32'b0000_0000_0000_0000_01xx_xxxx_xxxx_xxxx : CLZ_Result <= 6'd17;
32'b0000_0000_0000_0000_001x_xxxx_xxxx_xxxx : CLZ_Result <= 6'd18;
32'b0000_0000_0000_0000_0001_xxxx_xxxx_xxxx : CLZ_Result <= 6'd19;
32'b0000_0000_0000_0000_0000_1xxx_xxxx_xxxx : CLZ_Result <= 6'd20;
32'b0000_0000_0000_0000_0000_01xx_xxxx_xxxx : CLZ_Result <= 6'd21;
32'b0000_0000_0000_0000_0000_001x_xxxx_xxxx : CLZ_Result <= 6'd22;
32'b0000_0000_0000_0000_0000_0001_xxxx_xxxx : CLZ_Result <= 6'd23;
32'b0000_0000_0000_0000_0000_0000_1xxx_xxxx : CLZ_Result <= 6'd24;
32'b0000_0000_0000_0000_0000_0000_01xx_xxxx : CLZ_Result <= 6'd25;
32'b0000_0000_0000_0000_0000_0000_001x_xxxx : CLZ_Result <= 6'd26;
32'b0000_0000_0000_0000_0000_0000_0001_xxxx : CLZ_Result <= 6'd27;
32'b0000_0000_0000_0000_0000_0000_0000_1xxx : CLZ_Result <= 6'd28;
32'b0000_0000_0000_0000_0000_0000_0000_01xx : CLZ_Result <= 6'd29;
32'b0000_0000_0000_0000_0000_0000_0000_001x : CLZ_Result <= 6'd30;
32'b0000_0000_0000_0000_0000_0000_0000_0001 : CLZ_Result <= 6'd31;
32'b0000_0000_0000_0000_0000_0000_0000_0000 : CLZ_Result <= 6'd32;
default : CLZ_Result <= 6'd0;
endcase
end
endmodule
 
/MIPS32_Standalone/RegisterFile.v
54,5 → 54,5
assign ReadData1 = (ReadReg1 == 0) ? 32'h00000000 : registers[ReadReg1];
assign ReadData2 = (ReadReg2 == 0) ? 32'h00000000 : registers[ReadReg2];
 
endmodule
 
endmodule
/MIPS32_Standalone/Register.v
16,18 → 16,19
* value. Default is 32-bit width and 0s for initial value.
*/
module Register #(parameter WIDTH = 32, INIT = 0)(
input clock,
input reset,
input enable,
input [(WIDTH-1):0] D,
output reg [(WIDTH-1):0] Q
);
initial
Q = INIT;
input clock,
input reset,
input enable,
input [(WIDTH-1):0] D,
output reg [(WIDTH-1):0] Q
);
initial
Q = INIT;
 
always @(posedge clock) begin
Q <= (reset) ? INIT : ((enable) ? D : Q);
end
always @(posedge clock) begin
Q <= (reset) ? INIT : ((enable) ? D : Q);
end
 
endmodule
 
/MIPS32_Standalone/Compare.v
20,21 → 20,22
* LEZ : A is less than or equal to zero
*/
module Compare(
input [31:0] A,
input [31:0] B,
output EQ,
output GZ,
output LZ,
output GEZ,
output LEZ
);
input [31:0] A,
input [31:0] B,
output EQ,
output GZ,
output LZ,
output GEZ,
output LEZ
);
 
wire ZeroA = (A == 32'b0);
wire ZeroA = (A == 32'b0);
 
assign EQ = ( A == B);
assign GZ = (~A[31] & ~ZeroA);
assign LZ = A[31];
assign GEZ = ~A[31];
assign LEZ = ( A[31] | ZeroA);
assign EQ = ( A == B);
assign GZ = (~A[31] & ~ZeroA);
assign LZ = A[31];
assign GEZ = ~A[31];
assign LEZ = ( A[31] | ZeroA);
endmodule
 
/MIPS32_Standalone/Add.v
15,11 → 15,12
* A simple 32-bit 2-input adder.
*/
module Add(
input [31:0] A,
input [31:0] B,
output [31:0] C
);
assign C = (A + B);
input [31:0] A,
input [31:0] B,
output [31:0] C
);
assign C = (A + B);
 
endmodule
 
/MIPS32_Standalone/MEMWB_Stage.v
16,27 → 16,27
* The Pipeline Register to bridge the Memory and Writeback stages.
*/
module MEMWB_Stage(
input clock,
input reset,
input clock,
input reset,
input M_Flush,
input M_Stall,
input WB_Stall,
// Control Signals
input M_RegWrite,
input M_MemtoReg,
// Data Signals
input [31:0] M_ReadData,
input [31:0] M_ALU_Result,
input [4:0] M_RtRd,
// ----------------
output reg WB_RegWrite,
output reg WB_MemtoReg,
output reg [31:0] WB_ReadData,
output reg [31:0] WB_ALU_Result,
output reg [4:0] WB_RtRd
);
input WB_Stall,
// Control Signals
input M_RegWrite,
input M_MemtoReg,
// Data Signals
input [31:0] M_ReadData,
input [31:0] M_ALU_Result,
input [4:0] M_RtRd,
// ----------------
output reg WB_RegWrite,
output reg WB_MemtoReg,
output reg [31:0] WB_ReadData,
output reg [31:0] WB_ALU_Result,
output reg [4:0] WB_RtRd
);
/***
The purpose of a pipeline register is to capture data from one pipeline stage
and provide it to the next pipeline stage. This creates at least one clock cycle
71,3 → 71,4
end
 
endmodule
 
/MIPS32_Standalone/MIPS_Parameters.v
1,331 → 1,331
/*
* File : MIPS_Parameters.v
* Project : University of Utah, XUM Project MIPS32 core
* Creator(s) : Grant Ayers (ayers@cs.utah.edu)
*
* Modification History:
* Rev Date Initials Description of Change
* 1.0 26-May-2012 GEA Release version.
*
* Standards/Formatting:
* Verilog 2001, 4 soft tab, wide column.
*
* Description:
* Provides a language abstraction for the MIPS32-specific op-codes and
* the processor-specific datapath, hazard, and exception bits which
* control the processor. These parameter names are used extensively
* throughout the processor HDL modules.
*/
 
 
/*** Exception Vector Locations ***
When the CPU powers up or is reset, it will begin execution at 'EXC_Vector_Base_Reset'.
All other exceptions are the sum of a base address and offset:
- The base address is either a bootstrap or normal value. It is controlled by
the 'BEV' bit in the CP0 'Status' register. Both base addresses can be mapped to
the same location.
- The offset address is either a standard offset (which is always used for
non-interrupt general exceptions in this processor because it lacks TLB Refill
and Cache errors), or a special interrupt-only offset for interrupts, which is
enabled with the 'IV' bit in the CP0 'Cause' register.
Current Setup:
General exceptions go to 0x0. Interrupts go to 0x8. Booting starts at 0x10.
*/
parameter [31:0] EXC_Vector_Base_Reset = 32'h0000_0010; // MIPS Standard is 0xBFC0_0000
parameter [31:0] EXC_Vector_Base_Other_NoBoot = 32'h0000_0000; // MIPS Standard is 0x8000_0000
parameter [31:0] EXC_Vector_Base_Other_Boot = 32'h0000_0000; // MIPS Standard is 0xBFC0_0200
parameter [31:0] EXC_Vector_Offset_General = 32'h0000_0000; // MIPS Standard is 0x0000_0180
parameter [31:0] EXC_Vector_Offset_Special = 32'h0000_0008; // MIPS Standard is 0x0000_0200
 
 
 
/*** Kernel/User Memory Areas ***
 
Kernel memory starts at address 0x0. User memory starts at 'UMem_Lower' and extends to
the end of the address space.
A distinction is made to protect against accesses to kernel memory while the processor
is in user mode. Lacking MMU hardware, these addresses are physical, not virtual.
This simple two-part division of the address space can be extended almost arbitrarily
in the Data Memory Controller. Note that there is currently no user/kernel space check
for the Instruction Memory, because it is assumed that instructions are in the kernel space.
*/
parameter [31:0] UMem_Lower = 32'h08000000;
 
 
 
/*** Processor Endianness ***
 
MIPS32 allows user-mode addresses to be configured as big- or little-endian. For simplicity
reasons, this processor fixes the endianness to little endian. To add support for both
modes, the Data Memory Controller should be updated as well as CP0, which should change
the 'RE' bit in the Status register from a wire to a writable register.
*/
parameter Big_Endian = 0;
 
 
 
/*** Encodings for MIPS32 Release 1 Architecture ***/
 
 
/* Op Code Categories */
parameter [5:0] Op_Type_R = 6'b00_0000; // Standard R-Type instructions
parameter [5:0] Op_Type_R2 = 6'b01_1100; // Extended R-Like instructions
parameter [5:0] Op_Type_BI = 6'b00_0001; // Branch/Trap extended instructions
parameter [5:0] Op_Type_CP0 = 6'b01_0000; // Coprocessor 0 instructions
parameter [5:0] Op_Type_CP1 = 6'b01_0001; // Coprocessor 1 instructions (not implemented)
parameter [5:0] Op_Type_CP2 = 6'b01_0010; // Coprocessor 2 instructions (not implemented)
parameter [5:0] Op_Type_CP3 = 6'b01_0011; // Coprocessor 3 instructions (not implemented)
// --------------------------------------
parameter [5:0] Op_Add = Op_Type_R;
parameter [5:0] Op_Addi = 6'b00_1000;
parameter [5:0] Op_Addiu = 6'b00_1001;
parameter [5:0] Op_Addu = Op_Type_R;
parameter [5:0] Op_And = Op_Type_R;
parameter [5:0] Op_Andi = 6'b00_1100;
parameter [5:0] Op_Beq = 6'b00_0100;
parameter [5:0] Op_Bgez = Op_Type_BI;
parameter [5:0] Op_Bgezal = Op_Type_BI;
parameter [5:0] Op_Bgtz = 6'b00_0111;
parameter [5:0] Op_Blez = 6'b00_0110;
parameter [5:0] Op_Bltz = Op_Type_BI;
parameter [5:0] Op_Bltzal = Op_Type_BI;
parameter [5:0] Op_Bne = 6'b00_0101;
parameter [5:0] Op_Break = Op_Type_R;
parameter [5:0] Op_Clo = Op_Type_R2;
parameter [5:0] Op_Clz = Op_Type_R2;
parameter [5:0] Op_Div = Op_Type_R;
parameter [5:0] Op_Divu = Op_Type_R;
parameter [5:0] Op_Eret = Op_Type_CP0;
parameter [5:0] Op_J = 6'b00_0010;
parameter [5:0] Op_Jal = 6'b00_0011;
parameter [5:0] Op_Jalr = Op_Type_R;
parameter [5:0] Op_Jr = Op_Type_R;
parameter [5:0] Op_Lb = 6'b10_0000;
parameter [5:0] Op_Lbu = 6'b10_0100;
parameter [5:0] Op_Lh = 6'b10_0001;
parameter [5:0] Op_Lhu = 6'b10_0101;
parameter [5:0] Op_Ll = 6'b11_0000;
parameter [5:0] Op_Lui = 6'b00_1111;
parameter [5:0] Op_Lw = 6'b10_0011;
parameter [5:0] Op_Lwl = 6'b10_0010;
parameter [5:0] Op_Lwr = 6'b10_0110;
parameter [5:0] Op_Madd = Op_Type_R2;
parameter [5:0] Op_Maddu = Op_Type_R2;
parameter [5:0] Op_Mfc0 = Op_Type_CP0;
parameter [5:0] Op_Mfhi = Op_Type_R;
parameter [5:0] Op_Mflo = Op_Type_R;
parameter [5:0] Op_Movn = Op_Type_R;
parameter [5:0] Op_Movz = Op_Type_R;
parameter [5:0] Op_Msub = Op_Type_R2;
parameter [5:0] Op_Msubu = Op_Type_R2;
parameter [5:0] Op_Mtc0 = Op_Type_CP0;
parameter [5:0] Op_Mthi = Op_Type_R;
parameter [5:0] Op_Mtlo = Op_Type_R;
parameter [5:0] Op_Mul = Op_Type_R2;
parameter [5:0] Op_Mult = Op_Type_R;
parameter [5:0] Op_Multu = Op_Type_R;
parameter [5:0] Op_Nor = Op_Type_R;
parameter [5:0] Op_Or = Op_Type_R;
parameter [5:0] Op_Ori = 6'b00_1101;
parameter [5:0] Op_Pref = 6'b11_0011; // Prefetch does nothing in this implementation.
parameter [5:0] Op_Sb = 6'b10_1000;
parameter [5:0] Op_Sc = 6'b11_1000;
parameter [5:0] Op_Sh = 6'b10_1001;
parameter [5:0] Op_Sll = Op_Type_R;
parameter [5:0] Op_Sllv = Op_Type_R;
parameter [5:0] Op_Slt = Op_Type_R;
parameter [5:0] Op_Slti = 6'b00_1010;
parameter [5:0] Op_Sltiu = 6'b00_1011;
parameter [5:0] Op_Sltu = Op_Type_R;
parameter [5:0] Op_Sra = Op_Type_R;
parameter [5:0] Op_Srav = Op_Type_R;
parameter [5:0] Op_Srl = Op_Type_R;
parameter [5:0] Op_Srlv = Op_Type_R;
parameter [5:0] Op_Sub = Op_Type_R;
parameter [5:0] Op_Subu = Op_Type_R;
parameter [5:0] Op_Sw = 6'b10_1011;
parameter [5:0] Op_Swl = 6'b10_1010;
parameter [5:0] Op_Swr = 6'b10_1110;
parameter [5:0] Op_Syscall = Op_Type_R;
parameter [5:0] Op_Teq = Op_Type_R;
parameter [5:0] Op_Teqi = Op_Type_BI;
parameter [5:0] Op_Tge = Op_Type_R;
parameter [5:0] Op_Tgei = Op_Type_BI;
parameter [5:0] Op_Tgeiu = Op_Type_BI;
parameter [5:0] Op_Tgeu = Op_Type_R;
parameter [5:0] Op_Tlt = Op_Type_R;
parameter [5:0] Op_Tlti = Op_Type_BI;
parameter [5:0] Op_Tltiu = Op_Type_BI;
parameter [5:0] Op_Tltu = Op_Type_R;
parameter [5:0] Op_Tne = Op_Type_R;
parameter [5:0] Op_Tnei = Op_Type_BI;
parameter [5:0] Op_Xor = Op_Type_R;
parameter [5:0] Op_Xori = 6'b00_1110;
 
/* Op Code Rt fields for Branches & Traps */
parameter [4:0] OpRt_Bgez = 5'b00001;
parameter [4:0] OpRt_Bgezal = 5'b10001;
parameter [4:0] OpRt_Bltz = 5'b00000;
parameter [4:0] OpRt_Bltzal = 5'b10000;
parameter [4:0] OpRt_Teqi = 5'b01100;
parameter [4:0] OpRt_Tgei = 5'b01000;
parameter [4:0] OpRt_Tgeiu = 5'b01001;
parameter [4:0] OpRt_Tlti = 5'b01010;
parameter [4:0] OpRt_Tltiu = 5'b01011;
parameter [4:0] OpRt_Tnei = 5'b01110;
 
/* Op Code Rs fields for Coprocessors */
parameter [4:0] OpRs_MF = 5'b00000;
parameter [4:0] OpRs_MT = 5'b00100;
 
/* Special handling for ERET */
parameter [4:0] OpRs_ERET = 5'b10000;
parameter [5:0] Funct_ERET = 6'b011000;
 
/* Function Codes for R-Type Op Codes */
parameter [5:0] Funct_Add = 6'b10_0000;
parameter [5:0] Funct_Addu = 6'b10_0001;
parameter [5:0] Funct_And = 6'b10_0100;
parameter [5:0] Funct_Break = 6'b00_1101;
parameter [5:0] Funct_Clo = 6'b10_0001; // same as Addu
parameter [5:0] Funct_Clz = 6'b10_0000; // same as Add
parameter [5:0] Funct_Div = 6'b01_1010;
parameter [5:0] Funct_Divu = 6'b01_1011;
parameter [5:0] Funct_Jr = 6'b00_1000;
parameter [5:0] Funct_Jalr = 6'b00_1001;
parameter [5:0] Funct_Madd = 6'b00_0000;
parameter [5:0] Funct_Maddu = 6'b00_0001;
parameter [5:0] Funct_Mfhi = 6'b01_0000;
parameter [5:0] Funct_Mflo = 6'b01_0010;
parameter [5:0] Funct_Movn = 6'b00_1011;
parameter [5:0] Funct_Movz = 6'b00_1010;
parameter [5:0] Funct_Msub = 6'b00_0100; // same as Sllv
parameter [5:0] Funct_Msubu = 6'b00_0101;
parameter [5:0] Funct_Mthi = 6'b01_0001;
parameter [5:0] Funct_Mtlo = 6'b01_0011;
parameter [5:0] Funct_Mul = 6'b00_0010; // same as Srl
parameter [5:0] Funct_Mult = 6'b01_1000;
parameter [5:0] Funct_Multu = 6'b01_1001;
parameter [5:0] Funct_Nor = 6'b10_0111;
parameter [5:0] Funct_Or = 6'b10_0101;
parameter [5:0] Funct_Sll = 6'b00_0000;
parameter [5:0] Funct_Sllv = 6'b00_0100;
parameter [5:0] Funct_Slt = 6'b10_1010;
parameter [5:0] Funct_Sltu = 6'b10_1011;
parameter [5:0] Funct_Sra = 6'b00_0011;
parameter [5:0] Funct_Srav = 6'b00_0111;
parameter [5:0] Funct_Srl = 6'b00_0010;
parameter [5:0] Funct_Srlv = 6'b00_0110;
parameter [5:0] Funct_Sub = 6'b10_0010;
parameter [5:0] Funct_Subu = 6'b10_0011;
parameter [5:0] Funct_Syscall = 6'b00_1100;
parameter [5:0] Funct_Teq = 6'b11_0100;
parameter [5:0] Funct_Tge = 6'b11_0000;
parameter [5:0] Funct_Tgeu = 6'b11_0001;
parameter [5:0] Funct_Tlt = 6'b11_0010;
parameter [5:0] Funct_Tltu = 6'b11_0011;
parameter [5:0] Funct_Tne = 6'b11_0110;
parameter [5:0] Funct_Xor = 6'b10_0110;
 
/* ALU Operations (Implementation) */
parameter [4:0] AluOp_Add = 5'd1;
parameter [4:0] AluOp_Addu = 5'd0;
parameter [4:0] AluOp_And = 5'd2;
parameter [4:0] AluOp_Clo = 5'd3;
parameter [4:0] AluOp_Clz = 5'd4;
parameter [4:0] AluOp_Div = 5'd5;
parameter [4:0] AluOp_Divu = 5'd6;
parameter [4:0] AluOp_Madd = 5'd7;
parameter [4:0] AluOp_Maddu = 5'd8;
parameter [4:0] AluOp_Mfhi = 5'd9;
parameter [4:0] AluOp_Mflo = 5'd10;
parameter [4:0] AluOp_Msub = 5'd13;
parameter [4:0] AluOp_Msubu = 5'd14;
parameter [4:0] AluOp_Mthi = 5'd11;
parameter [4:0] AluOp_Mtlo = 5'd12;
parameter [4:0] AluOp_Mul = 5'd15;
parameter [4:0] AluOp_Mult = 5'd16;
parameter [4:0] AluOp_Multu = 5'd17;
parameter [4:0] AluOp_Nor = 5'd18;
parameter [4:0] AluOp_Or = 5'd19;
parameter [4:0] AluOp_Sll = 5'd20;
parameter [4:0] AluOp_Sllc = 5'd21; // Move this if another AluOp is needed
parameter [4:0] AluOp_Sllv = 5'd22;
parameter [4:0] AluOp_Slt = 5'd23;
parameter [4:0] AluOp_Sltu = 5'd24;
parameter [4:0] AluOp_Sra = 5'd25;
parameter [4:0] AluOp_Srav = 5'd26;
parameter [4:0] AluOp_Srl = 5'd27;
parameter [4:0] AluOp_Srlv = 5'd28;
parameter [4:0] AluOp_Sub = 5'd29;
parameter [4:0] AluOp_Subu = 5'd30;
parameter [4:0] AluOp_Xor = 5'd31;
 
 
// Movc:10->11, Trap:9->10, TrapCond:8->9, RegDst:7->8
/*** Datapath ***
 
All Signals are Active High. Branching and Jump signals (determined by "PCSrc"),
as well as ALU operation signals ("ALUOp") are handled by the controller and are not found here.
 
Bit Name Description
------------------------------
15: PCSrc (Instruction Type)
14: 11: Instruction is Jump to Register
10: Instruction is Branch
01: Instruction is Jump to Immediate
00: Instruction does not branch nor jump
13: Link (Link on Branch/Jump)
------------------------------
12: ALUSrc (ALU Source) [0=ALU input B is 2nd register file output; 1=Immediate value]
11: Movc (Conditional Move)
10: Trap (Trap Instruction)
9 : TrapCond (Trap Condition) [0=ALU result is 0; 1=ALU result is not 0]
8 : RegDst (Register File Target) [0=Rt field; 1=Rd field]
------------------------------
7 : LLSC (Load Linked or Store Conditional)
6 : MemRead (Data Memory Read)
5 : MemWrite (Data Memory Write)
4 : MemHalf (Half Word Memory Access)
3 : MemByte (Byte size Memory Access)
2 : MemSignExtend (Sign Extend Read Memory) [0=Zero Extend; 1=Sign Extend]
------------------------------
1 : RegWrite (Register File Write)
0 : MemtoReg (Memory to Register) [0=Register File write data is ALU output; 1=Is Data Memory]
------------------------------
*/
parameter [15:0] DP_None = 16'b000_00000_000000_00; // Instructions which require nothing of the main datapath.
parameter [15:0] DP_RType = 16'b000_00001_000000_10; // Standard R-Type
parameter [15:0] DP_IType = 16'b000_10000_000000_10; // Standard I-Type
parameter [15:0] DP_Branch = 16'b100_00000_000000_00; // Standard Branch
parameter [15:0] DP_BranchLink = 16'b101_00000_000000_10; // Branch and Link
parameter [15:0] DP_HiLoWr = 16'b000_00000_000000_00; // Write to Hi/Lo ALU register (Div,Divu,Mult,Multu,Mthi,Mtlo). Currently 'DP_None'.
parameter [15:0] DP_Jump = 16'b010_00000_000000_00; // Standard Jump
parameter [15:0] DP_JumpLink = 16'b011_00000_000000_10; // Jump and Link
parameter [15:0] DP_JumpLinkReg = 16'b111_00000_000000_10; // Jump and Link Register
parameter [15:0] DP_JumpReg = 16'b110_00000_000000_00; // Jump Register
parameter [15:0] DP_LoadByteS = 16'b000_10000_010011_11; // Load Byte Signed
parameter [15:0] DP_LoadByteU = 16'b000_10000_010010_11; // Load Byte Unsigned
parameter [15:0] DP_LoadHalfS = 16'b000_10000_010101_11; // Load Half Signed
parameter [15:0] DP_LoadHalfU = 16'b000_10000_010100_11; // Load Half Unsigned
parameter [15:0] DP_LoadWord = 16'b000_10000_010000_11; // Load Word
parameter [15:0] DP_ExtWrRt = 16'b000_00000_000000_10; // A DP-external write to Rt
parameter [15:0] DP_ExtWrRd = 16'b000_00001_000000_10; // A DP-external write to Rd
parameter [15:0] DP_Movc = 16'b000_01001_000000_10; // Conditional Move
parameter [15:0] DP_LoadLinked = 16'b000_10000_110000_11; // Load Linked
parameter [15:0] DP_StoreCond = 16'b000_10000_101000_11; // Store Conditional
parameter [15:0] DP_StoreByte = 16'b000_10000_001010_00; // Store Byte
parameter [15:0] DP_StoreHalf = 16'b000_10000_001100_00; // Store Half
parameter [15:0] DP_StoreWord = 16'b000_10000_001000_00; // Store Word
parameter [15:0] DP_TrapRegCNZ = 16'b000_00110_000000_00; // Trap using Rs and Rt, non-zero ALU (Tlt, Tltu, Tne)
parameter [15:0] DP_TrapRegCZ = 16'b000_00100_000000_00; // Trap using RS and Rt, zero ALU (Teq, Tge, Tgeu)
parameter [15:0] DP_TrapImmCNZ = 16'b000_10110_000000_00; // Trap using Rs and Imm, non-zero ALU (Tlti, Tltiu, Tnei)
parameter [15:0] DP_TrapImmCZ = 16'b000_10100_000000_00; // Trap using Rs and Imm, zero ALU (Teqi, Tgei, Tgeiu)
//--------------------------------------------------------
/*
* File : MIPS_Parameters.v
* Project : University of Utah, XUM Project MIPS32 core
* Creator(s) : Grant Ayers (ayers@cs.utah.edu)
*
* Modification History:
* Rev Date Initials Description of Change
* 1.0 26-May-2012 GEA Release version.
*
* Standards/Formatting:
* Verilog 2001, 4 soft tab, wide column.
*
* Description:
* Provides a language abstraction for the MIPS32-specific op-codes and
* the processor-specific datapath, hazard, and exception bits which
* control the processor. These parameter names are used extensively
* throughout the processor HDL modules.
*/
 
 
/*** Exception Vector Locations ***
When the CPU powers up or is reset, it will begin execution at 'EXC_Vector_Base_Reset'.
All other exceptions are the sum of a base address and offset:
- The base address is either a bootstrap or normal value. It is controlled by
the 'BEV' bit in the CP0 'Status' register. Both base addresses can be mapped to
the same location.
- The offset address is either a standard offset (which is always used for
non-interrupt general exceptions in this processor because it lacks TLB Refill
and Cache errors), or a special interrupt-only offset for interrupts, which is
enabled with the 'IV' bit in the CP0 'Cause' register.
Current Setup:
General exceptions go to 0x0. Interrupts go to 0x8. Booting starts at 0x10.
*/
parameter [31:0] EXC_Vector_Base_Reset = 32'h0000_0010; // MIPS Standard is 0xBFC0_0000
parameter [31:0] EXC_Vector_Base_Other_NoBoot = 32'h0000_0000; // MIPS Standard is 0x8000_0000
parameter [31:0] EXC_Vector_Base_Other_Boot = 32'h0000_0000; // MIPS Standard is 0xBFC0_0200
parameter [31:0] EXC_Vector_Offset_General = 32'h0000_0000; // MIPS Standard is 0x0000_0180
parameter [31:0] EXC_Vector_Offset_Special = 32'h0000_0008; // MIPS Standard is 0x0000_0200
 
 
 
/*** Kernel/User Memory Areas ***
 
Kernel memory starts at address 0x0. User memory starts at 'UMem_Lower' and extends to
the end of the address space.
A distinction is made to protect against accesses to kernel memory while the processor
is in user mode. Lacking MMU hardware, these addresses are physical, not virtual.
This simple two-part division of the address space can be extended almost arbitrarily
in the Data Memory Controller. Note that there is currently no user/kernel space check
for the Instruction Memory, because it is assumed that instructions are in the kernel space.
*/
parameter [31:0] UMem_Lower = 32'h08000000;
 
 
 
/*** Processor Endianness ***
 
MIPS32 allows user-mode addresses to be configured as big- or little-endian. For simplicity
reasons, this processor fixes the endianness to little endian. To add support for both
modes, the Data Memory Controller should be updated as well as CP0, which should change
the 'RE' bit in the Status register from a wire to a writable register.
*/
parameter Big_Endian = 0;
 
 
 
/*** Encodings for MIPS32 Release 1 Architecture ***/
 
 
/* Op Code Categories */
parameter [5:0] Op_Type_R = 6'b00_0000; // Standard R-Type instructions
parameter [5:0] Op_Type_R2 = 6'b01_1100; // Extended R-Like instructions
parameter [5:0] Op_Type_BI = 6'b00_0001; // Branch/Trap extended instructions
parameter [5:0] Op_Type_CP0 = 6'b01_0000; // Coprocessor 0 instructions
parameter [5:0] Op_Type_CP1 = 6'b01_0001; // Coprocessor 1 instructions (not implemented)
parameter [5:0] Op_Type_CP2 = 6'b01_0010; // Coprocessor 2 instructions (not implemented)
parameter [5:0] Op_Type_CP3 = 6'b01_0011; // Coprocessor 3 instructions (not implemented)
// --------------------------------------
parameter [5:0] Op_Add = Op_Type_R;
parameter [5:0] Op_Addi = 6'b00_1000;
parameter [5:0] Op_Addiu = 6'b00_1001;
parameter [5:0] Op_Addu = Op_Type_R;
parameter [5:0] Op_And = Op_Type_R;
parameter [5:0] Op_Andi = 6'b00_1100;
parameter [5:0] Op_Beq = 6'b00_0100;
parameter [5:0] Op_Bgez = Op_Type_BI;
parameter [5:0] Op_Bgezal = Op_Type_BI;
parameter [5:0] Op_Bgtz = 6'b00_0111;
parameter [5:0] Op_Blez = 6'b00_0110;
parameter [5:0] Op_Bltz = Op_Type_BI;
parameter [5:0] Op_Bltzal = Op_Type_BI;
parameter [5:0] Op_Bne = 6'b00_0101;
parameter [5:0] Op_Break = Op_Type_R;
parameter [5:0] Op_Clo = Op_Type_R2;
parameter [5:0] Op_Clz = Op_Type_R2;
parameter [5:0] Op_Div = Op_Type_R;
parameter [5:0] Op_Divu = Op_Type_R;
parameter [5:0] Op_Eret = Op_Type_CP0;
parameter [5:0] Op_J = 6'b00_0010;
parameter [5:0] Op_Jal = 6'b00_0011;
parameter [5:0] Op_Jalr = Op_Type_R;
parameter [5:0] Op_Jr = Op_Type_R;
parameter [5:0] Op_Lb = 6'b10_0000;
parameter [5:0] Op_Lbu = 6'b10_0100;
parameter [5:0] Op_Lh = 6'b10_0001;
parameter [5:0] Op_Lhu = 6'b10_0101;
parameter [5:0] Op_Ll = 6'b11_0000;
parameter [5:0] Op_Lui = 6'b00_1111;
parameter [5:0] Op_Lw = 6'b10_0011;
parameter [5:0] Op_Lwl = 6'b10_0010;
parameter [5:0] Op_Lwr = 6'b10_0110;
parameter [5:0] Op_Madd = Op_Type_R2;
parameter [5:0] Op_Maddu = Op_Type_R2;
parameter [5:0] Op_Mfc0 = Op_Type_CP0;
parameter [5:0] Op_Mfhi = Op_Type_R;
parameter [5:0] Op_Mflo = Op_Type_R;
parameter [5:0] Op_Movn = Op_Type_R;
parameter [5:0] Op_Movz = Op_Type_R;
parameter [5:0] Op_Msub = Op_Type_R2;
parameter [5:0] Op_Msubu = Op_Type_R2;
parameter [5:0] Op_Mtc0 = Op_Type_CP0;
parameter [5:0] Op_Mthi = Op_Type_R;
parameter [5:0] Op_Mtlo = Op_Type_R;
parameter [5:0] Op_Mul = Op_Type_R2;
parameter [5:0] Op_Mult = Op_Type_R;
parameter [5:0] Op_Multu = Op_Type_R;
parameter [5:0] Op_Nor = Op_Type_R;
parameter [5:0] Op_Or = Op_Type_R;
parameter [5:0] Op_Ori = 6'b00_1101;
parameter [5:0] Op_Pref = 6'b11_0011; // Prefetch does nothing in this implementation.
parameter [5:0] Op_Sb = 6'b10_1000;
parameter [5:0] Op_Sc = 6'b11_1000;
parameter [5:0] Op_Sh = 6'b10_1001;
parameter [5:0] Op_Sll = Op_Type_R;
parameter [5:0] Op_Sllv = Op_Type_R;
parameter [5:0] Op_Slt = Op_Type_R;
parameter [5:0] Op_Slti = 6'b00_1010;
parameter [5:0] Op_Sltiu = 6'b00_1011;
parameter [5:0] Op_Sltu = Op_Type_R;
parameter [5:0] Op_Sra = Op_Type_R;
parameter [5:0] Op_Srav = Op_Type_R;
parameter [5:0] Op_Srl = Op_Type_R;
parameter [5:0] Op_Srlv = Op_Type_R;
parameter [5:0] Op_Sub = Op_Type_R;
parameter [5:0] Op_Subu = Op_Type_R;
parameter [5:0] Op_Sw = 6'b10_1011;
parameter [5:0] Op_Swl = 6'b10_1010;
parameter [5:0] Op_Swr = 6'b10_1110;
parameter [5:0] Op_Syscall = Op_Type_R;
parameter [5:0] Op_Teq = Op_Type_R;
parameter [5:0] Op_Teqi = Op_Type_BI;
parameter [5:0] Op_Tge = Op_Type_R;
parameter [5:0] Op_Tgei = Op_Type_BI;
parameter [5:0] Op_Tgeiu = Op_Type_BI;
parameter [5:0] Op_Tgeu = Op_Type_R;
parameter [5:0] Op_Tlt = Op_Type_R;
parameter [5:0] Op_Tlti = Op_Type_BI;
parameter [5:0] Op_Tltiu = Op_Type_BI;
parameter [5:0] Op_Tltu = Op_Type_R;
parameter [5:0] Op_Tne = Op_Type_R;
parameter [5:0] Op_Tnei = Op_Type_BI;
parameter [5:0] Op_Xor = Op_Type_R;
parameter [5:0] Op_Xori = 6'b00_1110;
 
/* Op Code Rt fields for Branches & Traps */
parameter [4:0] OpRt_Bgez = 5'b00001;
parameter [4:0] OpRt_Bgezal = 5'b10001;
parameter [4:0] OpRt_Bltz = 5'b00000;
parameter [4:0] OpRt_Bltzal = 5'b10000;
parameter [4:0] OpRt_Teqi = 5'b01100;
parameter [4:0] OpRt_Tgei = 5'b01000;
parameter [4:0] OpRt_Tgeiu = 5'b01001;
parameter [4:0] OpRt_Tlti = 5'b01010;
parameter [4:0] OpRt_Tltiu = 5'b01011;
parameter [4:0] OpRt_Tnei = 5'b01110;
 
/* Op Code Rs fields for Coprocessors */
parameter [4:0] OpRs_MF = 5'b00000;
parameter [4:0] OpRs_MT = 5'b00100;
 
/* Special handling for ERET */
parameter [4:0] OpRs_ERET = 5'b10000;
parameter [5:0] Funct_ERET = 6'b011000;
 
/* Function Codes for R-Type Op Codes */
parameter [5:0] Funct_Add = 6'b10_0000;
parameter [5:0] Funct_Addu = 6'b10_0001;
parameter [5:0] Funct_And = 6'b10_0100;
parameter [5:0] Funct_Break = 6'b00_1101;
parameter [5:0] Funct_Clo = 6'b10_0001; // same as Addu
parameter [5:0] Funct_Clz = 6'b10_0000; // same as Add
parameter [5:0] Funct_Div = 6'b01_1010;
parameter [5:0] Funct_Divu = 6'b01_1011;
parameter [5:0] Funct_Jr = 6'b00_1000;
parameter [5:0] Funct_Jalr = 6'b00_1001;
parameter [5:0] Funct_Madd = 6'b00_0000;
parameter [5:0] Funct_Maddu = 6'b00_0001;
parameter [5:0] Funct_Mfhi = 6'b01_0000;
parameter [5:0] Funct_Mflo = 6'b01_0010;
parameter [5:0] Funct_Movn = 6'b00_1011;
parameter [5:0] Funct_Movz = 6'b00_1010;
parameter [5:0] Funct_Msub = 6'b00_0100; // same as Sllv
parameter [5:0] Funct_Msubu = 6'b00_0101;
parameter [5:0] Funct_Mthi = 6'b01_0001;
parameter [5:0] Funct_Mtlo = 6'b01_0011;
parameter [5:0] Funct_Mul = 6'b00_0010; // same as Srl
parameter [5:0] Funct_Mult = 6'b01_1000;
parameter [5:0] Funct_Multu = 6'b01_1001;
parameter [5:0] Funct_Nor = 6'b10_0111;
parameter [5:0] Funct_Or = 6'b10_0101;
parameter [5:0] Funct_Sll = 6'b00_0000;
parameter [5:0] Funct_Sllv = 6'b00_0100;
parameter [5:0] Funct_Slt = 6'b10_1010;
parameter [5:0] Funct_Sltu = 6'b10_1011;
parameter [5:0] Funct_Sra = 6'b00_0011;
parameter [5:0] Funct_Srav = 6'b00_0111;
parameter [5:0] Funct_Srl = 6'b00_0010;
parameter [5:0] Funct_Srlv = 6'b00_0110;
parameter [5:0] Funct_Sub = 6'b10_0010;
parameter [5:0] Funct_Subu = 6'b10_0011;
parameter [5:0] Funct_Syscall = 6'b00_1100;
parameter [5:0] Funct_Teq = 6'b11_0100;
parameter [5:0] Funct_Tge = 6'b11_0000;
parameter [5:0] Funct_Tgeu = 6'b11_0001;
parameter [5:0] Funct_Tlt = 6'b11_0010;
parameter [5:0] Funct_Tltu = 6'b11_0011;
parameter [5:0] Funct_Tne = 6'b11_0110;
parameter [5:0] Funct_Xor = 6'b10_0110;
 
/* ALU Operations (Implementation) */
parameter [4:0] AluOp_Add = 5'd1;
parameter [4:0] AluOp_Addu = 5'd0;
parameter [4:0] AluOp_And = 5'd2;
parameter [4:0] AluOp_Clo = 5'd3;
parameter [4:0] AluOp_Clz = 5'd4;
parameter [4:0] AluOp_Div = 5'd5;
parameter [4:0] AluOp_Divu = 5'd6;
parameter [4:0] AluOp_Madd = 5'd7;
parameter [4:0] AluOp_Maddu = 5'd8;
parameter [4:0] AluOp_Mfhi = 5'd9;
parameter [4:0] AluOp_Mflo = 5'd10;
parameter [4:0] AluOp_Msub = 5'd13;
parameter [4:0] AluOp_Msubu = 5'd14;
parameter [4:0] AluOp_Mthi = 5'd11;
parameter [4:0] AluOp_Mtlo = 5'd12;
parameter [4:0] AluOp_Mul = 5'd15;
parameter [4:0] AluOp_Mult = 5'd16;
parameter [4:0] AluOp_Multu = 5'd17;
parameter [4:0] AluOp_Nor = 5'd18;
parameter [4:0] AluOp_Or = 5'd19;
parameter [4:0] AluOp_Sll = 5'd20;
parameter [4:0] AluOp_Sllc = 5'd21; // Move this if another AluOp is needed
parameter [4:0] AluOp_Sllv = 5'd22;
parameter [4:0] AluOp_Slt = 5'd23;
parameter [4:0] AluOp_Sltu = 5'd24;
parameter [4:0] AluOp_Sra = 5'd25;
parameter [4:0] AluOp_Srav = 5'd26;
parameter [4:0] AluOp_Srl = 5'd27;
parameter [4:0] AluOp_Srlv = 5'd28;
parameter [4:0] AluOp_Sub = 5'd29;
parameter [4:0] AluOp_Subu = 5'd30;
parameter [4:0] AluOp_Xor = 5'd31;
 
 
// Movc:10->11, Trap:9->10, TrapCond:8->9, RegDst:7->8
/*** Datapath ***
 
All Signals are Active High. Branching and Jump signals (determined by "PCSrc"),
as well as ALU operation signals ("ALUOp") are handled by the controller and are not found here.
 
Bit Name Description
------------------------------
15: PCSrc (Instruction Type)
14: 11: Instruction is Jump to Register
10: Instruction is Branch
01: Instruction is Jump to Immediate
00: Instruction does not branch nor jump
13: Link (Link on Branch/Jump)
------------------------------
12: ALUSrc (ALU Source) [0=ALU input B is 2nd register file output; 1=Immediate value]
11: Movc (Conditional Move)
10: Trap (Trap Instruction)
9 : TrapCond (Trap Condition) [0=ALU result is 0; 1=ALU result is not 0]
8 : RegDst (Register File Target) [0=Rt field; 1=Rd field]
------------------------------
7 : LLSC (Load Linked or Store Conditional)
6 : MemRead (Data Memory Read)
5 : MemWrite (Data Memory Write)
4 : MemHalf (Half Word Memory Access)
3 : MemByte (Byte size Memory Access)
2 : MemSignExtend (Sign Extend Read Memory) [0=Zero Extend; 1=Sign Extend]
------------------------------
1 : RegWrite (Register File Write)
0 : MemtoReg (Memory to Register) [0=Register File write data is ALU output; 1=Is Data Memory]
------------------------------
*/
parameter [15:0] DP_None = 16'b000_00000_000000_00; // Instructions which require nothing of the main datapath.
parameter [15:0] DP_RType = 16'b000_00001_000000_10; // Standard R-Type
parameter [15:0] DP_IType = 16'b000_10000_000000_10; // Standard I-Type
parameter [15:0] DP_Branch = 16'b100_00000_000000_00; // Standard Branch
parameter [15:0] DP_BranchLink = 16'b101_00000_000000_10; // Branch and Link
parameter [15:0] DP_HiLoWr = 16'b000_00000_000000_00; // Write to Hi/Lo ALU register (Div,Divu,Mult,Multu,Mthi,Mtlo). Currently 'DP_None'.
parameter [15:0] DP_Jump = 16'b010_00000_000000_00; // Standard Jump
parameter [15:0] DP_JumpLink = 16'b011_00000_000000_10; // Jump and Link
parameter [15:0] DP_JumpLinkReg = 16'b111_00000_000000_10; // Jump and Link Register
parameter [15:0] DP_JumpReg = 16'b110_00000_000000_00; // Jump Register
parameter [15:0] DP_LoadByteS = 16'b000_10000_010011_11; // Load Byte Signed
parameter [15:0] DP_LoadByteU = 16'b000_10000_010010_11; // Load Byte Unsigned
parameter [15:0] DP_LoadHalfS = 16'b000_10000_010101_11; // Load Half Signed
parameter [15:0] DP_LoadHalfU = 16'b000_10000_010100_11; // Load Half Unsigned
parameter [15:0] DP_LoadWord = 16'b000_10000_010000_11; // Load Word
parameter [15:0] DP_ExtWrRt = 16'b000_00000_000000_10; // A DP-external write to Rt
parameter [15:0] DP_ExtWrRd = 16'b000_00001_000000_10; // A DP-external write to Rd
parameter [15:0] DP_Movc = 16'b000_01001_000000_10; // Conditional Move
parameter [15:0] DP_LoadLinked = 16'b000_10000_110000_11; // Load Linked
parameter [15:0] DP_StoreCond = 16'b000_10000_101000_11; // Store Conditional
parameter [15:0] DP_StoreByte = 16'b000_10000_001010_00; // Store Byte
parameter [15:0] DP_StoreHalf = 16'b000_10000_001100_00; // Store Half
parameter [15:0] DP_StoreWord = 16'b000_10000_001000_00; // Store Word
parameter [15:0] DP_TrapRegCNZ = 16'b000_00110_000000_00; // Trap using Rs and Rt, non-zero ALU (Tlt, Tltu, Tne)
parameter [15:0] DP_TrapRegCZ = 16'b000_00100_000000_00; // Trap using RS and Rt, zero ALU (Teq, Tge, Tgeu)
parameter [15:0] DP_TrapImmCNZ = 16'b000_10110_000000_00; // Trap using Rs and Imm, non-zero ALU (Tlti, Tltiu, Tnei)
parameter [15:0] DP_TrapImmCZ = 16'b000_10100_000000_00; // Trap using Rs and Imm, zero ALU (Teqi, Tgei, Tgeiu)
//--------------------------------------------------------
parameter [15:0] DP_Add = DP_RType;
parameter [15:0] DP_Addi = DP_IType;
parameter [15:0] DP_Addiu = DP_IType;
410,223 → 410,223
parameter [15:0] DP_Tne = DP_TrapRegCNZ;
parameter [15:0] DP_Tnei = DP_TrapImmCNZ;
parameter [15:0] DP_Xor = DP_RType;
parameter [15:0] DP_Xori = DP_IType;
 
 
 
 
/*** Exception Information ***
 
All signals are Active High.
 
Bit Meaning
------------
2: Instruction can cause exceptions in ID
1: Instruction can cause exceptions in EX
0: Instruction can cause exceptions in MEM
*/
parameter [2:0] EXC_None = 3'b000;
parameter [2:0] EXC_ID = 3'b100;
parameter [2:0] EXC_EX = 3'b010;
parameter [2:0] EXC_MEM = 3'b001;
//--------------------------------
parameter [2:0] EXC_Add = EXC_EX;
parameter [2:0] EXC_Addi = EXC_EX;
parameter [2:0] EXC_Addiu = EXC_None;
parameter [2:0] EXC_Addu = EXC_None;
parameter [2:0] EXC_And = EXC_None;
parameter [2:0] EXC_Andi = EXC_None;
parameter [2:0] EXC_Beq = EXC_None;
parameter [2:0] EXC_Bgez = EXC_None;
parameter [2:0] EXC_Bgezal = EXC_None;
parameter [2:0] EXC_Bgtz = EXC_None;
parameter [2:0] EXC_Blez = EXC_None;
parameter [2:0] EXC_Bltz = EXC_None;
parameter [2:0] EXC_Bltzal = EXC_None;
parameter [2:0] EXC_Bne = EXC_None;
parameter [2:0] EXC_Break = EXC_ID;
parameter [2:0] EXC_Clo = EXC_None;
parameter [2:0] EXC_Clz = EXC_None;
parameter [2:0] EXC_Div = EXC_None;
parameter [2:0] EXC_Divu = EXC_None;
parameter [2:0] EXC_Eret = EXC_ID;
parameter [2:0] EXC_J = EXC_None;
parameter [2:0] EXC_Jal = EXC_None;
parameter [2:0] EXC_Jalr = EXC_None;
parameter [2:0] EXC_Jr = EXC_None;
parameter [2:0] EXC_Lb = EXC_MEM;
parameter [2:0] EXC_Lbu = EXC_MEM;
parameter [2:0] EXC_Lh = EXC_MEM;
parameter [2:0] EXC_Lhu = EXC_MEM;
parameter [2:0] EXC_Ll = EXC_MEM;
parameter [2:0] EXC_Lui = EXC_None;
parameter [2:0] EXC_Lw = EXC_MEM;
parameter [2:0] EXC_Lwl = EXC_MEM;
parameter [2:0] EXC_Lwr = EXC_MEM;
parameter [2:0] EXC_Madd = EXC_None;
parameter [2:0] EXC_Maddu = EXC_None;
parameter [2:0] EXC_Mfc0 = EXC_ID;
parameter [2:0] EXC_Mfhi = EXC_None;
parameter [2:0] EXC_Mflo = EXC_None;
parameter [2:0] EXC_Movn = EXC_None;
parameter [2:0] EXC_Movz = EXC_None;
parameter [2:0] EXC_Msub = EXC_None;
parameter [2:0] EXC_Msubu = EXC_None;
parameter [2:0] EXC_Mtc0 = EXC_ID;
parameter [2:0] EXC_Mthi = EXC_None;
parameter [2:0] EXC_Mtlo = EXC_None;
parameter [2:0] EXC_Mul = EXC_None;
parameter [2:0] EXC_Mult = EXC_None;
parameter [2:0] EXC_Multu = EXC_None;
parameter [2:0] EXC_Nor = EXC_None;
parameter [2:0] EXC_Or = EXC_None;
parameter [2:0] EXC_Ori = EXC_None;
parameter [2:0] EXC_Pref = EXC_None; // XXX
parameter [2:0] EXC_Sb = EXC_MEM;
parameter [2:0] EXC_Sc = EXC_MEM;
parameter [2:0] EXC_Sh = EXC_MEM;
parameter [2:0] EXC_Sll = EXC_None;
parameter [2:0] EXC_Sllv = EXC_None;
parameter [2:0] EXC_Slt = EXC_None;
parameter [2:0] EXC_Slti = EXC_None;
parameter [2:0] EXC_Sltiu = EXC_None;
parameter [2:0] EXC_Sltu = EXC_None;
parameter [2:0] EXC_Sra = EXC_None;
parameter [2:0] EXC_Srav = EXC_None;
parameter [2:0] EXC_Srl = EXC_None;
parameter [2:0] EXC_Srlv = EXC_None;
parameter [2:0] EXC_Sub = EXC_EX;
parameter [2:0] EXC_Subu = EXC_None;
parameter [2:0] EXC_Sw = EXC_MEM;
parameter [2:0] EXC_Swl = EXC_MEM;
parameter [2:0] EXC_Swr = EXC_MEM;
parameter [2:0] EXC_Syscall = EXC_ID;
parameter [2:0] EXC_Teq = EXC_MEM;
parameter [2:0] EXC_Teqi = EXC_MEM;
parameter [2:0] EXC_Tge = EXC_MEM;
parameter [2:0] EXC_Tgei = EXC_MEM;
parameter [2:0] EXC_Tgeiu = EXC_MEM;
parameter [2:0] EXC_Tgeu = EXC_MEM;
parameter [2:0] EXC_Tlt = EXC_MEM;
parameter [2:0] EXC_Tlti = EXC_MEM;
parameter [2:0] EXC_Tltiu = EXC_MEM;
parameter [2:0] EXC_Tltu = EXC_MEM;
parameter [2:0] EXC_Tne = EXC_MEM;
parameter [2:0] EXC_Tnei = EXC_MEM;
parameter [2:0] EXC_Xor = EXC_None;
parameter [2:0] EXC_Xori = EXC_None;
 
 
 
 
/*** Hazard & Forwarding Datapath ***
 
All signals are Active High.
Bit Meaning
------------
7: Wants Rs by ID
6: Needs Rs by ID
5: Wants Rt by ID
4: Needs Rt by ID
3: Wants Rs by EX
2: Needs Rs by EX
1: Wants Rt by EX
0: Needs Rt by EX
*/
parameter [7:0] HAZ_Nothing = 8'b00000000; // Jumps, Lui, Mfhi/lo, special, etc.
parameter [7:0] HAZ_IDRsIDRt = 8'b11110000; // Beq, Bne, Traps
parameter [7:0] HAZ_IDRs = 8'b11000000; // Most branches, Jumps to registers
parameter [7:0] HAZ_IDRt = 8'b00110000; // Mtc0
parameter [7:0] HAZ_IDRtEXRs = 8'b10111100; // Movn, Movz
parameter [7:0] HAZ_EXRsEXRt = 8'b10101111; // Many R-Type ops
parameter [7:0] HAZ_EXRs = 8'b10001100; // Immediates: Loads, Clo/z, Mthi/lo, etc.
parameter [7:0] HAZ_EXRsWRt = 8'b10101110; // Stores
parameter [7:0] HAZ_EXRt = 8'b00100011; // Shifts using Shamt field
//-----------------------------------------
parameter [7:0] HAZ_Add = HAZ_EXRsEXRt;
parameter [7:0] HAZ_Addi = HAZ_EXRs;
parameter [7:0] HAZ_Addiu = HAZ_EXRs;
parameter [7:0] HAZ_Addu = HAZ_EXRsEXRt;
parameter [7:0] HAZ_And = HAZ_EXRsEXRt;
parameter [7:0] HAZ_Andi = HAZ_EXRs;
parameter [7:0] HAZ_Beq = HAZ_IDRsIDRt;
parameter [7:0] HAZ_Bgez = HAZ_IDRs;
parameter [7:0] HAZ_Bgezal = HAZ_IDRs;
parameter [7:0] HAZ_Bgtz = HAZ_IDRs;
parameter [7:0] HAZ_Blez = HAZ_IDRs;
parameter [7:0] HAZ_Bltz = HAZ_IDRs;
parameter [7:0] HAZ_Bltzal = HAZ_IDRs;
parameter [7:0] HAZ_Bne = HAZ_IDRsIDRt;
parameter [7:0] HAZ_Break = HAZ_Nothing;
parameter [7:0] HAZ_Clo = HAZ_EXRs;
parameter [7:0] HAZ_Clz = HAZ_EXRs;
parameter [7:0] HAZ_Div = HAZ_EXRsEXRt;
parameter [7:0] HAZ_Divu = HAZ_EXRsEXRt;
parameter [7:0] HAZ_Eret = HAZ_Nothing;
parameter [7:0] HAZ_J = HAZ_Nothing;
parameter [7:0] HAZ_Jal = HAZ_Nothing;
parameter [7:0] HAZ_Jalr = HAZ_IDRs;
parameter [7:0] HAZ_Jr = HAZ_IDRs;
parameter [7:0] HAZ_Lb = HAZ_EXRs;
parameter [7:0] HAZ_Lbu = HAZ_EXRs;
parameter [7:0] HAZ_Lh = HAZ_EXRs;
parameter [7:0] HAZ_Lhu = HAZ_EXRs;
parameter [7:0] HAZ_Ll = HAZ_EXRs;
parameter [7:0] HAZ_Lui = HAZ_Nothing;
parameter [7:0] HAZ_Lw = HAZ_EXRs;
parameter [7:0] HAZ_Lwl = HAZ_EXRsEXRt;
parameter [7:0] HAZ_Lwr = HAZ_EXRsEXRt;
parameter [7:0] HAZ_Madd = HAZ_EXRsEXRt;
parameter [7:0] HAZ_Maddu = HAZ_EXRsEXRt;
parameter [7:0] HAZ_Mfc0 = HAZ_Nothing;
parameter [7:0] HAZ_Mfhi = HAZ_Nothing;
parameter [7:0] HAZ_Mflo = HAZ_Nothing;
parameter [7:0] HAZ_Movn = HAZ_IDRtEXRs;
parameter [7:0] HAZ_Movz = HAZ_IDRtEXRs;
parameter [7:0] HAZ_Msub = HAZ_EXRsEXRt;
parameter [7:0] HAZ_Msubu = HAZ_EXRsEXRt;
parameter [7:0] HAZ_Mtc0 = HAZ_IDRt;
parameter [7:0] HAZ_Mthi = HAZ_EXRs;
parameter [7:0] HAZ_Mtlo = HAZ_EXRs;
parameter [7:0] HAZ_Mul = HAZ_EXRsEXRt;
parameter [7:0] HAZ_Mult = HAZ_EXRsEXRt;
parameter [7:0] HAZ_Multu = HAZ_EXRsEXRt;
parameter [7:0] HAZ_Nor = HAZ_EXRsEXRt;
parameter [7:0] HAZ_Or = HAZ_EXRsEXRt;
parameter [7:0] HAZ_Ori = HAZ_EXRs;
parameter [7:0] HAZ_Pref = HAZ_Nothing; // XXX
parameter [7:0] HAZ_Sb = HAZ_EXRsWRt;
parameter [7:0] HAZ_Sc = HAZ_EXRsWRt;
parameter [7:0] HAZ_Sh = HAZ_EXRsWRt;
parameter [7:0] HAZ_Sll = HAZ_EXRt;
parameter [7:0] HAZ_Sllv = HAZ_EXRsEXRt;
parameter [7:0] HAZ_Slt = HAZ_EXRsEXRt;
parameter [7:0] HAZ_Slti = HAZ_EXRs;
parameter [7:0] HAZ_Sltiu = HAZ_EXRs;
parameter [7:0] HAZ_Sltu = HAZ_EXRsEXRt;
parameter [7:0] HAZ_Sra = HAZ_EXRt;
parameter [7:0] HAZ_Srav = HAZ_EXRsEXRt;
parameter [7:0] HAZ_Srl = HAZ_EXRt;
parameter [7:0] HAZ_Srlv = HAZ_EXRsEXRt;
parameter [7:0] HAZ_Sub = HAZ_EXRsEXRt;
parameter [7:0] HAZ_Subu = HAZ_EXRsEXRt;
parameter [7:0] HAZ_Sw = HAZ_EXRsWRt;
parameter [7:0] HAZ_Swl = HAZ_EXRsWRt;
parameter [7:0] HAZ_Swr = HAZ_EXRsWRt;
parameter [7:0] HAZ_Syscall = HAZ_Nothing;
parameter [7:0] HAZ_Teq = HAZ_EXRsEXRt;
parameter [7:0] HAZ_Teqi = HAZ_EXRs;
parameter [7:0] HAZ_Tge = HAZ_EXRsEXRt;
parameter [7:0] HAZ_Tgei = HAZ_EXRs;
parameter [7:0] HAZ_Tgeiu = HAZ_EXRs;
parameter [7:0] HAZ_Tgeu = HAZ_EXRsEXRt;
parameter [7:0] HAZ_Tlt = HAZ_EXRsEXRt;
parameter [7:0] HAZ_Tlti = HAZ_EXRs;
parameter [7:0] HAZ_Tltiu = HAZ_EXRs;
parameter [7:0] HAZ_Tltu = HAZ_EXRsEXRt;
parameter [7:0] HAZ_Tne = HAZ_EXRsEXRt;
parameter [7:0] HAZ_Tnei = HAZ_EXRs;
parameter [7:0] HAZ_Xor = HAZ_EXRsEXRt;
parameter [7:0] HAZ_Xori = HAZ_EXRs;
 
parameter [15:0] DP_Xori = DP_IType;
 
 
 
 
/*** Exception Information ***
 
All signals are Active High.
 
Bit Meaning
------------
2: Instruction can cause exceptions in ID
1: Instruction can cause exceptions in EX
0: Instruction can cause exceptions in MEM
*/
parameter [2:0] EXC_None = 3'b000;
parameter [2:0] EXC_ID = 3'b100;
parameter [2:0] EXC_EX = 3'b010;
parameter [2:0] EXC_MEM = 3'b001;
//--------------------------------
parameter [2:0] EXC_Add = EXC_EX;
parameter [2:0] EXC_Addi = EXC_EX;
parameter [2:0] EXC_Addiu = EXC_None;
parameter [2:0] EXC_Addu = EXC_None;
parameter [2:0] EXC_And = EXC_None;
parameter [2:0] EXC_Andi = EXC_None;
parameter [2:0] EXC_Beq = EXC_None;
parameter [2:0] EXC_Bgez = EXC_None;
parameter [2:0] EXC_Bgezal = EXC_None;
parameter [2:0] EXC_Bgtz = EXC_None;
parameter [2:0] EXC_Blez = EXC_None;
parameter [2:0] EXC_Bltz = EXC_None;
parameter [2:0] EXC_Bltzal = EXC_None;
parameter [2:0] EXC_Bne = EXC_None;
parameter [2:0] EXC_Break = EXC_ID;
parameter [2:0] EXC_Clo = EXC_None;
parameter [2:0] EXC_Clz = EXC_None;
parameter [2:0] EXC_Div = EXC_None;
parameter [2:0] EXC_Divu = EXC_None;
parameter [2:0] EXC_Eret = EXC_ID;
parameter [2:0] EXC_J = EXC_None;
parameter [2:0] EXC_Jal = EXC_None;
parameter [2:0] EXC_Jalr = EXC_None;
parameter [2:0] EXC_Jr = EXC_None;
parameter [2:0] EXC_Lb = EXC_MEM;
parameter [2:0] EXC_Lbu = EXC_MEM;
parameter [2:0] EXC_Lh = EXC_MEM;
parameter [2:0] EXC_Lhu = EXC_MEM;
parameter [2:0] EXC_Ll = EXC_MEM;
parameter [2:0] EXC_Lui = EXC_None;
parameter [2:0] EXC_Lw = EXC_MEM;
parameter [2:0] EXC_Lwl = EXC_MEM;
parameter [2:0] EXC_Lwr = EXC_MEM;
parameter [2:0] EXC_Madd = EXC_None;
parameter [2:0] EXC_Maddu = EXC_None;
parameter [2:0] EXC_Mfc0 = EXC_ID;
parameter [2:0] EXC_Mfhi = EXC_None;
parameter [2:0] EXC_Mflo = EXC_None;
parameter [2:0] EXC_Movn = EXC_None;
parameter [2:0] EXC_Movz = EXC_None;
parameter [2:0] EXC_Msub = EXC_None;
parameter [2:0] EXC_Msubu = EXC_None;
parameter [2:0] EXC_Mtc0 = EXC_ID;
parameter [2:0] EXC_Mthi = EXC_None;
parameter [2:0] EXC_Mtlo = EXC_None;
parameter [2:0] EXC_Mul = EXC_None;
parameter [2:0] EXC_Mult = EXC_None;
parameter [2:0] EXC_Multu = EXC_None;
parameter [2:0] EXC_Nor = EXC_None;
parameter [2:0] EXC_Or = EXC_None;
parameter [2:0] EXC_Ori = EXC_None;
parameter [2:0] EXC_Pref = EXC_None; // XXX
parameter [2:0] EXC_Sb = EXC_MEM;
parameter [2:0] EXC_Sc = EXC_MEM;
parameter [2:0] EXC_Sh = EXC_MEM;
parameter [2:0] EXC_Sll = EXC_None;
parameter [2:0] EXC_Sllv = EXC_None;
parameter [2:0] EXC_Slt = EXC_None;
parameter [2:0] EXC_Slti = EXC_None;
parameter [2:0] EXC_Sltiu = EXC_None;
parameter [2:0] EXC_Sltu = EXC_None;
parameter [2:0] EXC_Sra = EXC_None;
parameter [2:0] EXC_Srav = EXC_None;
parameter [2:0] EXC_Srl = EXC_None;
parameter [2:0] EXC_Srlv = EXC_None;
parameter [2:0] EXC_Sub = EXC_EX;
parameter [2:0] EXC_Subu = EXC_None;
parameter [2:0] EXC_Sw = EXC_MEM;
parameter [2:0] EXC_Swl = EXC_MEM;
parameter [2:0] EXC_Swr = EXC_MEM;
parameter [2:0] EXC_Syscall = EXC_ID;
parameter [2:0] EXC_Teq = EXC_MEM;
parameter [2:0] EXC_Teqi = EXC_MEM;
parameter [2:0] EXC_Tge = EXC_MEM;
parameter [2:0] EXC_Tgei = EXC_MEM;
parameter [2:0] EXC_Tgeiu = EXC_MEM;
parameter [2:0] EXC_Tgeu = EXC_MEM;
parameter [2:0] EXC_Tlt = EXC_MEM;
parameter [2:0] EXC_Tlti = EXC_MEM;
parameter [2:0] EXC_Tltiu = EXC_MEM;
parameter [2:0] EXC_Tltu = EXC_MEM;
parameter [2:0] EXC_Tne = EXC_MEM;
parameter [2:0] EXC_Tnei = EXC_MEM;
parameter [2:0] EXC_Xor = EXC_None;
parameter [2:0] EXC_Xori = EXC_None;
 
 
 
 
/*** Hazard & Forwarding Datapath ***
 
All signals are Active High.
Bit Meaning
------------
7: Wants Rs by ID
6: Needs Rs by ID
5: Wants Rt by ID
4: Needs Rt by ID
3: Wants Rs by EX
2: Needs Rs by EX
1: Wants Rt by EX
0: Needs Rt by EX
*/
parameter [7:0] HAZ_Nothing = 8'b00000000; // Jumps, Lui, Mfhi/lo, special, etc.
parameter [7:0] HAZ_IDRsIDRt = 8'b11110000; // Beq, Bne, Traps
parameter [7:0] HAZ_IDRs = 8'b11000000; // Most branches, Jumps to registers
parameter [7:0] HAZ_IDRt = 8'b00110000; // Mtc0
parameter [7:0] HAZ_IDRtEXRs = 8'b10111100; // Movn, Movz
parameter [7:0] HAZ_EXRsEXRt = 8'b10101111; // Many R-Type ops
parameter [7:0] HAZ_EXRs = 8'b10001100; // Immediates: Loads, Clo/z, Mthi/lo, etc.
parameter [7:0] HAZ_EXRsWRt = 8'b10101110; // Stores
parameter [7:0] HAZ_EXRt = 8'b00100011; // Shifts using Shamt field
//-----------------------------------------
parameter [7:0] HAZ_Add = HAZ_EXRsEXRt;
parameter [7:0] HAZ_Addi = HAZ_EXRs;
parameter [7:0] HAZ_Addiu = HAZ_EXRs;
parameter [7:0] HAZ_Addu = HAZ_EXRsEXRt;
parameter [7:0] HAZ_And = HAZ_EXRsEXRt;
parameter [7:0] HAZ_Andi = HAZ_EXRs;
parameter [7:0] HAZ_Beq = HAZ_IDRsIDRt;
parameter [7:0] HAZ_Bgez = HAZ_IDRs;
parameter [7:0] HAZ_Bgezal = HAZ_IDRs;
parameter [7:0] HAZ_Bgtz = HAZ_IDRs;
parameter [7:0] HAZ_Blez = HAZ_IDRs;
parameter [7:0] HAZ_Bltz = HAZ_IDRs;
parameter [7:0] HAZ_Bltzal = HAZ_IDRs;
parameter [7:0] HAZ_Bne = HAZ_IDRsIDRt;
parameter [7:0] HAZ_Break = HAZ_Nothing;
parameter [7:0] HAZ_Clo = HAZ_EXRs;
parameter [7:0] HAZ_Clz = HAZ_EXRs;
parameter [7:0] HAZ_Div = HAZ_EXRsEXRt;
parameter [7:0] HAZ_Divu = HAZ_EXRsEXRt;
parameter [7:0] HAZ_Eret = HAZ_Nothing;
parameter [7:0] HAZ_J = HAZ_Nothing;
parameter [7:0] HAZ_Jal = HAZ_Nothing;
parameter [7:0] HAZ_Jalr = HAZ_IDRs;
parameter [7:0] HAZ_Jr = HAZ_IDRs;
parameter [7:0] HAZ_Lb = HAZ_EXRs;
parameter [7:0] HAZ_Lbu = HAZ_EXRs;
parameter [7:0] HAZ_Lh = HAZ_EXRs;
parameter [7:0] HAZ_Lhu = HAZ_EXRs;
parameter [7:0] HAZ_Ll = HAZ_EXRs;
parameter [7:0] HAZ_Lui = HAZ_Nothing;
parameter [7:0] HAZ_Lw = HAZ_EXRs;
parameter [7:0] HAZ_Lwl = HAZ_EXRsEXRt;
parameter [7:0] HAZ_Lwr = HAZ_EXRsEXRt;
parameter [7:0] HAZ_Madd = HAZ_EXRsEXRt;
parameter [7:0] HAZ_Maddu = HAZ_EXRsEXRt;
parameter [7:0] HAZ_Mfc0 = HAZ_Nothing;
parameter [7:0] HAZ_Mfhi = HAZ_Nothing;
parameter [7:0] HAZ_Mflo = HAZ_Nothing;
parameter [7:0] HAZ_Movn = HAZ_IDRtEXRs;
parameter [7:0] HAZ_Movz = HAZ_IDRtEXRs;
parameter [7:0] HAZ_Msub = HAZ_EXRsEXRt;
parameter [7:0] HAZ_Msubu = HAZ_EXRsEXRt;
parameter [7:0] HAZ_Mtc0 = HAZ_IDRt;
parameter [7:0] HAZ_Mthi = HAZ_EXRs;
parameter [7:0] HAZ_Mtlo = HAZ_EXRs;
parameter [7:0] HAZ_Mul = HAZ_EXRsEXRt;
parameter [7:0] HAZ_Mult = HAZ_EXRsEXRt;
parameter [7:0] HAZ_Multu = HAZ_EXRsEXRt;
parameter [7:0] HAZ_Nor = HAZ_EXRsEXRt;
parameter [7:0] HAZ_Or = HAZ_EXRsEXRt;
parameter [7:0] HAZ_Ori = HAZ_EXRs;
parameter [7:0] HAZ_Pref = HAZ_Nothing; // XXX
parameter [7:0] HAZ_Sb = HAZ_EXRsWRt;
parameter [7:0] HAZ_Sc = HAZ_EXRsWRt;
parameter [7:0] HAZ_Sh = HAZ_EXRsWRt;
parameter [7:0] HAZ_Sll = HAZ_EXRt;
parameter [7:0] HAZ_Sllv = HAZ_EXRsEXRt;
parameter [7:0] HAZ_Slt = HAZ_EXRsEXRt;
parameter [7:0] HAZ_Slti = HAZ_EXRs;
parameter [7:0] HAZ_Sltiu = HAZ_EXRs;
parameter [7:0] HAZ_Sltu = HAZ_EXRsEXRt;
parameter [7:0] HAZ_Sra = HAZ_EXRt;
parameter [7:0] HAZ_Srav = HAZ_EXRsEXRt;
parameter [7:0] HAZ_Srl = HAZ_EXRt;
parameter [7:0] HAZ_Srlv = HAZ_EXRsEXRt;
parameter [7:0] HAZ_Sub = HAZ_EXRsEXRt;
parameter [7:0] HAZ_Subu = HAZ_EXRsEXRt;
parameter [7:0] HAZ_Sw = HAZ_EXRsWRt;
parameter [7:0] HAZ_Swl = HAZ_EXRsWRt;
parameter [7:0] HAZ_Swr = HAZ_EXRsWRt;
parameter [7:0] HAZ_Syscall = HAZ_Nothing;
parameter [7:0] HAZ_Teq = HAZ_EXRsEXRt;
parameter [7:0] HAZ_Teqi = HAZ_EXRs;
parameter [7:0] HAZ_Tge = HAZ_EXRsEXRt;
parameter [7:0] HAZ_Tgei = HAZ_EXRs;
parameter [7:0] HAZ_Tgeiu = HAZ_EXRs;
parameter [7:0] HAZ_Tgeu = HAZ_EXRsEXRt;
parameter [7:0] HAZ_Tlt = HAZ_EXRsEXRt;
parameter [7:0] HAZ_Tlti = HAZ_EXRs;
parameter [7:0] HAZ_Tltiu = HAZ_EXRs;
parameter [7:0] HAZ_Tltu = HAZ_EXRsEXRt;
parameter [7:0] HAZ_Tne = HAZ_EXRsEXRt;
parameter [7:0] HAZ_Tnei = HAZ_EXRs;
parameter [7:0] HAZ_Xor = HAZ_EXRsEXRt;
parameter [7:0] HAZ_Xori = HAZ_EXRs;
 
/MIPS32_Standalone/Mux2.v
15,11 → 15,12
* A 2-input Mux of variable width, defaulting to 32-bit width.
*/
module Mux2 #(parameter WIDTH = 32)(
input sel,
input [(WIDTH-1):0] in0, in1,
output [(WIDTH-1):0] out
);
input sel,
input [(WIDTH-1):0] in0, in1,
output [(WIDTH-1):0] out
);
 
assign out = (sel) ? in1 : in0;
assign out = (sel) ? in1 : in0;
 
endmodule
 
/MIPS32_Standalone/Mux4.v
15,18 → 15,19
* A 4-input Mux of variable width, defaulting to 32-bit width.
*/
module Mux4 #(parameter WIDTH = 32)(
input [1:0] sel,
input [(WIDTH-1):0] in0, in1, in2, in3,
output reg [(WIDTH-1):0] out
);
input [1:0] sel,
input [(WIDTH-1):0] in0, in1, in2, in3,
output reg [(WIDTH-1):0] out
);
 
always @(*) begin
case (sel)
2'b00 : out <= in0;
2'b01 : out <= in1;
2'b10 : out <= in2;
2'b11 : out <= in3;
endcase
end
always @(*) begin
case (sel)
2'b00 : out <= in0;
2'b01 : out <= in1;
2'b10 : out <= in2;
2'b11 : out <= in3;
endcase
end
 
endmodule
 
/MIPS32_Standalone/EXMEM_Stage.v
16,27 → 16,27
* The Pipeline Register to bridge the Execute and Memory stages.
*/
module EXMEM_Stage(
input clock,
input reset,
input clock,
input reset,
input EX_Flush,
input EX_Stall,
input M_Stall,
// Control Signals
input EX_Stall,
input M_Stall,
// Control Signals
input EX_Movn,
input EX_Movz,
input EX_BZero,
input EX_RegWrite, // Future Control to WB
input EX_MemtoReg, // Future Control to WB
input EX_RegWrite, // Future Control to WB
input EX_MemtoReg, // Future Control to WB
input EX_ReverseEndian,
input EX_LLSC,
input EX_MemRead,
input EX_MemWrite,
input EX_MemByte,
input EX_MemHalf,
input EX_MemSignExtend,
input EX_MemRead,
input EX_MemWrite,
input EX_MemByte,
input EX_MemHalf,
input EX_MemSignExtend,
input EX_Left,
input EX_Right,
// Exception Control/Info
// Exception Control/Info
input EX_KernelMode,
input [31:0] EX_RestartPC,
input EX_IsBDS,
43,20 → 43,20
input EX_Trap,
input EX_TrapCond,
input EX_M_CanErr,
// Data Signals
input [31:0] EX_ALU_Result,
input [31:0] EX_ReadData2,
input [4:0] EX_RtRd,
// ------------------
output reg M_RegWrite,
output reg M_MemtoReg,
// Data Signals
input [31:0] EX_ALU_Result,
input [31:0] EX_ReadData2,
input [4:0] EX_RtRd,
// ------------------
output reg M_RegWrite,
output reg M_MemtoReg,
output reg M_ReverseEndian,
output reg M_LLSC,
output reg M_MemRead,
output reg M_MemWrite,
output reg M_MemByte,
output reg M_MemHalf,
output reg M_MemSignExtend,
output reg M_MemRead,
output reg M_MemWrite,
output reg M_MemByte,
output reg M_MemHalf,
output reg M_MemSignExtend,
output reg M_Left,
output reg M_Right,
output reg M_KernelMode,
65,10 → 65,10
output reg M_Trap,
output reg M_TrapCond,
output reg M_M_CanErr,
output reg [31:0] M_ALU_Result,
output reg [31:0] M_ReadData2,
output reg [4:0] M_RtRd
);
output reg [31:0] M_ALU_Result,
output reg [31:0] M_ReadData2,
output reg [4:0] M_RtRd
);
 
/***
The purpose of a pipeline register is to capture data from one pipeline stage
113,3 → 113,4
end
 
endmodule
 
/MIPS32_Standalone/IFID_Stage.v
17,25 → 17,25
* and Instruction Decode stages.
*/
module IFID_Stage(
input clock,
input reset,
input IF_Flush,
input clock,
input reset,
input IF_Flush,
input IF_Stall,
input ID_Stall,
// Control Signals
input [31:0] IF_Instruction,
// Data Signals
input [31:0] IF_PCAdd4,
input ID_Stall,
// Control Signals
input [31:0] IF_Instruction,
// Data Signals
input [31:0] IF_PCAdd4,
input [31:0] IF_PC,
input IF_IsBDS,
// ------------------
output reg [31:0] ID_Instruction,
output reg [31:0] ID_PCAdd4,
// ------------------
output reg [31:0] ID_Instruction,
output reg [31:0] ID_PCAdd4,
output reg [31:0] ID_RestartPC,
output reg ID_IsBDS,
output reg ID_IsFlushed
);
);
/***
The purpose of a pipeline register is to capture data from one pipeline stage
and provide it to the next pipeline stage. This creates at least one clock cycle
72,3 → 72,4
end
 
endmodule
 
/MIPS32_Standalone/TrapDetect.v
25,3 → 25,4
assign EXC_Tr = Trap & (TrapCond ^ ALUZero);
 
endmodule
 
/MIPS32_Standalone/CPZero.v
21,37 → 21,37
* is MIPS-32-compliant.
*/
module CPZero(
input clock,
//-- CP0 Functionality --//
input clock,
//-- CP0 Functionality --//
input Mfc0, // CPU instruction is Mfc0
input Mtc0, // CPU instruction is Mtc0
input Mtc0, // CPU instruction is Mtc0
input IF_Stall,
input ID_Stall, // Commits are not made during stalls
input COP1, // Instruction for Coprocessor 1
input COP2, // Instruction for Coprocessor 2
input COP3, // Instruction for Coprocessor 3
input COP1, // Instruction for Coprocessor 1
input COP2, // Instruction for Coprocessor 2
input COP3, // Instruction for Coprocessor 3
input ERET, // Instruction is ERET (Exception Return)
input [4:0] Rd, // Specifies Cp0 register
input [2:0] Sel, // Specifies Cp0 'select'
input [31:0] Reg_In, // Data from GP register to replace CP0 register
input [4:0] Rd, // Specifies Cp0 register
input [2:0] Sel, // Specifies Cp0 'select'
input [31:0] Reg_In, // Data from GP register to replace CP0 register
output reg [31:0] Reg_Out, // Data from CP0 register for GP register
output KernelMode, // Kernel mode indicator for pipeline transit
output ReverseEndian, // Reverse Endian memory indicator for User Mode
//-- Hw Interrupts --//
input [4:0] Int, // Five hardware interrupts external to the processor
//-- Exceptions --//
input reset, // Cold Reset (EXC_Reset)
//-- Hw Interrupts --//
input [4:0] Int, // Five hardware interrupts external to the processor
//-- Exceptions --//
input reset, // Cold Reset (EXC_Reset)
// input EXC_SReset, // Soft Reset (not implemented)
input EXC_NMI, // Non-Maskable Interrupt
input EXC_NMI, // Non-Maskable Interrupt
input EXC_AdIF, // Address Error Exception from i-fetch (mapped to AdEL)
input EXC_AdEL, // Address Error Exception from data memory load
input EXC_AdES, // Address Error Exception from data memory store
input EXC_Ov, // Integer Overflow Exception
input EXC_Tr, // Trap Exception
input EXC_Sys, // System Call Exception
input EXC_Bp, // Breakpoint Exception
input EXC_RI, // Reserved Instruction Exception
//-- Exception Data --//
input EXC_AdEL, // Address Error Exception from data memory load
input EXC_AdES, // Address Error Exception from data memory store
input EXC_Ov, // Integer Overflow Exception
input EXC_Tr, // Trap Exception
input EXC_Sys, // System Call Exception
input EXC_Bp, // Breakpoint Exception
input EXC_RI, // Reserved Instruction Exception
//-- Exception Data --//
input [31:0] ID_RestartPC, // PC for exception, whether PC of instruction or of branch (PC-4) if BDS
input [31:0] EX_RestartPC, // Same as 'ID_RestartPC' but in EX stage
input [31:0] M_RestartPC, // Same as 'ID_RestartPC' but in MEM stage
60,7 → 60,7
input ID_IsBD, // Indicator of ID exception being a branch delay slot instruction
input EX_IsBD, // Indicator of EX exception being a branch delay slot instruction
input M_IsBD, // Indicator of M exception being a branch delay slot instruction
input [31:0] BadAddr_M, // Bad 'Virtual' Address for exceptions AdEL, AdES in MEM stage
input [31:0] BadAddr_M, // Bad 'Virtual' Address for exceptions AdEL, AdES in MEM stage
input [31:0] BadAddr_IF, // Bad 'Virtual' Address for AdIF (i.e. AdEL) in IF stage
input ID_CanErr, // Cumulative signal, i.e. (ID_ID_CanErr | ID_EX_CanErr | ID_M_CanErr)
input EX_CanErr, // Cumulative signal, i.e. (EX_EX_CanErr | EX_M_CanErr)
77,9 → 77,9
output Exc_PC_Sel, // Mux selector for exception PC override
output reg [31:0] Exc_PC_Out, // Address for PC at the beginning of an exception
output [7:0] IP // Pending Interrupts from Cause register (for diagnostic purposes)
);
);
 
`include "MIPS_Parameters.v"
`include "MIPS_Parameters.v"
 
 
/***
118,18 → 118,18
until the interrupts has been processed.
 
Exception Name Short Name Pipeline Stage
Address Error Ex (AdEL, AdES) MEM, IF
Integer Overflow Ex (Ov) EX
Trap Ex (Tr) MEM
Syscall (Sys) ID
Breakpoint (Bp) ID
Reserved Instruction (RI) ID
Coprocessor Unusable (CpU) ID
Interrupt (Int) ID
Reset, SReset, NMI ID
Address Error Ex (AdEL, AdES) MEM, IF
Integer Overflow Ex (Ov) EX
Trap Ex (Tr) MEM
Syscall (Sys) ID
Breakpoint (Bp) ID
Reserved Instruction (RI) ID
Coprocessor Unusable (CpU) ID
Interrupt (Int) ID
Reset, SReset, NMI ID
***/
// Exceptions Generated Internally
wire EXC_CpU;
 
178,9 → 178,9
reg Status_RE; // Reverse Endian Memory for User Mode
wire Status_MX = 0;
wire Status_PX = 0;
reg Status_BEV; // Exception vector locations (0->Norm, 1->Bootstrap)
reg Status_BEV; // Exception vector locations (0->Norm, 1->Bootstrap)
wire Status_TS = 0;
wire Status_SR = 0; // Soft reset not implemented
wire Status_SR = 0; // Soft reset not implemented
reg Status_NMI; // Non-Maskable Interrupt
wire Status_RES = 0;
wire [1:0] Status_Custom = 2'b00;
188,9 → 188,9
wire Status_KX = 0;
wire Status_SX = 0;
wire Status_UX = 0;
reg Status_UM; // Base operating mode (0->Kernel, 1->User)
reg Status_UM; // Base operating mode (0->Kernel, 1->User)
wire Status_R0 = 0;
reg Status_ERL; // Error Level (0->Normal, 1->Error (reset, NMI))
reg Status_ERL; // Error Level (0->Normal, 1->Error (reset, NMI))
reg Status_EXL; // Exception level (0->Normal, 1->Exception)
reg Status_IE; // Interrupt Enable
wire [31:0] Status = {Status_CU_321, Status_CU_0, Status_RP, Status_FR, Status_RE, Status_MX,
199,11 → 199,11
Status_UM, Status_R0, Status_ERL, Status_EXL, Status_IE};
 
// Cause Register (Register 13, Select 0)
reg Cause_BD; // Exception occured in Branch Delay
reg [1:0] Cause_CE; // CP number for CP Unusable exception
reg Cause_IV; // Indicator of general IV (0->0x180) or special IV (1->0x200)
reg Cause_BD; // Exception occured in Branch Delay
reg [1:0] Cause_CE; // CP number for CP Unusable exception
reg Cause_IV; // Indicator of general IV (0->0x180) or special IV (1->0x200)
wire Cause_WP = 0;
reg [7:0] Cause_IP; // Pending HW Interrupt indicator.
reg [7:0] Cause_IP; // Pending HW Interrupt indicator.
wire Cause_ExcCode4 = 0; // Can be made into a register when this bit is needed.
reg [3:0] Cause_ExcCode30; // Description of Exception (only lower 4 bits currently used; see above)
wire [31:0] Cause = {Cause_BD, 1'b0, Cause_CE, 4'b0000, Cause_IV, Cause_WP,
222,7 → 222,7
// Configuration Register (Register 16, Select 0)
wire Config_M = 1;
wire [14:0] Config_Impl = 15'b000_0000_0000_0000;
wire Config_BE = Big_Endian; // From parameters file
wire Config_BE = Big_Endian; // From parameters file
wire [1:0] Config_AT = 2'b00;
wire [2:0] Config_AR = 3'b000;
wire [2:0] Config_MT = 3'b000;
241,8 → 241,8
wire [2:0] Config1_DA = 3'b000;
wire Config1_C2 = 0;
wire Config1_MD = 0;
wire Config1_PC = 0; // XXX Performance Counters
wire Config1_WR = 0; // XXX Watch Registers
wire Config1_PC = 0; // XXX Performance Counters
wire Config1_WR = 0; // XXX Watch Registers
wire Config1_CA = 0;
wire Config1_EP = 0;
wire Config1_FP = 0;
524,6 → 524,6
else if (EXC_Int) Cause_ExcCode_bits <= 4'h0; // 00000 // OK that NMI writes this.
else Cause_ExcCode_bits <= 4'bxxxx;
end
endmodule
 
endmodule
/MIPS32_Standalone/Hazard_Detection.v
22,71 → 22,71
* This module is heavily commented. Read below for more information.
*/
module Hazard_Detection(
input [7:0] DP_Hazards,
input [4:0] ID_Rs,
input [4:0] ID_Rt,
input [4:0] EX_Rs,
input [4:0] EX_Rt,
input [4:0] EX_RtRd,
input [4:0] MEM_RtRd,
input [4:0] WB_RtRd,
input [7:0] DP_Hazards,
input [4:0] ID_Rs,
input [4:0] ID_Rt,
input [4:0] EX_Rs,
input [4:0] EX_Rt,
input [4:0] EX_RtRd,
input [4:0] MEM_RtRd,
input [4:0] WB_RtRd,
input ID_Link,
input EX_Link,
input EX_RegWrite,
input MEM_RegWrite,
input WB_RegWrite,
input MEM_MemRead,
input EX_Link,
input EX_RegWrite,
input MEM_RegWrite,
input WB_RegWrite,
input MEM_MemRead,
input MEM_MemWrite, // Needed for Store Conditional which writes to a register
input InstMem_Read,
input InstMem_Ready,
input Mfc0, // Using fwd mux; not part of haz/fwd.
input InstMem_Ready,
input Mfc0, // Using fwd mux; not part of haz/fwd.
input IF_Exception_Stall,
input ID_Exception_Stall,
input EX_Exception_Stall,
input M_Stall_Controller, // Determined by data memory controller
output IF_Stall,
output ID_Stall,
output EX_Stall,
output IF_Stall,
output ID_Stall,
output EX_Stall,
output M_Stall,
output WB_Stall,
output [1:0] ID_RsFwdSel,
output [1:0] ID_RtFwdSel,
output [1:0] EX_RsFwdSel,
output [1:0] EX_RtFwdSel,
output M_WriteDataFwdSel
);
/* Hazard and Forward Detection
*
* Most instructions read from one or more registers. Normally this occurs in
* the ID stage. However, frequently the register file in the ID stage is stale
* when one or more forward stages in the pipeline (EX, MEM, or WB) contains
* an instruction which will eventually update it but has not yet done so.
*
* A hazard condition is created when a forward pipeline stage is set to write
* the same register that a current pipeline stage (e.g. in ID) needs to read.
* The solution is to stall the current stage (and effectively all stages behind
* it) or bypass (forward) the data from forward stages. Fortunately forwarding
* works for most combinations of instructions.
*
* Hazard and Forward conditions are handled based on two simple rules:
* "Wants" and "Needs." If an instruction "wants" data in a certain pipeline
* stage, and that data is available further along in the pipeline, it will
* be forwarded. If it "needs" data and the data is not yet available for forwarding,
* the pipeline stage stalls. If it does not want or need data in a certain
* stage, forwarding is disabled and a stall will not occur. This is important
* for instructions which insert custom data, such as jal or movz.
*
* Currently, "Want" and "Need" conditions are defined for both Rs data and Rt
* data (the two read registers in MIPS), and these conditions exist in the
* ID and EX pipeline stages. This is a total of eight condition bits.
*
* A unique exception exists with Store instructions, which don't need the
* "Rt" data until the MEM stage. Because data doesn't change in WB, and WB
* is the only stage following MEM, forwarding is *always* possible from
* WB to Mem. This unit handles this situation, and a condition bit is not
* needed.
*
output [1:0] ID_RsFwdSel,
output [1:0] ID_RtFwdSel,
output [1:0] EX_RsFwdSel,
output [1:0] EX_RtFwdSel,
output M_WriteDataFwdSel
);
/* Hazard and Forward Detection
*
* Most instructions read from one or more registers. Normally this occurs in
* the ID stage. However, frequently the register file in the ID stage is stale
* when one or more forward stages in the pipeline (EX, MEM, or WB) contains
* an instruction which will eventually update it but has not yet done so.
*
* A hazard condition is created when a forward pipeline stage is set to write
* the same register that a current pipeline stage (e.g. in ID) needs to read.
* The solution is to stall the current stage (and effectively all stages behind
* it) or bypass (forward) the data from forward stages. Fortunately forwarding
* works for most combinations of instructions.
*
* Hazard and Forward conditions are handled based on two simple rules:
* "Wants" and "Needs." If an instruction "wants" data in a certain pipeline
* stage, and that data is available further along in the pipeline, it will
* be forwarded. If it "needs" data and the data is not yet available for forwarding,
* the pipeline stage stalls. If it does not want or need data in a certain
* stage, forwarding is disabled and a stall will not occur. This is important
* for instructions which insert custom data, such as jal or movz.
*
* Currently, "Want" and "Need" conditions are defined for both Rs data and Rt
* data (the two read registers in MIPS), and these conditions exist in the
* ID and EX pipeline stages. This is a total of eight condition bits.
*
* A unique exception exists with Store instructions, which don't need the
* "Rt" data until the MEM stage. Because data doesn't change in WB, and WB
* is the only stage following MEM, forwarding is *always* possible from
* WB to Mem. This unit handles this situation, and a condition bit is not
* needed.
*
* When data is needed from the MEM stage by a previous stage (ID or EX), the
* decision to forward or stall is based on whether MEM is accessing memory
* (stall) or not (forward). Normally store instructions don't write to registers
94,69 → 94,69
* is sufficient to determine. Because of the Store Conditional instruction,
* however, 'MEM_MemWrite' must also be considered because it writes to a register.
*
*/
wire WantRsByID, NeedRsByID, WantRtByID, NeedRtByID, WantRsByEX, NeedRsByEX, WantRtByEX, NeedRtByEX;
assign WantRsByID = DP_Hazards[7];
assign NeedRsByID = DP_Hazards[6];
assign WantRtByID = DP_Hazards[5];
assign NeedRtByID = DP_Hazards[4];
assign WantRsByEX = DP_Hazards[3];
assign NeedRsByEX = DP_Hazards[2];
assign WantRtByEX = DP_Hazards[1];
assign NeedRtByEX = DP_Hazards[0];
*/
wire WantRsByID, NeedRsByID, WantRtByID, NeedRtByID, WantRsByEX, NeedRsByEX, WantRtByEX, NeedRtByEX;
assign WantRsByID = DP_Hazards[7];
assign NeedRsByID = DP_Hazards[6];
assign WantRtByID = DP_Hazards[5];
assign NeedRtByID = DP_Hazards[4];
assign WantRsByEX = DP_Hazards[3];
assign NeedRsByEX = DP_Hazards[2];
assign WantRtByEX = DP_Hazards[1];
assign NeedRtByEX = DP_Hazards[0];
 
// Trick allowed by RegDst = 0 which gives Rt. MEM_Rt is only used on
// Data Memory write operations (stores), and RegWrite is always 0 in this case.
wire [4:0] MEM_Rt = MEM_RtRd;
// Forwarding should not happen when the src/dst register is $zero
wire EX_RtRd_NZ = (EX_RtRd != 5'b00000);
wire MEM_RtRd_NZ = (MEM_RtRd != 5'b00000);
wire WB_RtRd_NZ = (WB_RtRd != 5'b00000);
// ID Dependencies
wire Rs_IDEX_Match = (ID_Rs == EX_RtRd) & EX_RtRd_NZ & (WantRsByID | NeedRsByID) & EX_RegWrite;
wire Rt_IDEX_Match = (ID_Rt == EX_RtRd) & EX_RtRd_NZ & (WantRtByID | NeedRtByID) & EX_RegWrite;
wire Rs_IDMEM_Match = (ID_Rs == MEM_RtRd) & MEM_RtRd_NZ & (WantRsByID | NeedRsByID) & MEM_RegWrite;
wire Rt_IDMEM_Match = (ID_Rt == MEM_RtRd) & MEM_RtRd_NZ & (WantRtByID | NeedRtByID) & MEM_RegWrite;
wire Rs_IDWB_Match = (ID_Rs == WB_RtRd) & WB_RtRd_NZ & (WantRsByID | NeedRsByID) & WB_RegWrite;
wire Rt_IDWB_Match = (ID_Rt == WB_RtRd) & WB_RtRd_NZ & (WantRtByID | NeedRtByID) & WB_RegWrite;
// EX Dependencies
wire Rs_EXMEM_Match = (EX_Rs == MEM_RtRd) & MEM_RtRd_NZ & (WantRsByEX | NeedRsByEX) & MEM_RegWrite;
wire Rt_EXMEM_Match = (EX_Rt == MEM_RtRd) & MEM_RtRd_NZ & (WantRtByEX | NeedRtByEX) & MEM_RegWrite;
wire Rs_EXWB_Match = (EX_Rs == WB_RtRd) & WB_RtRd_NZ & (WantRsByEX | NeedRsByEX) & WB_RegWrite;
wire Rt_EXWB_Match = (EX_Rt == WB_RtRd) & WB_RtRd_NZ & (WantRtByEX | NeedRtByEX) & WB_RegWrite;
// MEM Dependencies
wire Rt_MEMWB_Match = (MEM_Rt == WB_RtRd) & WB_RtRd_NZ & WB_RegWrite;
// Trick allowed by RegDst = 0 which gives Rt. MEM_Rt is only used on
// Data Memory write operations (stores), and RegWrite is always 0 in this case.
wire [4:0] MEM_Rt = MEM_RtRd;
// Forwarding should not happen when the src/dst register is $zero
wire EX_RtRd_NZ = (EX_RtRd != 5'b00000);
wire MEM_RtRd_NZ = (MEM_RtRd != 5'b00000);
wire WB_RtRd_NZ = (WB_RtRd != 5'b00000);
// ID Dependencies
wire Rs_IDEX_Match = (ID_Rs == EX_RtRd) & EX_RtRd_NZ & (WantRsByID | NeedRsByID) & EX_RegWrite;
wire Rt_IDEX_Match = (ID_Rt == EX_RtRd) & EX_RtRd_NZ & (WantRtByID | NeedRtByID) & EX_RegWrite;
wire Rs_IDMEM_Match = (ID_Rs == MEM_RtRd) & MEM_RtRd_NZ & (WantRsByID | NeedRsByID) & MEM_RegWrite;
wire Rt_IDMEM_Match = (ID_Rt == MEM_RtRd) & MEM_RtRd_NZ & (WantRtByID | NeedRtByID) & MEM_RegWrite;
wire Rs_IDWB_Match = (ID_Rs == WB_RtRd) & WB_RtRd_NZ & (WantRsByID | NeedRsByID) & WB_RegWrite;
wire Rt_IDWB_Match = (ID_Rt == WB_RtRd) & WB_RtRd_NZ & (WantRtByID | NeedRtByID) & WB_RegWrite;
// EX Dependencies
wire Rs_EXMEM_Match = (EX_Rs == MEM_RtRd) & MEM_RtRd_NZ & (WantRsByEX | NeedRsByEX) & MEM_RegWrite;
wire Rt_EXMEM_Match = (EX_Rt == MEM_RtRd) & MEM_RtRd_NZ & (WantRtByEX | NeedRtByEX) & MEM_RegWrite;
wire Rs_EXWB_Match = (EX_Rs == WB_RtRd) & WB_RtRd_NZ & (WantRsByEX | NeedRsByEX) & WB_RegWrite;
wire Rt_EXWB_Match = (EX_Rt == WB_RtRd) & WB_RtRd_NZ & (WantRtByEX | NeedRtByEX) & WB_RegWrite;
// MEM Dependencies
wire Rt_MEMWB_Match = (MEM_Rt == WB_RtRd) & WB_RtRd_NZ & WB_RegWrite;
 
 
// ID needs data from EX : Stall
wire ID_Stall_1 = (Rs_IDEX_Match & NeedRsByID);
wire ID_Stall_2 = (Rt_IDEX_Match & NeedRtByID);
// ID needs data from MEM : Stall if mem access
wire ID_Stall_3 = (Rs_IDMEM_Match & (MEM_MemRead | MEM_MemWrite) & NeedRsByID);
wire ID_Stall_4 = (Rt_IDMEM_Match & (MEM_MemRead | MEM_MemWrite) & NeedRtByID);
// ID wants data from MEM : Forward if not mem access
wire ID_Fwd_1 = (Rs_IDMEM_Match & ~(MEM_MemRead | MEM_MemWrite));
wire ID_Fwd_2 = (Rt_IDMEM_Match & ~(MEM_MemRead | MEM_MemWrite));
// ID wants/needs data from WB : Forward
wire ID_Fwd_3 = (Rs_IDWB_Match);
wire ID_Fwd_4 = (Rt_IDWB_Match);
// EX needs data from MEM : Stall if mem access
wire EX_Stall_1 = (Rs_EXMEM_Match & (MEM_MemRead | MEM_MemWrite) & NeedRsByEX);
wire EX_Stall_2 = (Rt_EXMEM_Match & (MEM_MemRead | MEM_MemWrite) & NeedRtByEX);
// EX wants data from MEM : Forward if not mem access
wire EX_Fwd_1 = (Rs_EXMEM_Match & ~(MEM_MemRead | MEM_MemWrite));
wire EX_Fwd_2 = (Rt_EXMEM_Match & ~(MEM_MemRead | MEM_MemWrite));
// EX wants/needs data from WB : Forward
wire EX_Fwd_3 = (Rs_EXWB_Match);
wire EX_Fwd_4 = (Rt_EXWB_Match);
// MEM needs data from WB : Forward
wire MEM_Fwd_1 = (Rt_MEMWB_Match);
// ID needs data from EX : Stall
wire ID_Stall_1 = (Rs_IDEX_Match & NeedRsByID);
wire ID_Stall_2 = (Rt_IDEX_Match & NeedRtByID);
// ID needs data from MEM : Stall if mem access
wire ID_Stall_3 = (Rs_IDMEM_Match & (MEM_MemRead | MEM_MemWrite) & NeedRsByID);
wire ID_Stall_4 = (Rt_IDMEM_Match & (MEM_MemRead | MEM_MemWrite) & NeedRtByID);
// ID wants data from MEM : Forward if not mem access
wire ID_Fwd_1 = (Rs_IDMEM_Match & ~(MEM_MemRead | MEM_MemWrite));
wire ID_Fwd_2 = (Rt_IDMEM_Match & ~(MEM_MemRead | MEM_MemWrite));
// ID wants/needs data from WB : Forward
wire ID_Fwd_3 = (Rs_IDWB_Match);
wire ID_Fwd_4 = (Rt_IDWB_Match);
// EX needs data from MEM : Stall if mem access
wire EX_Stall_1 = (Rs_EXMEM_Match & (MEM_MemRead | MEM_MemWrite) & NeedRsByEX);
wire EX_Stall_2 = (Rt_EXMEM_Match & (MEM_MemRead | MEM_MemWrite) & NeedRtByEX);
// EX wants data from MEM : Forward if not mem access
wire EX_Fwd_1 = (Rs_EXMEM_Match & ~(MEM_MemRead | MEM_MemWrite));
wire EX_Fwd_2 = (Rt_EXMEM_Match & ~(MEM_MemRead | MEM_MemWrite));
// EX wants/needs data from WB : Forward
wire EX_Fwd_3 = (Rs_EXWB_Match);
wire EX_Fwd_4 = (Rt_EXWB_Match);
// MEM needs data from WB : Forward
wire MEM_Fwd_1 = (Rt_MEMWB_Match);
 
// Stalls and Control Flow Final Assignments
// Stalls and Control Flow Final Assignments
assign WB_Stall = M_Stall;
assign M_Stall = IF_Stall | M_Stall_Controller;
assign EX_Stall = (EX_Stall_1 | EX_Stall_2 | EX_Exception_Stall) | M_Stall;
163,11 → 163,12
assign ID_Stall = (ID_Stall_1 | ID_Stall_2 | ID_Stall_3 | ID_Stall_4 | ID_Exception_Stall) | EX_Stall;
assign IF_Stall = InstMem_Read | InstMem_Ready | IF_Exception_Stall;
// Forwarding Control Final Assignments
assign ID_RsFwdSel = (ID_Link) ? 2'b11 : ((ID_Fwd_1) ? 2'b01 : ((ID_Fwd_3) ? 2'b10 : 2'b00));
assign ID_RtFwdSel = (Mfc0) ? 2'b11 : ((ID_Fwd_2) ? 2'b01 : ((ID_Fwd_4) ? 2'b10 : 2'b00));
// Forwarding Control Final Assignments
assign ID_RsFwdSel = (ID_Link) ? 2'b11 : ((ID_Fwd_1) ? 2'b01 : ((ID_Fwd_3) ? 2'b10 : 2'b00));
assign ID_RtFwdSel = (Mfc0) ? 2'b11 : ((ID_Fwd_2) ? 2'b01 : ((ID_Fwd_4) ? 2'b10 : 2'b00));
assign EX_RsFwdSel = (EX_Fwd_1) ? 2'b01 : ((EX_Fwd_3) ? 2'b10 : 2'b00);
assign EX_RtFwdSel = (EX_Link) ? 2'b11 : ((EX_Fwd_2) ? 2'b01 : ((EX_Fwd_4) ? 2'b10 : 2'b00));
assign M_WriteDataFwdSel = MEM_Fwd_1;
assign EX_RtFwdSel = (EX_Link) ? 2'b11 : ((EX_Fwd_2) ? 2'b01 : ((EX_Fwd_4) ? 2'b10 : 2'b00));
assign M_WriteDataFwdSel = MEM_Fwd_1;
endmodule
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.