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/Piezo/Piezo.v
40,3 → 40,4
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/Switch_Filter.v
73,3 → 73,4
*/ |
|
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-min.v
126,3 → 126,4
); |
|
endmodule |
|
/XUPV5-LX110T_SoC/MIPS32-Pipelined-Hw/src/UART/uart_bootloader_v2.v
218,3 → 218,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/UART/uart_tx.v
76,3 → 76,4
end |
|
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_Controller.v
95,3 → 95,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/MemControl.v
230,3 → 230,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 |
|