Initial commit

This commit is contained in:
muellerlu
2026-05-29 10:19:13 +02:00
commit fedfd92270
726 changed files with 542654 additions and 0 deletions
@@ -0,0 +1,290 @@
`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,
output ALU_Stall // Stalls due to long ALU operations
);
`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.
***/
/***
Divider Logic:
The hardware divider requires 32 cycles to complete. Because it writes its
results to HILO and not to the pipeline, the pipeline can proceed without
stalling. When a later instruction tries to access HILO, the pipeline will
stall if the divide operation has not yet completed.
***/
// Internal state registers
reg [63:0] HILO;
reg HILO_Access; // Behavioral; not DFFs
reg [5:0] CLO_Result, CLZ_Result; // Behavioral; not DFFs
reg div_fsm;
// Internal signals
wire [31:0] HI, LO;
wire HILO_Commit;
wire signed [31:0] As, Bs;
wire AddSub_Add;
wire signed [31:0] AddSub_Result;
wire signed [63:0] Mult_Result;
wire [63:0] Multu_Result;
wire [31:0] Quotient;
wire [31:0] Remainder;
wire Div_Stall;
wire Div_Start, Divu_Start;
wire DivOp;
wire Div_Commit;
// Assignments
assign HI = HILO[63:32];
assign LO = HILO[31:0];
assign HILO_Commit = ~(EX_Stall | EX_Flush);
assign As = A;
assign Bs = B;
assign AddSub_Add = ((Operation == AluOp_Add) | (Operation == AluOp_Addu));
assign AddSub_Result = (AddSub_Add) ? (A + B) : (A - B);
assign Mult_Result = As * Bs;
assign Multu_Result = A * B;
assign BZero = (B == 32'h00000000);
assign DivOp = (Operation == AluOp_Div) || (Operation == AluOp_Divu);
assign Div_Commit = (div_fsm == 1'b1) && (Div_Stall == 1'b0);
assign Div_Start = (div_fsm == 1'b0) && (Operation == AluOp_Div) && (HILO_Commit == 1'b1);
assign Divu_Start = (div_fsm == 1'b0) && (Operation == AluOp_Divu) && (HILO_Commit == 1'b1);
assign ALU_Stall = (div_fsm == 1'b1) && (HILO_Access == 1'b1);
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_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 (Div_Commit) begin
HILO <= {Remainder, Quotient};
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 accesses to HILO. RAW and WAW hazards are possible while a
// divide operation is computing, so reads and writes to HILO must stall
// while the divider is busy.
// (This logic could be put into an earlier pipeline stage or into the
// datapath bits to improve timing.)
always @(Operation) begin
case (Operation)
AluOp_Div : HILO_Access <= 1;
AluOp_Divu : HILO_Access <= 1;
AluOp_Mfhi : HILO_Access <= 1;
AluOp_Mflo : HILO_Access <= 1;
AluOp_Mult : HILO_Access <= 1;
AluOp_Multu : HILO_Access <= 1;
AluOp_Madd : HILO_Access <= 1;
AluOp_Maddu : HILO_Access <= 1;
AluOp_Msub : HILO_Access <= 1;
AluOp_Msubu : HILO_Access <= 1;
AluOp_Mthi : HILO_Access <= 1;
AluOp_Mtlo : HILO_Access <= 1;
default : HILO_Access <= 0;
endcase
end
// Divider FSM: The divide unit is either available or busy.
always @(posedge clock) begin
if (reset) begin
div_fsm <= 2'd0;
end
else begin
case (div_fsm)
1'd0 : div_fsm <= (DivOp & HILO_Commit) ? 1'd1 : 1'd0;
1'd1 : div_fsm <= (~Div_Stall) ? 1'd0 : 1'd1;
endcase
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
// Multicycle divide unit
Divide Divider (
.clock (clock),
.reset (reset),
.OP_div (Div_Start),
.OP_divu (Divu_Start),
.Dividend (A),
.Divisor (B),
.Quotient (Quotient),
.Remainder (Remainder),
.Stall (Div_Stall)
);
endmodule
@@ -0,0 +1,26 @@
`timescale 1ns / 1ps
/*
* File : Add.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.
*
* Standards/Formatting:
* Verilog 2001, 4 soft tab, wide column.
*
* Description:
* 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);
endmodule
@@ -0,0 +1,529 @@
`timescale 1ns / 1ps
/*
* File : CPZero.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-Sep-2011 GEA Initial design.
* 2.0 14-May-2012 GEA Complete rework.
*
* Standards/Formatting:
* Verilog 2001, 4 soft tab, wide column.
*
* Description:
* The MIPS-32 Coprocessor 0 (CP0). This is the processor management unit that allows
* interrupts, traps, system calls, and other exceptions. It distinguishes
* user and kernel modes, provides status information, and can override program
* flow. This processor is designed for "bare metal" memory access and thus does
* not have virtual memory hardware as a part of it. However, the subset of CP0
* is MIPS-32-compliant.
*/
module CPZero(
input clock,
//-- CP0 Functionality --//
input Mfc0, // CPU instruction is Mfc0
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 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
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)
// input EXC_SReset, // Soft Reset (not implemented)
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 [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
input ID_IsFlushed,
input IF_IsBD, // Indicator of IF exception being a branch delay slot instruction
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_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)
input M_CanErr, // Memory stage can error (i.e. cause exception)
//-- Exception Control Flow --/
output IF_Exception_Stall,
output ID_Exception_Stall,
output EX_Exception_Stall,
output M_Exception_Stall,
output IF_Exception_Flush,
output ID_Exception_Flush,
output EX_Exception_Flush,
output M_Exception_Flush,
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"
/***
Exception Control Flow Notes
- Exceptions can occur in every pipeline stage. This implies that more than one exception
can be raised in a single cycle. When this occurs, only the forward-most exception
(i.e. MEM over EX) is handled. This and the following note guarantee program order.
- An exception in any pipeline stage must stall that stage until all following stages are
exception-free. This is because it only makes sense for exceptions to occur in program order.
- A pipeline stage which causes an exception must flush, i.e. prevent any commits it would
have normally made and convert itself to a NOP for the next pipeline stage. Furthermore,
it must flush all previous pipeline stages as well in order to retain program order.
- Instructions reading CP0 (mtc0) read in ID without further action. Writes to CP0 (mtc0,
eret) also write in ID, but only after forward pipeline stages have been cleared
of possible exceptions. This prevents many insidious bugs, such as switching to User Mode
in ID when a legitimate memory access in kernel mode is processing in MEM, or conversely
a switch to Kernel Mode in ID when an instruction in User Mode is attempting a kernel region
memory access (when a kernel mode signal does not propagate through the pipeline).
- Commits occur in ID (CP0), EX (HILO), MEM, and WB (registers).
- Hardware interrupts are detected and inserted in the ID stage, but only when there are no
other possible exceptions in the pipeline. Because they appear 'asynchronous' to the
processor, the remaining instructions in forward stages (EX, MEM, WB) can either be
flushed or completed. It is simplest to have them complete to avoid restarts, but the
interrupt latency is higher if e.g. the MEM stage stalls on a memory access (this would
be unavoidable on single-cycle processors). This implementation allows all forward instructions
to complete, for a greater instruction throughput but higher interrupt latency.
- Software interrupts should appear synchronous in the program order, meaning that all
instructions previous to them should complete and no instructions after them should start
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
***/
// Exceptions Generated Internally
wire EXC_CpU;
// Hardware Interrupt #5, caused by Timer/Perf counter
wire Int5;
// Top-level Authoritative Interrupt Signal
wire EXC_Int;
// General Exception detection (all but Interrupts, Reset, Soft Reset, and NMI)
wire EXC_General = EXC_AdIF | EXC_AdEL | EXC_AdES | EXC_Ov | EXC_Tr | EXC_Sys | EXC_Bp | EXC_RI | EXC_CpU;
// Misc
wire CP0_WriteCond;
reg [3:0] Cause_ExcCode_bits;
reg reset_r;
always @(posedge clock) begin
reset_r <= reset;
end
/***
MIPS-32 COPROCESSOR 0 (Cp0) REGISTERS
These are defined in "MIPS32 Architecture for Programmers Volume III:
The MIPS32 Privileged Resource Architecture" from MIPS Technologies, Inc.
Optional registers are omitted. Changes to the processor (such as adding
an MMU/TLB, etc. must be reflected in these registers.
*/
// BadVAddr Register (Register 8, Select 0)
reg [31:0] BadVAddr;
// Count Register (Register 9, Select 0)
reg [31:0] Count;
// Compare Register (Register 11, Select 0)
reg [31:0] Compare;
// Status Register (Register 12, Select 0)
wire [2:0] Status_CU_321 = 3'b000;
reg Status_CU_0; // Access Control to CPs, [2]->Cp3, ... [0]->Cp0
wire Status_RP = 0;
wire Status_FR = 0;
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)
wire Status_TS = 0;
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;
reg [7:0] Status_IM; // Interrupt mask
wire Status_KX = 0;
wire Status_SX = 0;
wire Status_UX = 0;
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_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,
Status_PX, Status_BEV, Status_TS, Status_SR, Status_NMI, Status_RES,
Status_Custom, Status_IM, Status_KX, Status_SX, Status_UX,
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)
wire Cause_WP = 0;
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,
6'b000000, Cause_IP, 1'b0, Cause_ExcCode4, Cause_ExcCode30, 2'b00};
// Exception Program Counter (Register 14, Select 0)
reg [31:0] EPC;
// Processor Identification (Register 15, Select 0)
wire [7:0] ID_Options = 8'b0000_0000;
wire [7:0] ID_CID = 8'b0000_0000;
wire [7:0] ID_PID = 8'b0000_0000;
wire [7:0] ID_Rev = 8'b0000_0001;
wire [31:0] PRId = {ID_Options, ID_CID, ID_PID, ID_Rev};
// 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 [1:0] Config_AT = 2'b00;
wire [2:0] Config_AR = 3'b000;
wire [2:0] Config_MT = 3'b000;
wire [2:0] Config_K0 = 3'b000;
wire [31:0] Config = {Config_M, Config_Impl, Config_BE, Config_AT, Config_AR, Config_MT,
4'b0000, Config_K0};
// Configuration Register 1 (Register 16, Select 1)
wire Config1_M = 0;
wire [5:0] Config1_MMU = 6'b000000;
wire [2:0] Config1_IS = 3'b000;
wire [2:0] Config1_IL = 3'b000;
wire [2:0] Config1_IA = 3'b000;
wire [2:0] Config1_DS = 3'b000;
wire [2:0] Config1_DL = 3'b000;
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_CA = 0;
wire Config1_EP = 0;
wire Config1_FP = 0;
wire [31:0] Config1 = {Config1_M, Config1_MMU, Config1_IS, Config1_IL, Config1_IA,
Config1_DS, Config1_DL, Config1_DA, Config1_C2,
Config1_MD, Config1_PC, Config1_WR, Config1_CA,
Config1_EP, Config1_FP};
// Performance Counter Register (Register 25) XXX TODO
// ErrorEPC Register (Register 30, Select 0)
reg [31:0] ErrorEPC;
// Exception Detection and Processing
wire M_Exception_Detect, EX_Exception_Detect, ID_Exception_Detect, IF_Exception_Detect;
wire M_Exception_Mask, EX_Exception_Mask, ID_Exception_Mask, IF_Exception_Mask;
wire M_Exception_Ready, EX_Exception_Ready, ID_Exception_Ready, IF_Exception_Ready;
assign IP = Cause_IP;
/*** Coprocessor Unusable Exception ***/
assign EXC_CpU = COP1 | COP2 | COP3 | ((Mtc0 | Mfc0 | ERET) & ~(Status_CU_0 | KernelMode));
/*** Kernel Mode Signal ***/
assign KernelMode = ~Status_UM | Status_EXL | Status_ERL;
/*** Reverse Endian for User Mode ***/
assign ReverseEndian = Status_RE;
/*** Interrupts ***/
assign Int5 = (Count == Compare);
//assign EXC_Int = ((Cause_IP[7:0] & Status_IM[7:0]) != 8'h00) & Status_IE & ~Status_EXL & ~Status_ERL & ~ID_IsFlushed;
wire Enabled_Interrupt = EXC_NMI | (Status_IE & ((Cause_IP[7:0] & Status_IM[7:0]) != 8'h00));
assign EXC_Int = Enabled_Interrupt & ~Status_EXL & ~Status_ERL & ~ID_IsFlushed;
assign CP0_WriteCond = (Status_CU_0 | KernelMode) & Mtc0 & ~ID_Stall;
/***
Exception Hazard Flow Control Explanation:
- An exception at any time in any stage causes its own and any previous stages to
flush (clear own commits, NOPS to fwd stages).
- An exception in a stage can also stall that stage (and inherently all previous stages) if and only if:
1. A forward stage is capable of causing an exception AND
2. A forward stage is not currently causing an exception.
- An exception is ready to process when it is detected and not stalled in a stage.
Flush specifics per pipeline stage:
MEM: Mask 'MemWrite' and 'MemRead' (for performance) after EX/M and before data memory. NOPs to M/WB.
EX : Mask writes to HI/LO. NOPs to EX/M.
ID : Mask writes (reads?) to CP0. NOPs to ID/EX.
IF : NOP to IF/ID.
***/
/*** Exceptions grouped by pipeline stage ***/
assign M_Exception_Detect = EXC_AdEL | EXC_AdES | EXC_Tr;
assign EX_Exception_Detect = EXC_Ov;
assign ID_Exception_Detect = EXC_Sys | EXC_Bp | EXC_RI | EXC_CpU | EXC_Int;
assign IF_Exception_Detect = EXC_AdIF;
/*** Exception mask conditions ***/
// A potential bug would occur if e.g. EX stalls, MEM has data, but MEM is not stalled and finishes
// going through the pipeline so forwarding would fail. This is not a problem however because
// EX would not need data since it would flush on an exception.
assign M_Exception_Mask = IF_Stall;
assign EX_Exception_Mask = IF_Stall | M_CanErr;
assign ID_Exception_Mask = IF_Stall | M_CanErr | EX_CanErr;
assign IF_Exception_Mask = M_CanErr | EX_CanErr | ID_CanErr | EXC_Int;
/***
Exceptions which must wait for forward stages. A stage will not stall if a forward stage has an exception.
These stalls must be inserted as stall conditions in the hazard unit so that it will take care of chaining.
All writes to CP0 must also wait for forward hazard conditions to clear.
*/
assign M_Exception_Stall = M_Exception_Detect & M_Exception_Mask;
assign EX_Exception_Stall = EX_Exception_Detect & EX_Exception_Mask & ~M_Exception_Detect;
assign ID_Exception_Stall = (ID_Exception_Detect | ERET | Mtc0) & ID_Exception_Mask & ~(EX_Exception_Detect | M_Exception_Detect);
assign IF_Exception_Stall = IF_Exception_Detect & IF_Exception_Mask & ~(ID_Exception_Detect | EX_Exception_Detect | M_Exception_Detect);
/*** Exceptions which are ready to process (mutually exclusive) ***/
// XXX can remove ~ID_Stall since in mask now (?)
assign M_Exception_Ready = ~ID_Stall & M_Exception_Detect & ~M_Exception_Mask;
assign EX_Exception_Ready = ~ID_Stall & EX_Exception_Detect & ~EX_Exception_Mask;
assign ID_Exception_Ready = ~ID_Stall & ID_Exception_Detect & ~ID_Exception_Mask;
assign IF_Exception_Ready = ~ID_Stall & IF_Exception_Detect & ~IF_Exception_Mask;
/***
Flushes. A flush clears a pipeline stage's control signals and prevents the stage from committing any changes.
Data such as 'RestartPC' and the detected exception must remain.
*/
assign M_Exception_Flush = M_Exception_Detect;
assign EX_Exception_Flush = M_Exception_Detect | EX_Exception_Detect;
assign ID_Exception_Flush = M_Exception_Detect | EX_Exception_Detect | ID_Exception_Detect;
assign IF_Exception_Flush = M_Exception_Detect | EX_Exception_Detect | ID_Exception_Detect | IF_Exception_Detect | (ERET & ~ID_Stall) | reset_r;
/*** Software reads of CP0 Registers ***/
always @(*) begin
if (Mfc0 & (Status_CU_0 | KernelMode)) begin
case (Rd)
5'd8 : Reg_Out <= BadVAddr;
5'd9 : Reg_Out <= Count;
5'd11 : Reg_Out <= Compare;
5'd12 : Reg_Out <= Status;
5'd13 : Reg_Out <= Cause;
5'd14 : Reg_Out <= EPC;
5'd15 : Reg_Out <= PRId;
5'd16 : Reg_Out <= (Sel == 3'b000) ? Config : Config1;
5'd30 : Reg_Out <= ErrorEPC;
default : Reg_Out <= 32'h0000_0000;
endcase
end
else begin
Reg_Out <= 32'h0000_0000;
end
end
/*** Cp0 Register Assignments: Non-general exceptions (Reset, Soft Reset, NMI...) ***/
always @(posedge clock) begin
if (reset) begin
Status_BEV <= 1;
Status_NMI <= 0;
Status_ERL <= 1;
ErrorEPC <= 32'b0;
end
else if (ID_Exception_Ready & EXC_NMI) begin
Status_BEV <= 1;
Status_NMI <= 1;
Status_ERL <= 1;
ErrorEPC <= ID_RestartPC;
end
else begin
Status_BEV <= (CP0_WriteCond & (Rd == 5'd12) & (Sel == 3'b000)) ? Reg_In[22] : Status_BEV;
Status_NMI <= (CP0_WriteCond & (Rd == 5'd12) & (Sel == 3'b000)) ? Reg_In[19] : Status_NMI;
Status_ERL <= (CP0_WriteCond & (Rd == 5'd12) & (Sel == 3'b000)) ? Reg_In[2] : ((Status_ERL & ERET & ~ID_Stall) ? 0 : Status_ERL);
ErrorEPC <= (CP0_WriteCond & (Rd == 5'd30) & (Sel == 3'b000)) ? Reg_In : ErrorEPC;
end
end
/*** Cp0 Register Assignments: All other registers ***/
always @(posedge clock) begin
if (reset) begin
Count <= 32'b0;
Compare <= 32'b0;
Status_CU_0 <= 0;
Status_RE <= 0;
Status_IM <= 8'b0;
Status_UM <= 0;
Status_IE <= 0;
Cause_IV <= 0;
Cause_IP <= 8'b0;
end
else begin
Count <= (CP0_WriteCond & (Rd == 5'd9 ) & (Sel == 3'b000)) ? Reg_In : ((Count == Compare) ? 32'b0 : Count + 1);
Compare <= (CP0_WriteCond & (Rd == 5'd11) & (Sel == 3'b000)) ? Reg_In : Compare;
Status_CU_0 <= (CP0_WriteCond & (Rd == 5'd12) & (Sel == 3'b000)) ? Reg_In[28] : Status_CU_0;
Status_RE <= (CP0_WriteCond & (Rd == 5'd12) & (Sel == 3'b000)) ? Reg_In[25] : Status_RE;
Status_IM <= (CP0_WriteCond & (Rd == 5'd12) & (Sel == 3'b000)) ? Reg_In[15:8] : Status_IM;
Status_UM <= (CP0_WriteCond & (Rd == 5'd12) & (Sel == 3'b000)) ? Reg_In[4] : Status_UM;
Status_IE <= (CP0_WriteCond & (Rd == 5'd12) & (Sel == 3'b000)) ? Reg_In[0] : Status_IE;
Cause_IV <= (CP0_WriteCond & (Rd == 5'd13) & (Sel == 3'b000)) ? Reg_In[23] : Cause_IV;
/* Cause_IP indicates 8 interrupts:
[7] is set by the timer comparison, and cleared by reading 'Count'.
[6:2] are set and cleared by external hardware.
[1:0] are set and cleared by software.
*/
// If reading -> 0, Otherwise if 0 -> Int5.
Cause_IP[7] <= ((Status_CU_0 | KernelMode) & Mfc0 & (Rd == 5'd9) & (Sel == 3'b000)) ? 0 : ((Cause_IP[7] == 0) ? Int5 : Cause_IP[7]);
Cause_IP[6:2] <= Int[4:0];
Cause_IP[1:0] <= (CP0_WriteCond & (Rd == 5'd13) & (Sel == 3'b000)) ? Reg_In[9:8] : Cause_IP[1:0];
end
end
/*** Cp0 Register Assignments: General Exception and Interrupt Processing ***/
always @(posedge clock) begin
if (reset) begin
Cause_BD <= 0;
Cause_CE <= 2'b00;
Cause_ExcCode30 <= 4'b0000;
Status_EXL <= 0;
EPC <= 32'h0;
BadVAddr <= 32'h0;
end
else begin
// MEM stage
if (M_Exception_Ready) begin
Cause_BD <= (Status_EXL) ? Cause_BD : M_IsBD;
Cause_CE <= (COP3) ? 2'b11 : ((COP2) ? 2'b10 : ((COP1) ? 2'b01 : 2'b00));
Cause_ExcCode30 <= Cause_ExcCode_bits;
Status_EXL <= 1;
EPC <= (Status_EXL) ? EPC : M_RestartPC;
BadVAddr <= BadAddr_M;
end
// EX stage
else if (EX_Exception_Ready) begin
Cause_BD <= (Status_EXL) ? Cause_BD : EX_IsBD;
Cause_CE <= (COP3) ? 2'b11 : ((COP2) ? 2'b10 : ((COP1) ? 2'b01 : 2'b00));
Cause_ExcCode30 <= Cause_ExcCode_bits;
Status_EXL <= 1;
EPC <= (Status_EXL) ? EPC : EX_RestartPC;
BadVAddr <= BadVAddr;
end
// ID stage
else if (ID_Exception_Ready) begin
Cause_BD <= (Status_EXL) ? Cause_BD : ID_IsBD;
Cause_CE <= (COP3) ? 2'b11 : ((COP2) ? 2'b10 : ((COP1) ? 2'b01 : 2'b00));
Cause_ExcCode30 <= Cause_ExcCode_bits;
Status_EXL <= 1;
EPC <= (Status_EXL) ? EPC : ID_RestartPC;
BadVAddr <= BadVAddr;
end
// IF stage
else if (IF_Exception_Ready) begin
Cause_BD <= (Status_EXL) ? Cause_BD : IF_IsBD;
Cause_CE <= (COP3) ? 2'b11 : ((COP2) ? 2'b10 : ((COP1) ? 2'b01 : 2'b00));
Cause_ExcCode30 <= Cause_ExcCode_bits;
Status_EXL <= 1;
EPC <= (Status_EXL) ? EPC : BadAddr_IF;
BadVAddr <= BadAddr_IF;
end
// No exceptions this cycle
else begin
Cause_BD <= 1'b0;
Cause_CE <= Cause_CE;
Cause_ExcCode30 <= Cause_ExcCode30;
// Without new exceptions, 'Status_EXL' is set by software or cleared by ERET.
Status_EXL <= (CP0_WriteCond & (Rd == 5'd12) & (Sel == 3'b000)) ? Reg_In[1] : ((Status_EXL & ERET & ~ID_Stall) ? 0 : Status_EXL);
// The EPC is also writable by software
EPC <= (CP0_WriteCond & (Rd == 5'd14) & (Sel == 3'b000)) ? Reg_In : EPC;
BadVAddr <= BadVAddr;
end
end
end
/*** Program Counter for all Exceptions/Interrupts ***/
always @(*) begin
// Following is redundant since PC has initial value now.
if (reset) begin
Exc_PC_Out <= EXC_Vector_Base_Reset;
end
else if (ERET & ~ID_Stall) begin
Exc_PC_Out <= (Status_ERL) ? ErrorEPC : EPC;
end
else if (EXC_General) begin
Exc_PC_Out <= (Status_BEV) ? (EXC_Vector_Base_Other_Boot + EXC_Vector_Offset_General) :
(EXC_Vector_Base_Other_NoBoot + EXC_Vector_Offset_General);
end
else if (EXC_NMI) begin
Exc_PC_Out <= EXC_Vector_Base_Reset;
end
else if (EXC_Int & Cause_IV) begin
Exc_PC_Out <= (Status_BEV) ? (EXC_Vector_Base_Other_Boot + EXC_Vector_Offset_Special) :
(EXC_Vector_Base_Other_NoBoot + EXC_Vector_Offset_Special);
end
else begin
Exc_PC_Out <= (Status_BEV) ? (EXC_Vector_Base_Other_Boot + EXC_Vector_Offset_General) :
(EXC_Vector_Base_Other_NoBoot + EXC_Vector_Offset_General);
end
end
//assign Exc_PC_Sel = (reset | (ERET & ~ID_Stall) | EXC_General | EXC_Int);
assign Exc_PC_Sel = reset | (ERET & ~ID_Stall) | IF_Exception_Ready | ID_Exception_Ready | EX_Exception_Ready | M_Exception_Ready;
/*** Cause Register ExcCode Field ***/
always @(*) begin
// Ordered by Pipeline Stage with Interrupts last
if (EXC_AdEL) Cause_ExcCode_bits <= 4'h4; // 00100
else if (EXC_AdES) Cause_ExcCode_bits <= 4'h5; // 00101
else if (EXC_Tr) Cause_ExcCode_bits <= 4'hd; // 01101
else if (EXC_Ov) Cause_ExcCode_bits <= 4'hc; // 01100
else if (EXC_Sys) Cause_ExcCode_bits <= 4'h8; // 01000
else if (EXC_Bp) Cause_ExcCode_bits <= 4'h9; // 01001
else if (EXC_RI) Cause_ExcCode_bits <= 4'ha; // 01010
else if (EXC_CpU) Cause_ExcCode_bits <= 4'hb; // 01011
else if (EXC_AdIF) Cause_ExcCode_bits <= 4'h4; // 00100
else if (EXC_Int) Cause_ExcCode_bits <= 4'h0; // 00000 // OK that NMI writes this.
else Cause_ExcCode_bits <= 4'bxxxx;
end
endmodule
@@ -0,0 +1,41 @@
`timescale 1ns / 1ps
/*
* File : Compare.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 15-Jun-2011 GEA Initial design.
*
* Standards/Formatting:
* Verilog 2001, 4 soft tab, wide column.
*
* Description:
* Compares two 32-bit values and outputs the following information about them:
* EQ : A and B are equal
* GZ : A is greater than zero
* LZ : A is less than zero
* GEZ : A is greater than or equal to zero
* 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
);
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);
endmodule
@@ -0,0 +1,509 @@
`timescale 1ns / 1ps
/*
* File : Control.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-May-2012 GEA Release version with CP0.
*
* Standards/Formatting:
* Verilog 2001, 4 soft tab, wide column.
*
* Description:
* The Datapath Controller. This module sets the datapath control
* bits for an incoming instruction. These control bits follow the
* instruction through each pipeline stage as needed, and constitute
* 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,
output Movz,
output Mfc0,
output Mtc0,
output CP1,
output CP2,
output CP3,
output Eret,
output Trap,
output TrapCond,
output EXC_Sys,
output EXC_Bp,
output EXC_RI,
output ID_CanErr,
output EX_CanErr,
output M_CanErr,
output NextIsDelay,
output RegDst,
output ALUSrcImm,
output reg [4:0] ALUOp,
output LLSC,
output MemWrite,
output MemRead,
output MemByte,
output MemHalf,
output MemSignExtend,
output Left,
output Right,
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 Unaligned_Mem;
reg [15:0] Datapath;
assign PCSrc[0] = Datapath[14];
assign Link = Datapath[13];
assign ALUSrcImm = Datapath[12];
assign Movc = Datapath[11];
assign Trap = Datapath[10];
assign TrapCond = Datapath[9];
assign RegDst = Datapath[8];
assign LLSC = Datapath[7];
assign MemRead = Datapath[6];
assign MemWrite = Datapath[5];
assign MemHalf = Datapath[4];
assign MemByte = Datapath[3];
assign MemSignExtend = Datapath[2];
assign RegWrite = Datapath[1];
assign MemtoReg = Datapath[0];
reg [2:0] DP_Exceptions;
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;
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
// 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
// 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
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
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
/***
These remaining options cover portions of the datapath that are not
controlled directly by the datapath bits. Note that some refer to bits of
the opcode or other fields, which breaks the otherwise fully-abstracted view
of instruction encodings. Make sure when adding custom instructions that
no false positives/negatives are generated here.
***/
// Branch Detection: Options are mutually exclusive.
assign Branch_EQ = OpCode[2] & ~OpCode[1] & ~OpCode[0] & Cmp_EQ;
assign Branch_GTZ = OpCode[2] & OpCode[1] & OpCode[0] & Cmp_GZ;
assign Branch_LEZ = OpCode[2] & OpCode[1] & ~OpCode[0] & Cmp_LEZ;
assign Branch_NEQ = OpCode[2] & ~OpCode[1] & OpCode[0] & ~Cmp_EQ;
assign Branch_GEZ = ~OpCode[2] & Rt[0] & Cmp_GEZ;
assign Branch_LTZ = ~OpCode[2] & ~Rt[0] & Cmp_LZ;
assign Branch = Branch_EQ | Branch_GTZ | Branch_LEZ | Branch_NEQ | Branch_GEZ | Branch_LTZ;
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;
// 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.
assign SignExtend = (OpCode[5:2] != 4'b0011);
// Move Conditional
assign Movn = Movc & Funct[0];
assign Movz = Movc & ~Funct[0];
// 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 Eret = ((OpCode == Op_Type_CP0) && (Rs == OpRs_ERET) && (Funct == Funct_ERET));
// Coprocessor 1,2,3 accesses (not implemented)
assign CP1 = (OpCode == Op_Type_CP1);
assign CP2 = (OpCode == Op_Type_CP2);
assign CP3 = (OpCode == Op_Type_CP3);
// Exceptions found in ID
assign EXC_Sys = ((OpCode == Op_Type_R) && (Funct == Funct_Syscall));
assign EXC_Bp = ((OpCode == Op_Type_R) && (Funct == Funct_Break));
// Unaligned Memory Accesses (lwl, lwr, swl, swr)
assign Unaligned_Mem = OpCode[5] & ~OpCode[4] & OpCode[1] & ~OpCode[0];
assign Left = Unaligned_Mem & ~OpCode[2];
assign Right = Unaligned_Mem & OpCode[2];
// TODO: Reserved Instruction Exception must still be implemented
assign EXC_RI = 0;
endmodule
@@ -0,0 +1,100 @@
`timescale 1ns / 1ns
/*
* File : Divide.v
* Project : University of Utah, XUM Project MIPS32 core
* Creator(s) : Neil Russell
*
* Modification History:
* Rev Date Initials Description of Change
* 1.0 6-Nov-2012 NJR Initial design.
*
* Description:
* A multi-cycle 32-bit divider.
*
* On any cycle that one of OP_div or OP_divu are true, the Dividend and
* Divisor will be captured and a multi-cycle divide operation initiated.
* Stall will go true on the next cycle and the first cycle of the divide
* operation completed. After some time (about 32 cycles), Stall will go
* false on the same cycle that the result becomes valid. OP_div or OP_divu
* will abort any currently running divide operation and initiate a new one.
*/
module Divide(
input clock,
input reset,
input OP_div, // True to initiate a signed divide
input OP_divu, // True to initiate an unsigned divide
input [31:0] Dividend,
input [31:0] Divisor,
output [31:0] Quotient,
output [31:0] Remainder,
output Stall // True while calculating
);
reg active; // True if the divider is running
reg neg; // True if the result will be negative
reg [4:0] cycle; // Number of cycles to go
reg [31:0] result; // Begin with dividend, end with quotient
reg [31:0] denom; // Divisor
reg [31:0] work; // Running remainder
// Calculate the current digit
wire [32:0] sub = { work[30:0], result[31] } - denom;
// Send the results to our master
assign Quotient = !neg ? result : -result;
assign Remainder = work;
assign Stall = active;
// The state machine
always @(posedge clock) begin
if (reset) begin
active <= 0;
neg <= 0;
cycle <= 0;
result <= 0;
denom <= 0;
work <= 0;
end
else begin
if (OP_div) begin
// Set up for a signed divide. Remember the resulting sign,
// and make the operands positive.
cycle <= 5'd31;
result <= (Dividend[31] == 0) ? Dividend : -Dividend;
denom <= (Divisor[31] == 0) ? Divisor : -Divisor;
work <= 32'b0;
neg <= Dividend[31] ^ Divisor[31];
active <= 1;
end
else if (OP_divu) begin
// Set up for an unsigned divide.
cycle <= 5'd31;
result <= Dividend;
denom <= Divisor;
work <= 32'b0;
neg <= 0;
active <= 1;
end
else if (active) begin
// Run an iteration of the divide.
if (sub[32] == 0) begin
work <= sub[31:0];
result <= {result[30:0], 1'b1};
end
else begin
work <= {work[30:0], result[31]};
result <= {result[30:0], 1'b0};
end
if (cycle == 0) begin
active <= 0;
end
cycle <= cycle - 5'd1;
end
end
end
endmodule
@@ -0,0 +1,116 @@
`timescale 1ns / 1ps
/*
* File : EXMEM_Stage.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 9-Jun-2011 GEA Initial design.
* 2.0 26-Jul-2012 GEA Many updates have been made.
*
* Standards/Formatting:
* Verilog 2001, 4 soft tab, wide column.
*
* Description:
* The Pipeline Register to bridge the Execute and Memory stages.
*/
module EXMEM_Stage(
input clock,
input reset,
input EX_Flush,
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_ReverseEndian,
input EX_LLSC,
input EX_MemRead,
input EX_MemWrite,
input EX_MemByte,
input EX_MemHalf,
input EX_MemSignExtend,
input EX_Left,
input EX_Right,
// Exception Control/Info
input EX_KernelMode,
input [31:0] EX_RestartPC,
input EX_IsBDS,
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,
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_Left,
output reg M_Right,
output reg M_KernelMode,
output reg [31:0] M_RestartPC,
output reg M_IsBDS,
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
);
/***
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
of delay, but reduces the combinatorial path length of signals which allows for
higher clock speeds.
All pipeline registers update unless the forward stage is stalled. When this occurs
or when the current stage is being flushed, the forward stage will receive data that
is effectively a NOP and causes nothing to happen throughout the remaining pipeline
traversal. In other words:
A stall masks all control signals to forward stages. A flush permanently clears
control signals to forward stages (but not certain data for exception purposes).
***/
// Mask of RegWrite if a Move Conditional failed.
wire MovcRegWrite = (EX_Movn & ~EX_BZero) | (EX_Movz & EX_BZero);
always @(posedge clock) begin
M_RegWrite <= (reset) ? 0 : ((M_Stall) ? M_RegWrite : ((EX_Stall | EX_Flush) ? 0 : EX_RegWrite));
M_RegWrite <= (reset) ? 0 : ((M_Stall) ? M_RegWrite : ((EX_Stall | EX_Flush) ? 0 : ((EX_Movn | EX_Movz) ? MovcRegWrite : EX_RegWrite)));
M_MemtoReg <= (reset) ? 0 : ((M_Stall) ? M_MemtoReg : EX_MemtoReg);
M_ReverseEndian <= (reset) ? 0 : ((M_Stall) ? M_ReverseEndian : EX_ReverseEndian);
M_LLSC <= (reset) ? 0 : ((M_Stall) ? M_LLSC : EX_LLSC);
M_MemRead <= (reset) ? 0 : ((M_Stall) ? M_MemRead : ((EX_Stall | EX_Flush) ? 0 : EX_MemRead));
M_MemWrite <= (reset) ? 0 : ((M_Stall) ? M_MemWrite : ((EX_Stall | EX_Flush) ? 0 : EX_MemWrite));
M_MemByte <= (reset) ? 0 : ((M_Stall) ? M_MemByte : EX_MemByte);
M_MemHalf <= (reset) ? 0 : ((M_Stall) ? M_MemHalf : EX_MemHalf);
M_MemSignExtend <= (reset) ? 0 : ((M_Stall) ? M_MemSignExtend : EX_MemSignExtend);
M_Left <= (reset) ? 0 : ((M_Stall) ? M_Left : EX_Left);
M_Right <= (reset) ? 0 : ((M_Stall) ? M_Right : EX_Right);
M_KernelMode <= (reset) ? 0 : ((M_Stall) ? M_KernelMode : EX_KernelMode);
M_RestartPC <= (reset) ? 32'b0 : ((M_Stall) ? M_RestartPC : EX_RestartPC);
M_IsBDS <= (reset) ? 0 : ((M_Stall) ? M_IsBDS : EX_IsBDS);
M_Trap <= (reset) ? 0 : ((M_Stall) ? M_Trap : ((EX_Stall | EX_Flush) ? 0 : EX_Trap));
M_TrapCond <= (reset) ? 0 : ((M_Stall) ? M_TrapCond : EX_TrapCond);
M_M_CanErr <= (reset) ? 0 : ((M_Stall) ? M_M_CanErr : ((EX_Stall | EX_Flush) ? 0 : EX_M_CanErr));
M_ALU_Result <= (reset) ? 32'b0 : ((M_Stall) ? M_ALU_Result : EX_ALU_Result);
M_ReadData2 <= (reset) ? 32'b0 : ((M_Stall) ? M_ReadData2 : EX_ReadData2);
M_RtRd <= (reset) ? 5'b0 : ((M_Stall) ? M_RtRd : EX_RtRd);
end
endmodule
@@ -0,0 +1,175 @@
`timescale 1ns / 1ps
/*
* File : Hazard_Detection.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 23-Jul-2011 GEA Initial design.
* 2.0 26-May-2012 GEA Release version with CP0.
* 2.01 1-Nov-2012 GEA Fixed issue with Jal.
*
* Standards/Formatting:
* Verilog 2001, 4 soft tab, wide column.
*
* Description:
* Hazard Detection and Forward Control. This is the glue that allows a
* pipelined processor to operate efficiently and correctly in the presence
* of data, structural, and control hazards. For each pipeline stage, it
* detects whether that stage requires data that is still in the pipeline,
* and whether that data may be forwarded or if the pipeline must be stalled.
*
* 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 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 IF_Exception_Stall,
input ID_Exception_Stall,
input EX_Exception_Stall,
input EX_ALU_Stall,
input M_Stall_Controller, // Determined by data memory controller
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.
*
* 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
* and thus are never needed for a data dependence, so the signal 'MEM_MemRead'
* 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];
// 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);
// 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) | EX_ALU_Stall | M_Stall;
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_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_Link) ? 2'b11 : ((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;
endmodule
@@ -0,0 +1,159 @@
`timescale 1ns / 1ps
/*
* File : IDEX_Stage.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 9-Jun-2011 GEA Initial design.
* 2.0 26-Jul-2012 GEA Many updates have been made.
*
* Standards/Formatting:
* Verilog 2001, 4 soft tab, wide column.
*
* Description:
* The Pipeline Register to bridge the Instruction Decode
* and Execute stages.
*/
module IDEX_Stage(
input clock,
input reset,
input ID_Flush,
input ID_Stall,
input EX_Stall,
// Control Signals
input ID_Link,
input ID_RegDst,
input ID_ALUSrcImm,
input [4:0] ID_ALUOp,
input ID_Movn,
input ID_Movz,
input ID_LLSC,
input ID_MemRead,
input ID_MemWrite,
input ID_MemByte,
input ID_MemHalf,
input ID_MemSignExtend,
input ID_Left,
input ID_Right,
input ID_RegWrite,
input ID_MemtoReg,
input ID_ReverseEndian,
// Hazard & Forwarding
input [4:0] ID_Rs,
input [4:0] ID_Rt,
input ID_WantRsByEX,
input ID_NeedRsByEX,
input ID_WantRtByEX,
input ID_NeedRtByEX,
// Exception Control/Info
input ID_KernelMode,
input [31:0] ID_RestartPC,
input ID_IsBDS,
input ID_Trap,
input ID_TrapCond,
input ID_EX_CanErr,
input ID_M_CanErr,
// Data Signals
input [31:0] ID_ReadData1,
input [31:0] ID_ReadData2,
input [16:0] ID_SignExtImm, // ID_Rd, ID_Shamt included here
// ----------------
output reg EX_Link,
output [1:0] EX_LinkRegDst,
output reg EX_ALUSrcImm,
output reg [4:0] EX_ALUOp,
output reg EX_Movn,
output reg EX_Movz,
output reg EX_LLSC,
output reg EX_MemRead,
output reg EX_MemWrite,
output reg EX_MemByte,
output reg EX_MemHalf,
output reg EX_MemSignExtend,
output reg EX_Left,
output reg EX_Right,
output reg EX_RegWrite,
output reg EX_MemtoReg,
output reg EX_ReverseEndian,
output reg [4:0] EX_Rs,
output reg [4:0] EX_Rt,
output reg EX_WantRsByEX,
output reg EX_NeedRsByEX,
output reg EX_WantRtByEX,
output reg EX_NeedRtByEX,
output reg EX_KernelMode,
output reg [31:0] EX_RestartPC,
output reg EX_IsBDS,
output reg EX_Trap,
output reg EX_TrapCond,
output reg EX_EX_CanErr,
output reg EX_M_CanErr,
output reg [31:0] EX_ReadData1,
output reg [31:0] EX_ReadData2,
output [31:0] EX_SignExtImm,
output [4:0] EX_Rd,
output [4:0] EX_Shamt
);
/***
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
of delay, but reduces the combinatorial path length of signals which allows for
higher clock speeds.
All pipeline registers update unless the forward stage is stalled. When this occurs
or when the current stage is being flushed, the forward stage will receive data that
is effectively a NOP and causes nothing to happen throughout the remaining pipeline
traversal. In other words:
A stall masks all control signals to forward stages. A flush permanently clears
control signals to forward stages (but not certain data for exception purposes).
***/
reg [16:0] EX_SignExtImm_pre;
reg EX_RegDst;
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]};
always @(posedge clock) begin
EX_Link <= (reset) ? 0 : ((EX_Stall) ? EX_Link : ID_Link);
EX_RegDst <= (reset) ? 0 : ((EX_Stall) ? EX_RegDst : ID_RegDst);
EX_ALUSrcImm <= (reset) ? 0 : ((EX_Stall) ? EX_ALUSrcImm : ID_ALUSrcImm);
EX_ALUOp <= (reset) ? 5'b0 : ((EX_Stall) ? EX_ALUOp : ((ID_Stall | ID_Flush) ? 5'b0 : ID_ALUOp));
EX_Movn <= (reset) ? 0 : ((EX_Stall) ? EX_Movn : ID_Movn);
EX_Movz <= (reset) ? 0 : ((EX_Stall) ? EX_Movz : ID_Movz);
EX_LLSC <= (reset) ? 0 : ((EX_Stall) ? EX_LLSC : ID_LLSC);
EX_MemRead <= (reset) ? 0 : ((EX_Stall) ? EX_MemRead : ((ID_Stall | ID_Flush) ? 0 : ID_MemRead));
EX_MemWrite <= (reset) ? 0 : ((EX_Stall) ? EX_MemWrite : ((ID_Stall | ID_Flush) ? 0 : ID_MemWrite));
EX_MemByte <= (reset) ? 0 : ((EX_Stall) ? EX_MemByte : ID_MemByte);
EX_MemHalf <= (reset) ? 0 : ((EX_Stall) ? EX_MemHalf : ID_MemHalf);
EX_MemSignExtend <= (reset) ? 0 : ((EX_Stall) ? EX_MemSignExtend : ID_MemSignExtend);
EX_Left <= (reset) ? 0 : ((EX_Stall) ? EX_Left : ID_Left);
EX_Right <= (reset) ? 0 : ((EX_Stall) ? EX_Right : ID_Right);
EX_RegWrite <= (reset) ? 0 : ((EX_Stall) ? EX_RegWrite : ((ID_Stall | ID_Flush) ? 0 : ID_RegWrite));
EX_MemtoReg <= (reset) ? 0 : ((EX_Stall) ? EX_MemtoReg : ID_MemtoReg);
EX_ReverseEndian <= (reset) ? 0 : ((EX_Stall) ? EX_ReverseEndian : ID_ReverseEndian);
EX_RestartPC <= (reset) ? 32'b0 : ((EX_Stall) ? EX_RestartPC : ID_RestartPC);
EX_IsBDS <= (reset) ? 0 : ((EX_Stall) ? EX_IsBDS : ID_IsBDS);
EX_Trap <= (reset) ? 0 : ((EX_Stall) ? EX_Trap : ((ID_Stall | ID_Flush) ? 0 : ID_Trap));
EX_TrapCond <= (reset) ? 0 : ((EX_Stall) ? EX_TrapCond : ID_TrapCond);
EX_EX_CanErr <= (reset) ? 0 : ((EX_Stall) ? EX_EX_CanErr : ((ID_Stall | ID_Flush) ? 0 : ID_EX_CanErr));
EX_M_CanErr <= (reset) ? 0 : ((EX_Stall) ? EX_M_CanErr : ((ID_Stall | ID_Flush) ? 0 : ID_M_CanErr));
EX_ReadData1 <= (reset) ? 32'b0 : ((EX_Stall) ? EX_ReadData1 : ID_ReadData1);
EX_ReadData2 <= (reset) ? 32'b0 : ((EX_Stall) ? EX_ReadData2 : ID_ReadData2);
EX_SignExtImm_pre <= (reset) ? 17'b0 : ((EX_Stall) ? EX_SignExtImm_pre : ID_SignExtImm);
EX_Rs <= (reset) ? 5'b0 : ((EX_Stall) ? EX_Rs : ID_Rs);
EX_Rt <= (reset) ? 5'b0 : ((EX_Stall) ? EX_Rt : ID_Rt);
EX_WantRsByEX <= (reset) ? 0 : ((EX_Stall) ? EX_WantRsByEX : ((ID_Stall | ID_Flush) ? 0 : ID_WantRsByEX));
EX_NeedRsByEX <= (reset) ? 0 : ((EX_Stall) ? EX_NeedRsByEX : ((ID_Stall | ID_Flush) ? 0 : ID_NeedRsByEX));
EX_WantRtByEX <= (reset) ? 0 : ((EX_Stall) ? EX_WantRtByEX : ((ID_Stall | ID_Flush) ? 0 : ID_WantRtByEX));
EX_NeedRtByEX <= (reset) ? 0 : ((EX_Stall) ? EX_NeedRtByEX : ((ID_Stall | ID_Flush) ? 0 : ID_NeedRtByEX));
EX_KernelMode <= (reset) ? 0 : ((EX_Stall) ? EX_KernelMode : ID_KernelMode);
end
endmodule
@@ -0,0 +1,75 @@
`timescale 1ns / 1ps
/*
* File : IFID_Stage.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 9-Jun-2011 GEA Initial design.
* 2.0 26-Jul-2012 GEA Many updates have been made.
*
* Standards/Formatting:
* Verilog 2001, 4 soft tab, wide column.
*
* Description:
* The Pipeline Register to bridge the Instruction Fetch
* and Instruction Decode stages.
*/
module IFID_Stage(
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 [31:0] IF_PC,
input IF_IsBDS,
// ------------------
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
of delay, but reduces the combinatorial path length of signals which allows for
higher clock speeds.
All pipeline registers update unless the forward stage is stalled. When this occurs
or when the current stage is being flushed, the forward stage will receive data that
is effectively a NOP and causes nothing to happen throughout the remaining pipeline
traversal. In other words:
A stall masks all control signals to forward stages. A flush permanently clears
control signals to forward stages (but not certain data for exception purposes).
***/
/***
The signal 'ID_IsFlushed' is needed because of interrupts. Normally, a flushed instruction
is a NOP which will never cause an exception and thus its restart PC will never be needed
or used. However, interrupts are detected in ID and may occur when any instruction, flushed
or not, is in the ID stage. It is an error to save the restart PC of a flushed instruction
since it was never supposed to execute (such as the "delay slot" after ERET or the branch
delay slot after a canceled Branch Likely instruction). A simple way to prevent this is to
pass a signal to ID indicating that its instruction was flushed. Interrupt detection is then
masked when this signal is high, and the interrupt will trigger on the next instruction load to ID.
***/
always @(posedge clock) begin
ID_Instruction <= (reset) ? 32'b0 : ((ID_Stall) ? ID_Instruction : ((IF_Stall | IF_Flush) ? 32'b0 : IF_Instruction));
ID_PCAdd4 <= (reset) ? 32'b0 : ((ID_Stall) ? ID_PCAdd4 : IF_PCAdd4);
ID_IsBDS <= (reset) ? 0 : ((ID_Stall) ? ID_IsBDS : IF_IsBDS);
ID_RestartPC <= (reset) ? 32'b0 : ((ID_Stall | IF_IsBDS) ? ID_RestartPC : IF_PC);
ID_IsFlushed <= (reset) ? 0 : ((ID_Stall) ? ID_IsFlushed : IF_Flush);
end
endmodule
@@ -0,0 +1,74 @@
`timescale 1ns / 1ps
/*
* File : MEMWB_Stage.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 9-Jun-2011 GEA Initial design.
* 2.0 26-Jul-2012 GEA Many updates have been made.
*
* Standards/Formatting:
* Verilog 2001, 4 soft tab, wide column.
*
* Description:
* The Pipeline Register to bridge the Memory and Writeback stages.
*/
module MEMWB_Stage(
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
);
/***
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
of delay, but reduces the combinatorial path length of signals which allows for
higher clock speeds.
All pipeline registers update unless the forward stage is stalled. When this occurs
or when the current stage is being flushed, the forward stage will receive data that
is effectively a NOP and causes nothing to happen throughout the remaining pipeline
traversal. In other words:
A stall masks all control signals to forward stages. A flush permanently clears
control signals to forward stages (but not certain data for exception purposes).
Since WB is the final stage in the pipeline, it would normally never stall.
However, because the MEM stage may be using data forwarded from WB, WB must stall
when MEM is stalled. If it didn't, the forward data would not be preserved. If
the processor didn't forward any data, a stall would not be needed.
In practice, the only time WB stalls is when forwarding for a Lw->Sw sequence, since
MEM doesn't need the data until its stage, but it does not latch the forwarded data.
This means WB_Stall is probably identical to M_Stall. There is no speed difference by
allowing WB to stall.
***/
always @(posedge clock) begin
WB_RegWrite <= (reset) ? 0 : ((WB_Stall) ? WB_RegWrite : ((M_Stall | M_Flush) ? 0 : M_RegWrite));
WB_MemtoReg <= (reset) ? 0 : ((WB_Stall) ? WB_MemtoReg : M_MemtoReg);
WB_ReadData <= (reset) ? 32'b0 : ((WB_Stall) ? WB_ReadData : M_ReadData);
WB_ALU_Result <= (reset) ? 32'b0 : ((WB_Stall) ? WB_ALU_Result : M_ALU_Result);
WB_RtRd <= (reset) ? 5'b0 : ((WB_Stall) ? WB_RtRd : M_RtRd);
end
endmodule
@@ -0,0 +1,631 @@
/*
* 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 ***
The MIPS Configuration Register (CP0 Register 16 Select 0) specifies the processor's
endianness. A processor in user mode may switch to reverse endianness, which will be
the opposite of this parameter.
*/
parameter Big_Endian = 1;
/*** 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;
parameter [15:0] DP_Addu = DP_RType;
parameter [15:0] DP_And = DP_RType;
parameter [15:0] DP_Andi = DP_IType;
parameter [15:0] DP_Beq = DP_Branch;
parameter [15:0] DP_Bgez = DP_Branch;
parameter [15:0] DP_Bgezal = DP_BranchLink;
parameter [15:0] DP_Bgtz = DP_Branch;
parameter [15:0] DP_Blez = DP_Branch;
parameter [15:0] DP_Bltz = DP_Branch;
parameter [15:0] DP_Bltzal = DP_BranchLink;
parameter [15:0] DP_Bne = DP_Branch;
parameter [15:0] DP_Break = DP_None;
parameter [15:0] DP_Clo = DP_RType;
parameter [15:0] DP_Clz = DP_RType;
parameter [15:0] DP_Div = DP_HiLoWr;
parameter [15:0] DP_Divu = DP_HiLoWr;
parameter [15:0] DP_Eret = DP_None;
parameter [15:0] DP_J = DP_Jump;
parameter [15:0] DP_Jal = DP_JumpLink;
parameter [15:0] DP_Jalr = DP_JumpLinkReg;
parameter [15:0] DP_Jr = DP_JumpReg;
parameter [15:0] DP_Lb = DP_LoadByteS;
parameter [15:0] DP_Lbu = DP_LoadByteU;
parameter [15:0] DP_Lh = DP_LoadHalfS;
parameter [15:0] DP_Lhu = DP_LoadHalfU;
parameter [15:0] DP_Ll = DP_LoadLinked;
parameter [15:0] DP_Lui = DP_IType;
parameter [15:0] DP_Lw = DP_LoadWord;
parameter [15:0] DP_Lwl = DP_LoadWord;
parameter [15:0] DP_Lwr = DP_LoadWord;
parameter [15:0] DP_Madd = DP_HiLoWr;
parameter [15:0] DP_Maddu = DP_HiLoWr;
parameter [15:0] DP_Mfc0 = DP_ExtWrRt;
parameter [15:0] DP_Mfhi = DP_ExtWrRd;
parameter [15:0] DP_Mflo = DP_ExtWrRd;
parameter [15:0] DP_Movn = DP_Movc;
parameter [15:0] DP_Movz = DP_Movc;
parameter [15:0] DP_Msub = DP_HiLoWr;
parameter [15:0] DP_Msubu = DP_HiLoWr;
parameter [15:0] DP_Mtc0 = DP_None;
parameter [15:0] DP_Mthi = DP_HiLoWr;
parameter [15:0] DP_Mtlo = DP_HiLoWr;
parameter [15:0] DP_Mul = DP_RType;
parameter [15:0] DP_Mult = DP_HiLoWr;
parameter [15:0] DP_Multu = DP_HiLoWr;
parameter [15:0] DP_Nor = DP_RType;
parameter [15:0] DP_Or = DP_RType;
parameter [15:0] DP_Ori = DP_IType;
parameter [15:0] DP_Pref = DP_None; // Not Implemented
parameter [15:0] DP_Sb = DP_StoreByte;
parameter [15:0] DP_Sc = DP_StoreCond;
parameter [15:0] DP_Sh = DP_StoreHalf;
parameter [15:0] DP_Sll = DP_RType;
parameter [15:0] DP_Sllv = DP_RType;
parameter [15:0] DP_Slt = DP_RType;
parameter [15:0] DP_Slti = DP_IType;
parameter [15:0] DP_Sltiu = DP_IType;
parameter [15:0] DP_Sltu = DP_RType;
parameter [15:0] DP_Sra = DP_RType;
parameter [15:0] DP_Srav = DP_RType;
parameter [15:0] DP_Srl = DP_RType;
parameter [15:0] DP_Srlv = DP_RType;
parameter [15:0] DP_Sub = DP_RType;
parameter [15:0] DP_Subu = DP_RType;
parameter [15:0] DP_Sw = DP_StoreWord;
parameter [15:0] DP_Swl = DP_StoreWord;
parameter [15:0] DP_Swr = DP_StoreWord;
parameter [15:0] DP_Syscall = DP_None;
parameter [15:0] DP_Teq = DP_TrapRegCZ;
parameter [15:0] DP_Teqi = DP_TrapImmCZ;
parameter [15:0] DP_Tge = DP_TrapRegCZ;
parameter [15:0] DP_Tgei = DP_TrapImmCZ;
parameter [15:0] DP_Tgeiu = DP_TrapImmCZ;
parameter [15:0] DP_Tgeu = DP_TrapRegCZ;
parameter [15:0] DP_Tlt = DP_TrapRegCNZ;
parameter [15:0] DP_Tlti = DP_TrapImmCNZ;
parameter [15:0] DP_Tltiu = DP_TrapImmCNZ;
parameter [15:0] DP_Tltu = DP_TrapRegCNZ;
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;
@@ -0,0 +1,233 @@
`timescale 1ns / 1ps
/*
* File : MemControl.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-Jun-2011 GEA Initial design.
* 2.0 28-Jun-2012 GEA Expanded from a simple byte/half/word unit to
* An advanced data memory controller capable of
* handling big/little endian, atomic and unaligned
* memory accesses.
*
* Standards/Formatting:
* Verilog 2001, 4 soft tab, wide column.
*
* Description:
* A Data Memory Controller which handles all read and write requests from the
* processor to data memory. All data accesses--whether big endian, little endian,
* byte, half, word, or unaligned transfers--are transformed into a simple read
* and write command to data memory over a 32-bit data bus, where the read command
* is one bit and the write command is 4 bits, one for each byte in the 32-bit word.
*/
module MemControl(
input clock,
input reset,
input [31:0] DataIn, // Data from CPU
input [31:0] Address, // From CPU
input [31:0] MReadData, // Data from Memory
input MemRead, // Memory Read command from CPU
input MemWrite, // Memory Write command from CPU
input DataMem_Ready, // Ready signal from Memory
input Byte, // Load/Store is Byte (8-bit)
input Half, // Load/Store is Half (16-bit)
input SignExtend, // Sub-word load should be sign extended
input KernelMode, // (Exception logic)
input ReverseEndian, // Reverse Endian Memory for User Mode
input LLSC, // (LLSC logic)
input ERET, // (LLSC logic)
input Left, // Unaligned Load/Store Word Left
input Right, // Unaligned Load/Store Word Right
input M_Exception_Stall,
input IF_Stall, // XXX Clean this up between this module and HAZ/FWD
output reg [31:0] DataOut, // Data to CPU
output [31:0] MWriteData, // Data to Memory
output reg [3:0] WriteEnable, // Write Enable to Memory for each of 4 bytes of Memory
output ReadEnable, // Read Enable to Memory
output M_Stall,
output EXC_AdEL, // Load Exception
output EXC_AdES // Store Exception
);
`include "MIPS_Parameters.v"
/*** Reverse Endian Mode
Normal memory accesses in the processor are Big Endian. The endianness can be reversed
to Little Endian in User Mode only.
*/
wire BE = KernelMode | ~ReverseEndian;
/*** Indicator that the current memory reference must be word-aligned ***/
wire Word = ~(Half | Byte | Left | Right);
// Exception Detection
wire EXC_KernelMem = ~KernelMode & (Address < UMem_Lower);
wire EXC_Word = Word & (Address[1] | Address[0]);
wire EXC_Half = Half & Address[0];
assign EXC_AdEL = MemRead & (EXC_KernelMem | EXC_Word | EXC_Half);
assign EXC_AdES = MemWrite & (EXC_KernelMem | EXC_Word | EXC_Half);
/*** Load Linked and Store Conditional logic ***
A 32-bit register keeps track of the address for atomic Load Linked / Store Conditional
operations. This register can be updated during stalls since it is not visible to
forward stages. It does not need to be flushed during exceptions, since ERET destroys
the atomicity condition and there are no detrimental effects in an exception handler.
The atomic condition is set with a Load Linked instruction, and cleared on an ERET
instruction or when any store instruction writes to one or more bytes covered by
the word address register. It does not update on a stall condition.
The MIPS32 spec states that an ERET instruction between LL and SC will cause the
atomicity condition to fail. This implementation uses the ERET signal from the ID
stage, which means instruction sequences such as "LL SC" could appear to have an
ERET instruction between them even though they don't. One way to fix this is to pass
the ERET signal through the pipeline to the MEM stage. However, because of the nature
of LL/SC operations (they occur in a loop which checks the result at each iteration),
an ERET will normally never be inserted into the pipeline programmatically until the
LL/SC sequence has completed (exceptions such as interrupts can still cause ERET, but
they can still cause them in the LL SC sequence as well). In other words, by not passing
ERET through the pipeline, the only possible effect is a performance penalty. Also this
may be irrelevant since currently ERET stalls for forward stages which can cause exceptions,
which includes LL and SC.
*/
reg [29:0] LLSC_Address;
reg LLSC_Atomic;
wire LLSC_MemWrite_Mask;
always @(posedge clock) begin
LLSC_Address <= (reset) ? 30'b0 : (MemRead & LLSC) ? Address[31:2] : LLSC_Address;
end
always @(posedge clock) begin
if (reset) begin
LLSC_Atomic <= 0;
end
else if (MemRead) begin
LLSC_Atomic <= (LLSC) ? 1 : LLSC_Atomic;
end
// XXX GEA Bug for Ganesh: remove "& ~IF_Stall" from below, then SC will always fail:
else if (ERET | (~M_Stall & ~IF_Stall & MemWrite & (Address[31:2] == LLSC_Address))) begin
LLSC_Atomic <= 0;
end
else begin
LLSC_Atomic <= LLSC_Atomic;
end
end
assign LLSC_MemWrite_Mask = (LLSC & MemWrite & (~LLSC_Atomic | (Address[31:2] != LLSC_Address)));
wire WriteCondition = MemWrite & ~(EXC_KernelMem | EXC_Word | EXC_Half) & ~LLSC_MemWrite_Mask;
wire ReadCondition = MemRead & ~(EXC_KernelMem | EXC_Word | EXC_Half);
reg RW_Mask;
always @(posedge clock) begin
RW_Mask <= (reset) ? 0 : (((MemWrite | MemRead) & DataMem_Ready) ? 1 : ((~M_Stall & ~IF_Stall) ? 0 : RW_Mask));
end
assign M_Stall = ReadEnable | (WriteEnable != 4'b0000) | DataMem_Ready | M_Exception_Stall;
assign ReadEnable = ReadCondition & ~RW_Mask;
wire Half_Access_L = (Address[1] ^ BE);
wire Half_Access_R = (Address[1] ~^ BE);
wire Byte_Access_LL = Half_Access_L & (Address[1] ~^ Address[0]);
wire Byte_Access_LM = Half_Access_L & (Address[0] ~^ BE);
wire Byte_Access_RM = Half_Access_R & (Address[0] ^ BE);
wire Byte_Access_RR = Half_Access_R & (Address[1] ~^ Address[0]);
// Write-Enable Signals to Memory
always @(*) begin
if (WriteCondition & ~RW_Mask) begin
if (Byte) begin
WriteEnable[3] <= Byte_Access_LL;
WriteEnable[2] <= Byte_Access_LM;
WriteEnable[1] <= Byte_Access_RM;
WriteEnable[0] <= Byte_Access_RR;
end
else if (Half) begin
WriteEnable[3] <= Half_Access_L;
WriteEnable[2] <= Half_Access_L;
WriteEnable[1] <= Half_Access_R;
WriteEnable[0] <= Half_Access_R;
end
else if (Left) begin
case (Address[1:0])
2'b00 : WriteEnable <= (BE) ? 4'b1111 : 4'b0001;
2'b01 : WriteEnable <= (BE) ? 4'b0111 : 4'b0011;
2'b10 : WriteEnable <= (BE) ? 4'b0011 : 4'b0111;
2'b11 : WriteEnable <= (BE) ? 4'b0001 : 4'b1111;
endcase
end
else if (Right) begin
case (Address[1:0])
2'b00 : WriteEnable <= (BE) ? 4'b1000 : 4'b1111;
2'b01 : WriteEnable <= (BE) ? 4'b1100 : 4'b1110;
2'b10 : WriteEnable <= (BE) ? 4'b1110 : 4'b1100;
2'b11 : WriteEnable <= (BE) ? 4'b1111 : 4'b1000;
endcase
end
else begin
WriteEnable <= 4'b1111;
end
end
else begin
WriteEnable <= 4'b0000;
end
end
// Data Going to Memory
assign MWriteData[31:24] = (Byte) ? DataIn[7:0] : ((Half) ? DataIn[15:8] : DataIn[31:24]);
assign MWriteData[23:16] = (Byte | Half) ? DataIn[7:0] : DataIn[23:16];
assign MWriteData[15:8] = (Byte) ? DataIn[7:0] : DataIn[15:8];
assign MWriteData[7:0] = DataIn[7:0];
// Data Read from Memory
always @(*) begin
if (Byte) begin
if (Byte_Access_LL) begin
DataOut <= (SignExtend & MReadData[31]) ? {24'hFFFFFF, MReadData[31:24]} : {24'h000000, MReadData[31:24]};
end
else if (Byte_Access_LM) begin
DataOut <= (SignExtend & MReadData[23]) ? {24'hFFFFFF, MReadData[23:16]} : {24'h000000, MReadData[23:16]};
end
else if (Byte_Access_RM) begin
DataOut <= (SignExtend & MReadData[15]) ? {24'hFFFFFF, MReadData[15:8]} : {24'h000000, MReadData[15:8]};
end
else begin
DataOut <= (SignExtend & MReadData[7]) ? {24'hFFFFFF, MReadData[7:0]} : {24'h000000, MReadData[7:0]};
end
end
else if (Half) begin
if (Half_Access_L) begin
DataOut <= (SignExtend & MReadData[31]) ? {16'hFFFF, MReadData[31:16]} : {16'h0000, MReadData[31:16]};
end
else begin
DataOut <= (SignExtend & MReadData[15]) ? {16'hFFFF, MReadData[15:0]} : {16'h0000, MReadData[15:0]};
end
end
else if (LLSC & MemWrite) begin
DataOut <= (LLSC_Atomic & (Address[31:2] == LLSC_Address)) ? 32'h0000_0001 : 32'h0000_0000;
end
else if (Left) begin
case (Address[1:0])
2'b00 : DataOut <= (BE) ? MReadData : {MReadData[7:0], DataIn[23:0]};
2'b01 : DataOut <= (BE) ? {MReadData[23:0], DataIn[7:0]} : {MReadData[15:0], DataIn[15:0]};
2'b10 : DataOut <= (BE) ? {MReadData[15:0], DataIn[15:0]} : {MReadData[23:0], DataIn[7:0]};
2'b11 : DataOut <= (BE) ? {MReadData[7:0], DataIn[23:0]} : MReadData;
endcase
end
else if (Right) begin
case (Address[1:0])
2'b00 : DataOut <= (BE) ? {DataIn[31:8], MReadData[31:24]} : MReadData;
2'b01 : DataOut <= (BE) ? {DataIn[31:16], MReadData[31:16]} : {DataIn[31:24], MReadData[31:8]};
2'b10 : DataOut <= (BE) ? {DataIn[31:24], MReadData[31:8]} : {DataIn[31:16], MReadData[31:16]};
2'b11 : DataOut <= (BE) ? MReadData : {DataIn[31:8], MReadData[31:24]};
endcase
end
else begin
DataOut <= MReadData;
end
end
endmodule
@@ -0,0 +1,26 @@
`timescale 1ns / 1ps
/*
* File : Mux2.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.
*
* Standards/Formatting:
* Verilog 2001, 4 soft tab, wide column.
*
* Description:
* 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
);
assign out = (sel) ? in1 : in0;
endmodule
@@ -0,0 +1,33 @@
`timescale 1ns / 1ps
/*
* File : Mux4.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.
*
* Standards/Formatting:
* Verilog 2001, 4 soft tab, wide column.
*
* Description:
* 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
);
always @(*) begin
case (sel)
2'b00 : out <= in0;
2'b01 : out <= in1;
2'b10 : out <= in2;
2'b11 : out <= in3;
endcase
end
endmodule
@@ -0,0 +1,679 @@
`timescale 1ns / 1ps
/*
* File : Processor.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 23-Jul-2011 GEA Initial design.
* 2.0 26-May-2012 GEA Release version with CP0.
* 2.01 1-Nov-2012 GEA Fixed issue with Jal.
*
* Standards/Formatting:
* Verilog 2001, 4 soft tab, wide column.
*
* Description:
* The top-level MIPS32 Processor. This file is mostly the instantiation
* and wiring of the building blocks of the processor according to the
* hardware design diagram. It contains very little logic itself.
*/
module Processor(
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,
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 [7:0] IP // Pending interrupts (diagnostic)
);
`include "MIPS_Parameters.v"
/*** MIPS Instruction and Components (ID Stage) ***/
wire [31:0] Instruction;
wire [5:0] OpCode = Instruction[31:26];
wire [4:0] Rs = Instruction[25:21];
wire [4:0] Rt = Instruction[20:16];
wire [4:0] Rd = Instruction[15:11];
wire [5:0] Funct = Instruction[5:0];
wire [15:0] Immediate = Instruction[15:0];
wire [25:0] JumpAddress = Instruction[25:0];
wire [2:0] Cp0_Sel = Instruction[2:0];
/*** IF (Instruction Fetch) Signals ***/
wire IF_Stall, IF_Flush;
wire IF_EXC_AdIF;
wire IF_Exception_Stall;
wire IF_Exception_Flush;
wire IF_IsBDS;
wire [31:0] IF_PCAdd4, IF_PC_PreExc, IF_PCIn, IF_PCOut, IF_Instruction;
/*** ID (Instruction Decode) Signals ***/
wire ID_Stall;
wire [1:0] ID_PCSrc;
wire [1:0] ID_RsFwdSel, ID_RtFwdSel;
wire ID_Link, ID_Movn, ID_Movz;
wire ID_SignExtend;
wire ID_LLSC;
wire ID_RegDst, ID_ALUSrcImm, ID_MemWrite, ID_MemRead, ID_MemByte, ID_MemHalf, ID_MemSignExtend, ID_RegWrite, ID_MemtoReg;
wire [4:0] ID_ALUOp;
wire ID_Mfc0, ID_Mtc0, ID_Eret;
wire ID_NextIsDelay;
wire ID_CanErr, ID_ID_CanErr, ID_EX_CanErr, ID_M_CanErr;
wire ID_KernelMode;
wire ID_ReverseEndian;
wire ID_Trap, ID_TrapCond;
wire ID_EXC_Sys, ID_EXC_Bp, ID_EXC_RI;
wire ID_Exception_Stall;
wire ID_Exception_Flush;
wire ID_PCSrc_Exc;
wire [31:0] ID_ExceptionPC;
wire ID_CP1, ID_CP2, ID_CP3;
wire [31:0] ID_PCAdd4;
wire [31:0] ID_ReadData1_RF, ID_ReadData1_End;
wire [31:0] ID_ReadData2_RF, ID_ReadData2_End;
wire [31:0] CP0_RegOut;
wire ID_CmpEQ, ID_CmpGZ, ID_CmpLZ, ID_CmpGEZ, ID_CmpLEZ;
wire [29:0] ID_SignExtImm = (ID_SignExtend & Immediate[15]) ? {14'h3FFF, Immediate} : {14'h0000, Immediate};
wire [31:0] ID_ImmLeftShift2 = {ID_SignExtImm[29:0], 2'b00};
wire [31:0] ID_JumpAddress = {ID_PCAdd4[31:28], JumpAddress[25:0], 2'b00};
wire [31:0] ID_BranchAddress;
wire [31:0] ID_RestartPC;
wire ID_IsBDS;
wire ID_Left, ID_Right;
wire ID_IsFlushed;
/*** EX (Execute) Signals ***/
wire EX_ALU_Stall, EX_Stall;
wire [1:0] EX_RsFwdSel, EX_RtFwdSel;
wire EX_Link;
wire [1:0] EX_LinkRegDst;
wire EX_ALUSrcImm;
wire [4:0] EX_ALUOp;
wire EX_Movn, EX_Movz;
wire EX_LLSC;
wire EX_MemRead, EX_MemWrite, EX_MemByte, EX_MemHalf, EX_MemSignExtend, EX_RegWrite, EX_MemtoReg;
wire [4:0] EX_Rs, EX_Rt;
wire EX_WantRsByEX, EX_NeedRsByEX, EX_WantRtByEX, EX_NeedRtByEX;
wire EX_Trap, EX_TrapCond;
wire EX_CanErr, EX_EX_CanErr, EX_M_CanErr;
wire EX_KernelMode;
wire EX_ReverseEndian;
wire EX_Exception_Stall;
wire EX_Exception_Flush;
wire [31:0] EX_ReadData1_PR, EX_ReadData1_Fwd, EX_ReadData2_PR, EX_ReadData2_Fwd, EX_ReadData2_Imm;
wire [31:0] EX_SignExtImm;
wire [4:0] EX_Rd, EX_RtRd, EX_Shamt;
wire [31:0] EX_ALUResult;
wire EX_BZero;
wire EX_EXC_Ov;
wire [31:0] EX_RestartPC;
wire EX_IsBDS;
wire EX_Left, EX_Right;
/*** MEM (Memory) Signals ***/
wire M_Stall, M_Stall_Controller;
wire M_LLSC;
wire M_MemRead, M_MemWrite, M_MemByte, M_MemHalf, M_MemSignExtend;
wire M_RegWrite, M_MemtoReg;
wire M_WriteDataFwdSel;
wire M_EXC_AdEL, M_EXC_AdES;
wire M_M_CanErr;
wire M_KernelMode;
wire M_ReverseEndian;
wire M_Trap, M_TrapCond;
wire M_EXC_Tr;
wire M_Exception_Flush;
wire [31:0] M_ALUResult, M_ReadData2_PR;
wire [4:0] M_RtRd;
wire [31:0] M_MemReadData;
wire [31:0] M_RestartPC;
wire M_IsBDS;
wire [31:0] M_WriteData_Pre;
wire M_Left, M_Right;
wire M_Exception_Stall;
/*** WB (Writeback) Signals ***/
wire WB_Stall, WB_RegWrite;
wire [31:0] WB_ReadData, WB_ALUResult;
wire [4:0] WB_RtRd;
wire [31:0] WB_WriteData;
/*** Other Signals ***/
wire [7:0] ID_DP_Hazards, HAZ_DP_Hazards;
/*** Assignments ***/
assign IF_Instruction = (IF_Stall) ? 32'h00000000 : InstMem_In;
assign IF_IsBDS = ID_NextIsDelay;
assign HAZ_DP_Hazards = {ID_DP_Hazards[7:4], EX_WantRsByEX, EX_NeedRsByEX, EX_WantRtByEX, EX_NeedRtByEX};
assign IF_EXC_AdIF = IF_PCOut[1] | IF_PCOut[0];
assign ID_CanErr = ID_ID_CanErr | ID_EX_CanErr | ID_M_CanErr;
assign EX_CanErr = EX_EX_CanErr | EX_M_CanErr;
assign M_CanErr = M_M_CanErr;
// External Memory Interface
reg IRead, IReadMask;
assign InstMem_Address = IF_PCOut[31:2];
assign DataMem_Address = M_ALUResult[31:2];
always @(posedge clock) begin
IRead <= (reset) ? 1 : ~InstMem_Ready;
IReadMask <= (reset) ? 0 : ((IRead & InstMem_Ready) ? 1 : ((~IF_Stall) ? 0 : IReadMask));
end
assign InstMem_Read = IRead & ~IReadMask;
/*** Datapath Controller ***/
Control Controller (
.ID_Stall (ID_Stall),
.OpCode (OpCode),
.Funct (Funct),
.Rs (Rs),
.Rt (Rt),
.Cmp_EQ (ID_CmpEQ),
.Cmp_GZ (ID_CmpGZ),
.Cmp_GEZ (ID_CmpGEZ),
.Cmp_LZ (ID_CmpLZ),
.Cmp_LEZ (ID_CmpLEZ),
.IF_Flush (IF_Flush),
.DP_Hazards (ID_DP_Hazards),
.PCSrc (ID_PCSrc),
.SignExtend (ID_SignExtend),
.Link (ID_Link),
.Movn (ID_Movn),
.Movz (ID_Movz),
.Mfc0 (ID_Mfc0),
.Mtc0 (ID_Mtc0),
.CP1 (ID_CP1),
.CP2 (ID_CP2),
.CP3 (ID_CP3),
.Eret (ID_Eret),
.Trap (ID_Trap),
.TrapCond (ID_TrapCond),
.EXC_Sys (ID_EXC_Sys),
.EXC_Bp (ID_EXC_Bp),
.EXC_RI (ID_EXC_RI),
.ID_CanErr (ID_ID_CanErr),
.EX_CanErr (ID_EX_CanErr),
.M_CanErr (ID_M_CanErr),
.NextIsDelay (ID_NextIsDelay),
.RegDst (ID_RegDst),
.ALUSrcImm (ID_ALUSrcImm),
.ALUOp (ID_ALUOp),
.LLSC (ID_LLSC),
.MemWrite (ID_MemWrite),
.MemRead (ID_MemRead),
.MemByte (ID_MemByte),
.MemHalf (ID_MemHalf),
.MemSignExtend (ID_MemSignExtend),
.Left (ID_Left),
.Right (ID_Right),
.RegWrite (ID_RegWrite),
.MemtoReg (ID_MemtoReg)
);
/*** Hazard and Forward Control Unit ***/
Hazard_Detection HazardControl (
.DP_Hazards (HAZ_DP_Hazards),
.ID_Rs (Rs),
.ID_Rt (Rt),
.EX_Rs (EX_Rs),
.EX_Rt (EX_Rt),
.EX_RtRd (EX_RtRd),
.MEM_RtRd (M_RtRd),
.WB_RtRd (WB_RtRd),
.EX_Link (EX_Link),
.EX_RegWrite (EX_RegWrite),
.MEM_RegWrite (M_RegWrite),
.WB_RegWrite (WB_RegWrite),
.MEM_MemRead (M_MemRead),
.MEM_MemWrite (M_MemWrite),
.InstMem_Read (InstMem_Read),
.InstMem_Ready (InstMem_Ready),
.Mfc0 (ID_Mfc0),
.IF_Exception_Stall (IF_Exception_Stall),
.ID_Exception_Stall (ID_Exception_Stall),
.EX_Exception_Stall (EX_Exception_Stall),
.EX_ALU_Stall (EX_ALU_Stall),
.M_Stall_Controller (M_Stall_Controller),
.IF_Stall (IF_Stall),
.ID_Stall (ID_Stall),
.EX_Stall (EX_Stall),
.M_Stall (M_Stall),
.WB_Stall (WB_Stall),
.ID_RsFwdSel (ID_RsFwdSel),
.ID_RtFwdSel (ID_RtFwdSel),
.EX_RsFwdSel (EX_RsFwdSel),
.EX_RtFwdSel (EX_RtFwdSel),
.M_WriteDataFwdSel (M_WriteDataFwdSel)
);
/*** Coprocessor 0: Exceptions and Interrupts ***/
CPZero CP0 (
.clock (clock),
.Mfc0 (ID_Mfc0),
.Mtc0 (ID_Mtc0),
.IF_Stall (IF_Stall),
.ID_Stall (ID_Stall),
.COP1 (ID_CP1),
.COP2 (ID_CP2),
.COP3 (ID_CP3),
.ERET (ID_Eret),
.Rd (Rd),
.Sel (Cp0_Sel),
.Reg_In (ID_ReadData2_End),
.Reg_Out (CP0_RegOut),
.KernelMode (ID_KernelMode),
.ReverseEndian (ID_ReverseEndian),
.Int (Interrupts),
.reset (reset),
.EXC_NMI (NMI),
.EXC_AdIF (IF_EXC_AdIF),
.EXC_AdEL (M_EXC_AdEL),
.EXC_AdES (M_EXC_AdES),
.EXC_Ov (EX_EXC_Ov),
.EXC_Tr (M_EXC_Tr),
.EXC_Sys (ID_EXC_Sys),
.EXC_Bp (ID_EXC_Bp),
.EXC_RI (ID_EXC_RI),
.ID_RestartPC (ID_RestartPC),
.EX_RestartPC (EX_RestartPC),
.M_RestartPC (M_RestartPC),
.ID_IsFlushed (ID_IsFlushed),
.IF_IsBD (IF_IsBDS),
.ID_IsBD (ID_IsBDS),
.EX_IsBD (EX_IsBDS),
.M_IsBD (M_IsBDS),
.BadAddr_M (M_ALUResult),
.BadAddr_IF (IF_PCOut),
.ID_CanErr (ID_CanErr),
.EX_CanErr (EX_CanErr),
.M_CanErr (M_CanErr),
.IF_Exception_Stall (IF_Exception_Stall),
.ID_Exception_Stall (ID_Exception_Stall),
.EX_Exception_Stall (EX_Exception_Stall),
.M_Exception_Stall (M_Exception_Stall),
.IF_Exception_Flush (IF_Exception_Flush),
.ID_Exception_Flush (ID_Exception_Flush),
.EX_Exception_Flush (EX_Exception_Flush),
.M_Exception_Flush (M_Exception_Flush),
.Exc_PC_Sel (ID_PCSrc_Exc),
.Exc_PC_Out (ID_ExceptionPC),
.IP (IP)
);
/*** PC Source Non-Exception Mux ***/
Mux4 #(.WIDTH(32)) PCSrcStd_Mux (
.sel (ID_PCSrc),
.in0 (IF_PCAdd4),
.in1 (ID_JumpAddress),
.in2 (ID_BranchAddress),
.in3 (ID_ReadData1_End),
.out (IF_PC_PreExc)
);
/*** PC Source Exception Mux ***/
Mux2 #(.WIDTH(32)) PCSrcExc_Mux (
.sel (ID_PCSrc_Exc),
.in0 (IF_PC_PreExc),
.in1 (ID_ExceptionPC),
.out (IF_PCIn)
);
/*** Program Counter (MIPS spec is 0xBFC00000 starting address) ***/
Register #(.WIDTH(32), .INIT(EXC_Vector_Base_Reset)) PC (
.clock (clock),
.reset (reset),
//.enable (~IF_Stall), // XXX verify. HERE. Was 1 but on stall latches PC+4, ad nauseum.
.enable (~(IF_Stall | ID_Stall)),
.D (IF_PCIn),
.Q (IF_PCOut)
);
/*** PC +4 Adder ***/
Add PC_Add4 (
.A (IF_PCOut),
.B (32'h00000004),
.C (IF_PCAdd4)
);
/*** Instruction Fetch -> Instruction Decode Stage Register ***/
IFID_Stage IFID (
.clock (clock),
.reset (reset),
.IF_Flush (IF_Exception_Flush | IF_Flush),
.IF_Stall (IF_Stall),
.ID_Stall (ID_Stall),
.IF_Instruction (IF_Instruction),
.IF_PCAdd4 (IF_PCAdd4),
.IF_PC (IF_PCOut),
.IF_IsBDS (IF_IsBDS),
.ID_Instruction (Instruction),
.ID_PCAdd4 (ID_PCAdd4),
.ID_RestartPC (ID_RestartPC),
.ID_IsBDS (ID_IsBDS),
.ID_IsFlushed (ID_IsFlushed)
);
/*** Register File ***/
RegisterFile RegisterFile (
.clock (clock),
.reset (reset),
.ReadReg1 (Rs),
.ReadReg2 (Rt),
.WriteReg (WB_RtRd),
.WriteData (WB_WriteData),
.RegWrite (WB_RegWrite),
.ReadData1 (ID_ReadData1_RF),
.ReadData2 (ID_ReadData2_RF)
);
/*** ID Rs Forwarding/Link Mux ***/
Mux4 #(.WIDTH(32)) IDRsFwd_Mux (
.sel (ID_RsFwdSel),
.in0 (ID_ReadData1_RF),
.in1 (M_ALUResult),
.in2 (WB_WriteData),
.in3 (32'hxxxxxxxx),
.out (ID_ReadData1_End)
);
/*** ID Rt Forwarding/CP0 Mfc0 Mux ***/
Mux4 #(.WIDTH(32)) IDRtFwd_Mux (
.sel (ID_RtFwdSel),
.in0 (ID_ReadData2_RF),
.in1 (M_ALUResult),
.in2 (WB_WriteData),
.in3 (CP0_RegOut),
.out (ID_ReadData2_End)
);
/*** Condition Compare Unit ***/
Compare Compare (
.A (ID_ReadData1_End),
.B (ID_ReadData2_End),
.EQ (ID_CmpEQ),
.GZ (ID_CmpGZ),
.LZ (ID_CmpLZ),
.GEZ (ID_CmpGEZ),
.LEZ (ID_CmpLEZ)
);
/*** Branch Address Adder ***/
Add BranchAddress_Add (
.A (ID_PCAdd4),
.B (ID_ImmLeftShift2),
.C (ID_BranchAddress)
);
/*** Instruction Decode -> Execute Pipeline Stage ***/
IDEX_Stage IDEX (
.clock (clock),
.reset (reset),
.ID_Flush (ID_Exception_Flush),
.ID_Stall (ID_Stall),
.EX_Stall (EX_Stall),
.ID_Link (ID_Link),
.ID_RegDst (ID_RegDst),
.ID_ALUSrcImm (ID_ALUSrcImm),
.ID_ALUOp (ID_ALUOp),
.ID_Movn (ID_Movn),
.ID_Movz (ID_Movz),
.ID_LLSC (ID_LLSC),
.ID_MemRead (ID_MemRead),
.ID_MemWrite (ID_MemWrite),
.ID_MemByte (ID_MemByte),
.ID_MemHalf (ID_MemHalf),
.ID_MemSignExtend (ID_MemSignExtend),
.ID_Left (ID_Left),
.ID_Right (ID_Right),
.ID_RegWrite (ID_RegWrite),
.ID_MemtoReg (ID_MemtoReg),
.ID_ReverseEndian (ID_ReverseEndian),
.ID_Rs (Rs),
.ID_Rt (Rt),
.ID_WantRsByEX (ID_DP_Hazards[3]),
.ID_NeedRsByEX (ID_DP_Hazards[2]),
.ID_WantRtByEX (ID_DP_Hazards[1]),
.ID_NeedRtByEX (ID_DP_Hazards[0]),
.ID_KernelMode (ID_KernelMode),
.ID_RestartPC (ID_RestartPC),
.ID_IsBDS (ID_IsBDS),
.ID_Trap (ID_Trap),
.ID_TrapCond (ID_TrapCond),
.ID_EX_CanErr (ID_EX_CanErr),
.ID_M_CanErr (ID_M_CanErr),
.ID_ReadData1 (ID_ReadData1_End),
.ID_ReadData2 (ID_ReadData2_End),
.ID_SignExtImm (ID_SignExtImm[16:0]),
.EX_Link (EX_Link),
.EX_LinkRegDst (EX_LinkRegDst),
.EX_ALUSrcImm (EX_ALUSrcImm),
.EX_ALUOp (EX_ALUOp),
.EX_Movn (EX_Movn),
.EX_Movz (EX_Movz),
.EX_LLSC (EX_LLSC),
.EX_MemRead (EX_MemRead),
.EX_MemWrite (EX_MemWrite),
.EX_MemByte (EX_MemByte),
.EX_MemHalf (EX_MemHalf),
.EX_MemSignExtend (EX_MemSignExtend),
.EX_Left (EX_Left),
.EX_Right (EX_Right),
.EX_RegWrite (EX_RegWrite),
.EX_MemtoReg (EX_MemtoReg),
.EX_ReverseEndian (EX_ReverseEndian),
.EX_Rs (EX_Rs),
.EX_Rt (EX_Rt),
.EX_WantRsByEX (EX_WantRsByEX),
.EX_NeedRsByEX (EX_NeedRsByEX),
.EX_WantRtByEX (EX_WantRtByEX),
.EX_NeedRtByEX (EX_NeedRtByEX),
.EX_KernelMode (EX_KernelMode),
.EX_RestartPC (EX_RestartPC),
.EX_IsBDS (EX_IsBDS),
.EX_Trap (EX_Trap),
.EX_TrapCond (EX_TrapCond),
.EX_EX_CanErr (EX_EX_CanErr),
.EX_M_CanErr (EX_M_CanErr),
.EX_ReadData1 (EX_ReadData1_PR),
.EX_ReadData2 (EX_ReadData2_PR),
.EX_SignExtImm (EX_SignExtImm),
.EX_Rd (EX_Rd),
.EX_Shamt (EX_Shamt)
);
/*** EX Rs Forwarding Mux ***/
Mux4 #(.WIDTH(32)) EXRsFwd_Mux (
.sel (EX_RsFwdSel),
.in0 (EX_ReadData1_PR),
.in1 (M_ALUResult),
.in2 (WB_WriteData),
.in3 (EX_RestartPC),
.out (EX_ReadData1_Fwd)
);
/*** EX Rt Forwarding / Link Mux ***/
Mux4 #(.WIDTH(32)) EXRtFwdLnk_Mux (
.sel (EX_RtFwdSel),
.in0 (EX_ReadData2_PR),
.in1 (M_ALUResult),
.in2 (WB_WriteData),
.in3 (32'h00000008),
.out (EX_ReadData2_Fwd)
);
/*** EX ALU Immediate Mux ***/
Mux2 #(.WIDTH(32)) EXALUImm_Mux (
.sel (EX_ALUSrcImm),
.in0 (EX_ReadData2_Fwd),
.in1 (EX_SignExtImm),
.out (EX_ReadData2_Imm)
);
/*** EX RtRd / Link Mux ***/
Mux4 #(.WIDTH(5)) EXRtRdLnk_Mux (
.sel (EX_LinkRegDst),
.in0 (EX_Rt),
.in1 (EX_Rd),
.in2 (5'b11111),
.in3 (5'bxxxxx),
.out (EX_RtRd)
);
/*** Arithmetic Logic Unit ***/
ALU ALU (
.clock (clock),
.reset (reset),
.EX_Stall (EX_Stall),
.EX_Flush (EX_Exception_Flush),
.A (EX_ReadData1_Fwd),
.B (EX_ReadData2_Imm),
.Operation (EX_ALUOp),
.Shamt (EX_Shamt),
.Result (EX_ALUResult),
.BZero (EX_BZero),
.EXC_Ov (EX_EXC_Ov),
.ALU_Stall (EX_ALU_Stall)
);
/*** Execute -> Memory Pipeline Stage ***/
EXMEM_Stage EXMEM (
.clock (clock),
.reset (reset),
.EX_Flush (EX_Exception_Flush),
.EX_Stall (EX_Stall),
.M_Stall (M_Stall),
.EX_Movn (EX_Movn),
.EX_Movz (EX_Movz),
.EX_BZero (EX_BZero),
.EX_RegWrite (EX_RegWrite),
.EX_MemtoReg (EX_MemtoReg),
.EX_ReverseEndian (EX_ReverseEndian),
.EX_LLSC (EX_LLSC),
.EX_MemRead (EX_MemRead),
.EX_MemWrite (EX_MemWrite),
.EX_MemByte (EX_MemByte),
.EX_MemHalf (EX_MemHalf),
.EX_MemSignExtend (EX_MemSignExtend),
.EX_Left (EX_Left),
.EX_Right (EX_Right),
.EX_KernelMode (EX_KernelMode),
.EX_RestartPC (EX_RestartPC),
.EX_IsBDS (EX_IsBDS),
.EX_Trap (EX_Trap),
.EX_TrapCond (EX_TrapCond),
.EX_M_CanErr (EX_M_CanErr),
.EX_ALU_Result (EX_ALUResult),
.EX_ReadData2 (EX_ReadData2_Fwd),
.EX_RtRd (EX_RtRd),
.M_RegWrite (M_RegWrite),
.M_MemtoReg (M_MemtoReg),
.M_ReverseEndian (M_ReverseEndian),
.M_LLSC (M_LLSC),
.M_MemRead (M_MemRead),
.M_MemWrite (M_MemWrite),
.M_MemByte (M_MemByte),
.M_MemHalf (M_MemHalf),
.M_MemSignExtend (M_MemSignExtend),
.M_Left (M_Left),
.M_Right (M_Right),
.M_KernelMode (M_KernelMode),
.M_RestartPC (M_RestartPC),
.M_IsBDS (M_IsBDS),
.M_Trap (M_Trap),
.M_TrapCond (M_TrapCond),
.M_M_CanErr (M_M_CanErr),
.M_ALU_Result (M_ALUResult),
.M_ReadData2 (M_ReadData2_PR),
.M_RtRd (M_RtRd)
);
/*** Trap Detection Unit ***/
TrapDetect TrapDetect (
.Trap (M_Trap),
.TrapCond (M_TrapCond),
.ALUResult (M_ALUResult),
.EXC_Tr (M_EXC_Tr)
);
/*** MEM Write Data Mux ***/
Mux2 #(.WIDTH(32)) MWriteData_Mux (
.sel (M_WriteDataFwdSel),
.in0 (M_ReadData2_PR),
.in1 (WB_WriteData),
.out (M_WriteData_Pre)
);
/*** Data Memory Controller ***/
MemControl DataMem_Controller (
.clock (clock),
.reset (reset),
.DataIn (M_WriteData_Pre),
.Address (M_ALUResult),
.MReadData (DataMem_In),
.MemRead (M_MemRead),
.MemWrite (M_MemWrite),
.DataMem_Ready (DataMem_Ready),
.Byte (M_MemByte),
.Half (M_MemHalf),
.SignExtend (M_MemSignExtend),
.KernelMode (M_KernelMode),
.ReverseEndian (M_ReverseEndian),
.LLSC (M_LLSC),
.ERET (ID_Eret),
.Left (M_Left),
.Right (M_Right),
.M_Exception_Stall (M_Exception_Stall),
.IF_Stall (IF_Stall),
.DataOut (M_MemReadData),
.MWriteData (DataMem_Out),
.WriteEnable (DataMem_Write),
.ReadEnable (DataMem_Read),
.M_Stall (M_Stall_Controller),
.EXC_AdEL (M_EXC_AdEL),
.EXC_AdES (M_EXC_AdES)
);
/*** Memory -> Writeback Pipeline Stage ***/
MEMWB_Stage MEMWB (
.clock (clock),
.reset (reset),
.M_Flush (M_Exception_Flush),
.M_Stall (M_Stall),
.WB_Stall (WB_Stall),
.M_RegWrite (M_RegWrite),
.M_MemtoReg (M_MemtoReg),
.M_ReadData (M_MemReadData),
.M_ALU_Result (M_ALUResult),
.M_RtRd (M_RtRd),
.WB_RegWrite (WB_RegWrite),
.WB_MemtoReg (WB_MemtoReg),
.WB_ReadData (WB_ReadData),
.WB_ALU_Result (WB_ALUResult),
.WB_RtRd (WB_RtRd)
);
/*** WB MemtoReg Mux ***/
Mux2 #(.WIDTH(32)) WBMemtoReg_Mux (
.sel (WB_MemtoReg),
.in0 (WB_ALUResult),
.in1 (WB_ReadData),
.out (WB_WriteData)
);
endmodule
@@ -0,0 +1,28 @@
MIPS32-R1 Standalone
--------------------
The files in this directory create a complete MIPS32 processor. The top-level
module is "Processor.v". The interface includes 5 general-purpose hardware
interrupts, a non-maskable hardware interrupt, the 8 pending ISA interrupts
(for diagnostics--this can be removed), and a memory interface for both
instructions and data.
The memory interface is implemented as a four-way handshake:
1. Read/Write request goes high.
2. Ack goes high when data is available.
3. Read/Write request goes low.
4. Ack signal goes low.
____
R/W: __| |____
____
Ack: _____| |____
This interface is simple and robust but can limit the performance of the
system. In the SoC design this is currently the case, since the instruction
memory fetches only once per handshake. This greatly increases the maximum
theoretical IPC from 1 to between 3 and 4.
If your application requires maximum performance out of this processor,
you should modify the memory handshake accordingly.
@@ -0,0 +1,34 @@
`timescale 1ns / 1ps
/*
* File : Register.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.
*
* Standards/Formatting:
* Verilog 2001, 4 soft tab, wide column.
*
* Description:
* A variable-width register (d flip-flop) with configurable initial
* 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;
always @(posedge clock) begin
Q <= (reset) ? INIT : ((enable) ? D : Q);
end
endmodule
@@ -0,0 +1,58 @@
`timescale 1ns / 1ps
/*
* File : RegisterFile.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.
*
* Standards/Formatting:
* Verilog 2001, 4 soft tab, wide column.
*
* Description:
* A Register File for a MIPS processor. Contains 32 general-purpose
* 32-bit wide registers and two read ports. Register 0 always reads
* as zero.
*/
module RegisterFile(
input clock,
input reset,
input [4:0] ReadReg1, ReadReg2, WriteReg,
input [31:0] WriteData,
input RegWrite,
output [31:0] ReadData1, ReadData2
);
// Register file of 32 32-bit registers. Register 0 is hardwired to 0s
reg [31:0] registers [1:31];
// Initialize all to zero
integer i;
initial begin
for (i=1; i<32; i=i+1) begin
registers[i] <= 0;
end
end
// Sequential (clocked) write.
// 'WriteReg' is the register index to write. 'RegWrite' is the command.
always @(posedge clock) begin
if (reset) begin
for (i=1; i<32; i=i+1) begin
registers[i] <= 0;
end
end
else begin
if (WriteReg != 0)
registers[WriteReg] <= (RegWrite) ? WriteData : registers[WriteReg];
end
end
// Combinatorial Read. Register 0 is all 0s.
assign ReadData1 = (ReadReg1 == 0) ? 32'h00000000 : registers[ReadReg1];
assign ReadData2 = (ReadReg2 == 0) ? 32'h00000000 : registers[ReadReg2];
endmodule
@@ -0,0 +1,28 @@
`timescale 1ns / 1ps
/*
* File : TrapDetect.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 15-May-2012 GEA Initial design.
*
* Standards/Formatting:
* Verilog 2001, 4 soft tab, wide column.
*
* Description:
* Detects a Trap Exception in the pipeline.
*/
module TrapDetect(
input Trap,
input TrapCond,
input [31:0] ALUResult,
output EXC_Tr
);
wire ALUZero = (ALUResult == 32'h00000000);
assign EXC_Tr = Trap & (TrapCond ^ ALUZero);
endmodule
@@ -0,0 +1,88 @@
MIPS32-R1 SoC HOWTO
-------------------
This document is a step-by-step procedure for building the MIPS32 hardware
and software and running it on the XUPV5-LX110T FPGA development board. With
minimal changes, other hardware platforms may be used as well (see FAQ).
Procedure
---------
1. Build the software toolchain. Instructions for doing this are located
in the "Software/toolchain" directory.
2. Open the project file "MIPS32-Pipelined-Hw.xise" located in the
"Hardware/XUPV5-LX110T_SoC/MIPS32-Pipelined-Hw" directory. This is
a Xilinx ISE 14.1 project file.
3. Build the Block RAM core by using the Block Memory Generator in
the Core Generator. See details below.
4. Build the hardware project and generate the programming .bit file.
Send the programming file to the board through Impact (you may need
to create a new Impact project file for your system, but no options
are needed other than the configuration .bit file targeted for the
Virtex-5 device). A default program built into the BRAM will print
a hello message to the LCD screen.
Alternatively, a pre-built .bit file is located in the
"Hardware/XUPV5-LX110T_SoC" directory. It is timed conservatively
at 33 MHz (66 MHz bus).
5. Compile any of the software demos located in "Software/demos" using
the Makefile included with the demo. One of the output files from
the compilation will have a .xum extension. This is a binary file that
contains the code and data for the program. Use the XUM Bootloader
software (Windows) to send the .xum file over a serial port to the
FPGA. When the program is sent, the CPU will reset and run it.
Rebuilding the Block RAM
------------------------
The following settings will allow you to build the Block RAM module
and add a default program to it assuming Xilinx Block Memory Generator
version 7.1): True Dual Port RAM, Common Clock, Byte Write Enable of 8
bits, Write/Read width of 32 bits, Write depth of 151552 (for full
592 KB), Always Enabled, same options for port B, Register Port A Output
of Memory Primitives AND Memory Core (for 2R version, this can be
customized), same settings for Port B, fill remaining locations with
0x00000000, optionally load a .coe file with initial memory contents,
use RSTA and RSTB. The file 'Boot.coe' provides the simple hello message
program.
FAQ
---
Q: What if I don't have the XUPV5-LX110T board?
A: If you have the same Virtex 5 FPGA but a different board, all you need
to do is update the pin locations in the User Constraints File (.ucf)
and either make sure your clock input is 100 MHz or adjust the PLL
in the clocking module of the design accordingly. Note that some
hardware such as the LCD screen or piezo speaker may not be present
on your board, in which case you should remove them from the design.
Q: What if I don't have a Virtex 5 FPGA?
A: Any FPGA can implement this design if it has enough logic resources.
There are only two Xilinx-specific modules in the MIPS32 SoC design;
the clocking module and BRAM module. Replace these with whatever suits
your hardware. Note however that the MIPS32 memory interface uses
byte-width write enables to memory (4 bits per 32-bit word), so if you
use Block Memory or equivalents they must either support this or
you must fake it somehow. You must also update the UCF.
Q: What if I don't have or use the Xilinx development tools?
A: If you only care about the MIPS32 processor and not the full SoC, start
with the "Hardware/MIPS32_Standalone" directory which contains only
Verilog files. The top-most module is "Processor.v". For the full SoC,
copy the "Hardware/XUPV5-LX110T_SoC/MIPS32-Pipelined-Hw/src" directory
to whatever development environment you use. This directory contains
all of the Verilog files with "Top.v" as the head. The "Clocks" and
"BRAM" directories will need to be customized for your environment,
as well as the pin constraints.
Q: Is there a non-Windows version of the bootloader?
A: No, but the boot protocol is simple and can be implemented for any OS.
See "Hardware/XUPV5-LX110T_SoC/MIPS32-Pipelined-Hw/src/UART/
uart_bootloader_v2.v" for a description of the protocol. If you
implement another version of the bootloader, please contribute it back
to the project.
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,30 @@
<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
<generated_project xmlns="http://www.xilinx.com/XMLSchema" xmlns:xil_pn="http://www.xilinx.com/XMLSchema">
<!-- -->
<!-- For tool use only. Do not edit. -->
<!-- -->
<!-- ProjectNavigator created generated project file. -->
<!-- For use in tracking generated file and other information -->
<!-- allowing preservation of process status. -->
<!-- -->
<!-- Copyright (c) 1995-2012 Xilinx, Inc. All rights reserved. -->
<version xmlns="http://www.xilinx.com/XMLSchema">11.1</version>
<sourceproject xmlns="http://www.xilinx.com/XMLSchema" xil_pn:fileType="FILE_XISE" xil_pn:name="MIPS32-Pipelined-Hw.xise"/>
<files xmlns="http://www.xilinx.com/XMLSchema">
<file xil_pn:fileType="FILE_NCD" xil_pn:name="Top_guide.ncd" xil_pn:origination="imported"/>
</files>
<transforms xmlns="http://www.xilinx.com/XMLSchema"/>
</generated_project>
@@ -0,0 +1,523 @@
<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
<project xmlns="http://www.xilinx.com/XMLSchema" xmlns:xil_pn="http://www.xilinx.com/XMLSchema">
<header>
<!-- ISE source project file created by Project Navigator. -->
<!-- -->
<!-- This file contains project source information including a list of -->
<!-- project source files, project and process properties. This file, -->
<!-- along with the project source files, is sufficient to open and -->
<!-- implement in ISE Project Navigator. -->
<!-- -->
<!-- Copyright (c) 1995-2012 Xilinx, Inc. All rights reserved. -->
</header>
<version xil_pn:ise_version="14.1" xil_pn:schema_version="2"/>
<files>
<file xil_pn:name="src/Top.ucf" xil_pn:type="FILE_UCF">
<association xil_pn:name="Implementation" xil_pn:seqID="0"/>
</file>
<file xil_pn:name="src/Top.v" xil_pn:type="FILE_VERILOG">
<association xil_pn:name="BehavioralSimulation" xil_pn:seqID="38"/>
<association xil_pn:name="Implementation" xil_pn:seqID="39"/>
</file>
<file xil_pn:name="src/UART/uart_bootloader_v2.v" xil_pn:type="FILE_VERILOG">
<association xil_pn:name="BehavioralSimulation" xil_pn:seqID="29"/>
<association xil_pn:name="Implementation" xil_pn:seqID="30"/>
</file>
<file xil_pn:name="src/UART/uart_clock.v" xil_pn:type="FILE_VERILOG">
<association xil_pn:name="BehavioralSimulation" xil_pn:seqID="4"/>
<association xil_pn:name="Implementation" xil_pn:seqID="4"/>
</file>
<file xil_pn:name="src/UART/uart_rx.v" xil_pn:type="FILE_VERILOG">
<association xil_pn:name="BehavioralSimulation" xil_pn:seqID="3"/>
<association xil_pn:name="Implementation" xil_pn:seqID="3"/>
</file>
<file xil_pn:name="src/UART/uart_tx.v" xil_pn:type="FILE_VERILOG">
<association xil_pn:name="BehavioralSimulation" xil_pn:seqID="2"/>
<association xil_pn:name="Implementation" xil_pn:seqID="2"/>
</file>
<file xil_pn:name="src/UART/uart-min.v" xil_pn:type="FILE_VERILOG">
<association xil_pn:name="BehavioralSimulation" xil_pn:seqID="8"/>
<association xil_pn:name="Implementation" xil_pn:seqID="9"/>
</file>
<file xil_pn:name="src/Common/FIFO_Clear.v" xil_pn:type="FILE_VERILOG">
<association xil_pn:name="BehavioralSimulation" xil_pn:seqID="7"/>
<association xil_pn:name="Implementation" xil_pn:seqID="8"/>
</file>
<file xil_pn:name="src/Common/FIFO_NoFull_Count.v" xil_pn:type="FILE_VERILOG">
<association xil_pn:name="BehavioralSimulation" xil_pn:seqID="6"/>
<association xil_pn:name="Implementation" xil_pn:seqID="7"/>
</file>
<file xil_pn:name="src/Common/Mux2.v" xil_pn:type="FILE_VERILOG">
<association xil_pn:name="BehavioralSimulation" xil_pn:seqID="27"/>
<association xil_pn:name="Implementation" xil_pn:seqID="28"/>
</file>
<file xil_pn:name="src/Common/Mux4.v" xil_pn:type="FILE_VERILOG">
<association xil_pn:name="BehavioralSimulation" xil_pn:seqID="26"/>
<association xil_pn:name="Implementation" xil_pn:seqID="27"/>
</file>
<file xil_pn:name="src/Common/SRAM.v" xil_pn:type="FILE_VERILOG">
<association xil_pn:name="BehavioralSimulation" xil_pn:seqID="1"/>
<association xil_pn:name="Implementation" xil_pn:seqID="1"/>
</file>
<file xil_pn:name="src/I2C/I2C_Clock.v" xil_pn:type="FILE_VERILOG">
<association xil_pn:name="BehavioralSimulation" xil_pn:seqID="5"/>
<association xil_pn:name="Implementation" xil_pn:seqID="6"/>
</file>
<file xil_pn:name="src/I2C/I2C_Controller.v" xil_pn:type="FILE_VERILOG">
<association xil_pn:name="BehavioralSimulation" xil_pn:seqID="35"/>
<association xil_pn:name="Implementation" xil_pn:seqID="36"/>
</file>
<file xil_pn:name="src/I2C/I2C_Phy.v" xil_pn:type="FILE_VERILOG">
<association xil_pn:name="BehavioralSimulation" xil_pn:seqID="25"/>
<association xil_pn:name="Implementation" xil_pn:seqID="26"/>
</file>
<file xil_pn:name="src/MIPS32/Add.v" xil_pn:type="FILE_VERILOG">
<association xil_pn:name="BehavioralSimulation" xil_pn:seqID="23"/>
<association xil_pn:name="Implementation" xil_pn:seqID="24"/>
</file>
<file xil_pn:name="src/MIPS32/ALU.v" xil_pn:type="FILE_VERILOG">
<association xil_pn:name="BehavioralSimulation" xil_pn:seqID="22"/>
<association xil_pn:name="Implementation" xil_pn:seqID="23"/>
</file>
<file xil_pn:name="src/MIPS32/Compare.v" xil_pn:type="FILE_VERILOG">
<association xil_pn:name="BehavioralSimulation" xil_pn:seqID="21"/>
<association xil_pn:name="Implementation" xil_pn:seqID="22"/>
</file>
<file xil_pn:name="src/MIPS32/Control.v" xil_pn:type="FILE_VERILOG">
<association xil_pn:name="BehavioralSimulation" xil_pn:seqID="20"/>
<association xil_pn:name="Implementation" xil_pn:seqID="21"/>
</file>
<file xil_pn:name="src/MIPS32/CPZero.v" xil_pn:type="FILE_VERILOG">
<association xil_pn:name="BehavioralSimulation" xil_pn:seqID="19"/>
<association xil_pn:name="Implementation" xil_pn:seqID="20"/>
</file>
<file xil_pn:name="src/MIPS32/EXMEM_Stage.v" xil_pn:type="FILE_VERILOG">
<association xil_pn:name="BehavioralSimulation" xil_pn:seqID="18"/>
<association xil_pn:name="Implementation" xil_pn:seqID="19"/>
</file>
<file xil_pn:name="src/MIPS32/Hazard_Detection.v" xil_pn:type="FILE_VERILOG">
<association xil_pn:name="BehavioralSimulation" xil_pn:seqID="17"/>
<association xil_pn:name="Implementation" xil_pn:seqID="18"/>
</file>
<file xil_pn:name="src/MIPS32/IDEX_Stage.v" xil_pn:type="FILE_VERILOG">
<association xil_pn:name="BehavioralSimulation" xil_pn:seqID="16"/>
<association xil_pn:name="Implementation" xil_pn:seqID="17"/>
</file>
<file xil_pn:name="src/MIPS32/IFID_Stage.v" xil_pn:type="FILE_VERILOG">
<association xil_pn:name="BehavioralSimulation" xil_pn:seqID="15"/>
<association xil_pn:name="Implementation" xil_pn:seqID="16"/>
</file>
<file xil_pn:name="src/MIPS32/MemControl.v" xil_pn:type="FILE_VERILOG">
<association xil_pn:name="BehavioralSimulation" xil_pn:seqID="14"/>
<association xil_pn:name="Implementation" xil_pn:seqID="15"/>
</file>
<file xil_pn:name="src/MIPS32/MEMWB_Stage.v" xil_pn:type="FILE_VERILOG">
<association xil_pn:name="BehavioralSimulation" xil_pn:seqID="13"/>
<association xil_pn:name="Implementation" xil_pn:seqID="14"/>
</file>
<file xil_pn:name="src/MIPS32/Processor.v" xil_pn:type="FILE_VERILOG">
<association xil_pn:name="BehavioralSimulation" xil_pn:seqID="32"/>
<association xil_pn:name="Implementation" xil_pn:seqID="33"/>
</file>
<file xil_pn:name="src/MIPS32/Register.v" xil_pn:type="FILE_VERILOG">
<association xil_pn:name="BehavioralSimulation" xil_pn:seqID="12"/>
<association xil_pn:name="Implementation" xil_pn:seqID="13"/>
</file>
<file xil_pn:name="src/MIPS32/RegisterFile.v" xil_pn:type="FILE_VERILOG">
<association xil_pn:name="BehavioralSimulation" xil_pn:seqID="11"/>
<association xil_pn:name="Implementation" xil_pn:seqID="12"/>
</file>
<file xil_pn:name="src/MIPS32/TrapDetect.v" xil_pn:type="FILE_VERILOG">
<association xil_pn:name="BehavioralSimulation" xil_pn:seqID="10"/>
<association xil_pn:name="Implementation" xil_pn:seqID="11"/>
</file>
<file xil_pn:name="src/LED/LED.v" xil_pn:type="FILE_VERILOG">
<association xil_pn:name="BehavioralSimulation" xil_pn:seqID="33"/>
<association xil_pn:name="Implementation" xil_pn:seqID="34"/>
</file>
<file xil_pn:name="src/LCD/LCD.v" xil_pn:type="FILE_VERILOG">
<association xil_pn:name="BehavioralSimulation" xil_pn:seqID="34"/>
<association xil_pn:name="Implementation" xil_pn:seqID="35"/>
</file>
<file xil_pn:name="src/LCD/lcd_ctrl.v" xil_pn:type="FILE_VERILOG">
<association xil_pn:name="BehavioralSimulation" xil_pn:seqID="24"/>
<association xil_pn:name="Implementation" xil_pn:seqID="25"/>
</file>
<file xil_pn:name="src/Piezo/Piezo.v" xil_pn:type="FILE_VERILOG">
<association xil_pn:name="BehavioralSimulation" xil_pn:seqID="31"/>
<association xil_pn:name="Implementation" xil_pn:seqID="32"/>
</file>
<file xil_pn:name="src/Switches/Switch_Filter.v" xil_pn:type="FILE_VERILOG">
<association xil_pn:name="BehavioralSimulation" xil_pn:seqID="9"/>
<association xil_pn:name="Implementation" xil_pn:seqID="10"/>
</file>
<file xil_pn:name="src/Switches/Switches.v" xil_pn:type="FILE_VERILOG">
<association xil_pn:name="BehavioralSimulation" xil_pn:seqID="30"/>
<association xil_pn:name="Implementation" xil_pn:seqID="31"/>
</file>
<file xil_pn:name="src/BRAM/BRAM_592KB_Wrapper.v" xil_pn:type="FILE_VERILOG">
<association xil_pn:name="BehavioralSimulation" xil_pn:seqID="37"/>
<association xil_pn:name="Implementation" xil_pn:seqID="38"/>
</file>
<file xil_pn:name="src/Simulation/Top_Tester.v" xil_pn:type="FILE_VERILOG">
<association xil_pn:name="BehavioralSimulation" xil_pn:seqID="39"/>
<association xil_pn:name="PostMapSimulation" xil_pn:seqID="57"/>
<association xil_pn:name="PostRouteSimulation" xil_pn:seqID="57"/>
<association xil_pn:name="PostTranslateSimulation" xil_pn:seqID="57"/>
</file>
<file xil_pn:name="src/MIPS32/Divide.v" xil_pn:type="FILE_VERILOG">
<association xil_pn:name="BehavioralSimulation" xil_pn:seqID="49"/>
<association xil_pn:name="Implementation" xil_pn:seqID="5"/>
</file>
<file xil_pn:name="src/Clocks/PLL_100MHz_to_33MHz_66MHz.v" xil_pn:type="FILE_VERILOG">
<association xil_pn:name="BehavioralSimulation" xil_pn:seqID="62"/>
<association xil_pn:name="Implementation" xil_pn:seqID="37"/>
</file>
</files>
<properties>
<property xil_pn:name="AES Initial Vector virtex5" xil_pn:value="" xil_pn:valueState="default"/>
<property xil_pn:name="AES Key (Hex String)" xil_pn:value="" xil_pn:valueState="default"/>
<property xil_pn:name="Add I/O Buffers" xil_pn:value="true" xil_pn:valueState="default"/>
<property xil_pn:name="Allow Logic Optimization Across Hierarchy" xil_pn:value="true" xil_pn:valueState="non-default"/>
<property xil_pn:name="Allow SelectMAP Pins to Persist" xil_pn:value="false" xil_pn:valueState="default"/>
<property xil_pn:name="Allow Unexpanded Blocks" xil_pn:value="false" xil_pn:valueState="default"/>
<property xil_pn:name="Allow Unmatched LOC Constraints" xil_pn:value="false" xil_pn:valueState="default"/>
<property xil_pn:name="Allow Unmatched Timing Group Constraints" xil_pn:value="false" xil_pn:valueState="default"/>
<property xil_pn:name="Analysis Effort Level" xil_pn:value="Standard" xil_pn:valueState="default"/>
<property xil_pn:name="Asynchronous To Synchronous" xil_pn:value="false" xil_pn:valueState="default"/>
<property xil_pn:name="Auto Implementation Compile Order" xil_pn:value="true" xil_pn:valueState="default"/>
<property xil_pn:name="Auto Implementation Top" xil_pn:value="true" xil_pn:valueState="default"/>
<property xil_pn:name="Automatic BRAM Packing" xil_pn:value="false" xil_pn:valueState="default"/>
<property xil_pn:name="Automatically Insert glbl Module in the Netlist" xil_pn:value="true" xil_pn:valueState="default"/>
<property xil_pn:name="Automatically Run Generate Target PROM/ACE File" xil_pn:value="false" xil_pn:valueState="default"/>
<property xil_pn:name="BPI Reads Per Page" xil_pn:value="1" xil_pn:valueState="default"/>
<property xil_pn:name="BRAM Utilization Ratio" xil_pn:value="100" xil_pn:valueState="default"/>
<property xil_pn:name="Bring Out Global Set/Reset Net as a Port" xil_pn:value="false" xil_pn:valueState="default"/>
<property xil_pn:name="Bring Out Global Tristate Net as a Port" xil_pn:value="false" xil_pn:valueState="default"/>
<property xil_pn:name="Bus Delimiter" xil_pn:value="&lt;>" xil_pn:valueState="default"/>
<property xil_pn:name="Case" xil_pn:value="Maintain" xil_pn:valueState="default"/>
<property xil_pn:name="Case Implementation Style" xil_pn:value="None" xil_pn:valueState="default"/>
<property xil_pn:name="Change Device Speed To" xil_pn:value="-1" xil_pn:valueState="default"/>
<property xil_pn:name="Change Device Speed To Post Trace" xil_pn:value="-1" xil_pn:valueState="default"/>
<property xil_pn:name="Combinatorial Logic Optimization" xil_pn:value="true" xil_pn:valueState="non-default"/>
<property xil_pn:name="Compile EDK Simulation Library" xil_pn:value="true" xil_pn:valueState="default"/>
<property xil_pn:name="Compile SIMPRIM (Timing) Simulation Library" xil_pn:value="true" xil_pn:valueState="default"/>
<property xil_pn:name="Compile UNISIM (Functional) Simulation Library" xil_pn:value="true" xil_pn:valueState="default"/>
<property xil_pn:name="Compile XilinxCoreLib (CORE Generator) Simulation Library" xil_pn:value="true" xil_pn:valueState="default"/>
<property xil_pn:name="Compile for HDL Debugging" xil_pn:value="true" xil_pn:valueState="default"/>
<property xil_pn:name="Configuration Clk (Configuration Pins)" xil_pn:value="Pull Up" xil_pn:valueState="default"/>
<property xil_pn:name="Configuration Pin Busy" xil_pn:value="Pull Up" xil_pn:valueState="default"/>
<property xil_pn:name="Configuration Pin CS" xil_pn:value="Pull Up" xil_pn:valueState="default"/>
<property xil_pn:name="Configuration Pin DIn" xil_pn:value="Pull Up" xil_pn:valueState="default"/>
<property xil_pn:name="Configuration Pin Done" xil_pn:value="Pull Up" xil_pn:valueState="default"/>
<property xil_pn:name="Configuration Pin HSWAPEN" xil_pn:value="Pull Up" xil_pn:valueState="default"/>
<property xil_pn:name="Configuration Pin Init" xil_pn:value="Pull Up" xil_pn:valueState="default"/>
<property xil_pn:name="Configuration Pin M0" xil_pn:value="Pull Up" xil_pn:valueState="default"/>
<property xil_pn:name="Configuration Pin M1" xil_pn:value="Pull Up" xil_pn:valueState="default"/>
<property xil_pn:name="Configuration Pin M2" xil_pn:value="Pull Up" xil_pn:valueState="default"/>
<property xil_pn:name="Configuration Pin Program" xil_pn:value="Pull Up" xil_pn:valueState="default"/>
<property xil_pn:name="Configuration Pin RdWr" xil_pn:value="Pull Up" xil_pn:valueState="default"/>
<property xil_pn:name="Configuration Rate virtex5" xil_pn:value="2" xil_pn:valueState="default"/>
<property xil_pn:name="Correlate Output to Input Design" xil_pn:value="false" xil_pn:valueState="default"/>
<property xil_pn:name="Create ASCII Configuration File" xil_pn:value="false" xil_pn:valueState="default"/>
<property xil_pn:name="Create Binary Configuration File" xil_pn:value="false" xil_pn:valueState="default"/>
<property xil_pn:name="Create Bit File" xil_pn:value="true" xil_pn:valueState="default"/>
<property xil_pn:name="Create I/O Pads from Ports" xil_pn:value="false" xil_pn:valueState="default"/>
<property xil_pn:name="Create IEEE 1532 Configuration File" xil_pn:value="false" xil_pn:valueState="default"/>
<property xil_pn:name="Create Logic Allocation File" xil_pn:value="false" xil_pn:valueState="default"/>
<property xil_pn:name="Create Mask File" xil_pn:value="false" xil_pn:valueState="default"/>
<property xil_pn:name="Create ReadBack Data Files" xil_pn:value="false" xil_pn:valueState="default"/>
<property xil_pn:name="Cross Clock Analysis" xil_pn:value="false" xil_pn:valueState="default"/>
<property xil_pn:name="Custom Waveform Configuration File Behav" xil_pn:value="src/Simulation/waveform.wcfg" xil_pn:valueState="non-default"/>
<property xil_pn:name="Cycles for First BPI Page Read" xil_pn:value="1" xil_pn:valueState="default"/>
<property xil_pn:name="DCI Update Mode" xil_pn:value="As Required" xil_pn:valueState="default"/>
<property xil_pn:name="DSP Utilization Ratio" xil_pn:value="100" xil_pn:valueState="default"/>
<property xil_pn:name="Decoder Extraction" xil_pn:value="true" xil_pn:valueState="default"/>
<property xil_pn:name="Delay Values To Be Read from SDF" xil_pn:value="Setup Time" xil_pn:valueState="default"/>
<property xil_pn:name="Device" xil_pn:value="xc5vlx110t" xil_pn:valueState="non-default"/>
<property xil_pn:name="Device Family" xil_pn:value="Virtex5" xil_pn:valueState="non-default"/>
<property xil_pn:name="Device Speed Grade/Select ABS Minimum" xil_pn:value="-1" xil_pn:valueState="default"/>
<property xil_pn:name="Disable Detailed Package Model Insertion" xil_pn:value="false" xil_pn:valueState="default"/>
<property xil_pn:name="Do Not Escape Signal and Instance Names in Netlist" xil_pn:value="false" xil_pn:valueState="default"/>
<property xil_pn:name="Done (Output Events)" xil_pn:value="Default (4)" xil_pn:valueState="default"/>
<property xil_pn:name="Drive Done Pin High" xil_pn:value="false" xil_pn:valueState="default"/>
<property xil_pn:name="Enable BitStream Compression" xil_pn:value="false" xil_pn:valueState="default"/>
<property xil_pn:name="Enable Cyclic Redundancy Checking (CRC)" xil_pn:value="true" xil_pn:valueState="default"/>
<property xil_pn:name="Enable Debugging of Serial Mode BitStream" xil_pn:value="false" xil_pn:valueState="default"/>
<property xil_pn:name="Enable Hardware Co-Simulation" xil_pn:value="false" xil_pn:valueState="default"/>
<property xil_pn:name="Enable Internal Done Pipe" xil_pn:value="true" xil_pn:valueState="non-default"/>
<property xil_pn:name="Enable Message Filtering" xil_pn:value="false" xil_pn:valueState="default"/>
<property xil_pn:name="Enable Multi-Threading" xil_pn:value="2" xil_pn:valueState="non-default"/>
<property xil_pn:name="Enable Multi-Threading par virtex5" xil_pn:value="4" xil_pn:valueState="non-default"/>
<property xil_pn:name="Enable Outputs (Output Events)" xil_pn:value="Default (5)" xil_pn:valueState="default"/>
<property xil_pn:name="Encrypt Bitstream" xil_pn:value="false" xil_pn:valueState="default"/>
<property xil_pn:name="Equivalent Register Removal" xil_pn:value="true" xil_pn:valueState="default"/>
<property xil_pn:name="Equivalent Register Removal XST" xil_pn:value="true" xil_pn:valueState="default"/>
<property xil_pn:name="Essential Bits" xil_pn:value="false" xil_pn:valueState="default"/>
<property xil_pn:name="Evaluation Development Board" xil_pn:value="None Specified" xil_pn:valueState="default"/>
<property xil_pn:name="Exclude Compilation of Deprecated EDK Cores" xil_pn:value="true" xil_pn:valueState="default"/>
<property xil_pn:name="Exclude Compilation of EDK Sub-Libraries" xil_pn:value="false" xil_pn:valueState="default"/>
<property xil_pn:name="Extra Effort (Highest PAR level only)" xil_pn:value="Normal" xil_pn:valueState="non-default"/>
<property xil_pn:name="FPGA Start-Up Clock" xil_pn:value="CCLK" xil_pn:valueState="default"/>
<property xil_pn:name="FSM Encoding Algorithm" xil_pn:value="Auto" xil_pn:valueState="default"/>
<property xil_pn:name="FSM Style" xil_pn:value="LUT" xil_pn:valueState="default"/>
<property xil_pn:name="Fallback Reconfiguration" xil_pn:value="Enable" xil_pn:valueState="default"/>
<property xil_pn:name="Filter Files From Compile Order" xil_pn:value="true" xil_pn:valueState="default"/>
<property xil_pn:name="Flatten Output Netlist" xil_pn:value="false" xil_pn:valueState="default"/>
<property xil_pn:name="Functional Model Target Language ArchWiz" xil_pn:value="Verilog" xil_pn:valueState="default"/>
<property xil_pn:name="Functional Model Target Language Coregen" xil_pn:value="Verilog" xil_pn:valueState="default"/>
<property xil_pn:name="Functional Model Target Language Schematic" xil_pn:value="Verilog" xil_pn:valueState="default"/>
<property xil_pn:name="Generate Architecture Only (No Entity Declaration)" xil_pn:value="false" xil_pn:valueState="default"/>
<property xil_pn:name="Generate Asynchronous Delay Report" xil_pn:value="false" xil_pn:valueState="default"/>
<property xil_pn:name="Generate Clock Region Report" xil_pn:value="false" xil_pn:valueState="default"/>
<property xil_pn:name="Generate Constraints Interaction Report" xil_pn:value="false" xil_pn:valueState="default"/>
<property xil_pn:name="Generate Constraints Interaction Report Post Trace" xil_pn:value="false" xil_pn:valueState="default"/>
<property xil_pn:name="Generate Datasheet Section" xil_pn:value="true" xil_pn:valueState="default"/>
<property xil_pn:name="Generate Datasheet Section Post Trace" xil_pn:value="true" xil_pn:valueState="default"/>
<property xil_pn:name="Generate Detailed MAP Report" xil_pn:value="false" xil_pn:valueState="default"/>
<property xil_pn:name="Generate Multiple Hierarchical Netlist Files" xil_pn:value="false" xil_pn:valueState="default"/>
<property xil_pn:name="Generate Post-Place &amp; Route Power Report" xil_pn:value="false" xil_pn:valueState="default"/>
<property xil_pn:name="Generate Post-Place &amp; Route Simulation Model" xil_pn:value="false" xil_pn:valueState="default"/>
<property xil_pn:name="Generate RTL Schematic" xil_pn:value="Yes" xil_pn:valueState="default"/>
<property xil_pn:name="Generate SAIF File for Power Optimization/Estimation Par" xil_pn:value="false" xil_pn:valueState="default"/>
<property xil_pn:name="Generate Testbench File" xil_pn:value="false" xil_pn:valueState="default"/>
<property xil_pn:name="Generate Timegroups Section" xil_pn:value="false" xil_pn:valueState="default"/>
<property xil_pn:name="Generate Timegroups Section Post Trace" xil_pn:value="false" xil_pn:valueState="default"/>
<property xil_pn:name="Generics, Parameters" xil_pn:value="" xil_pn:valueState="default"/>
<property xil_pn:name="Global Optimization Goal" xil_pn:value="AllClockNets" xil_pn:valueState="default"/>
<property xil_pn:name="Global Optimization map virtex5" xil_pn:value="Speed" xil_pn:valueState="non-default"/>
<property xil_pn:name="Global Set/Reset Port Name" xil_pn:value="GSR_PORT" xil_pn:valueState="default"/>
<property xil_pn:name="Global Tristate Port Name" xil_pn:value="GTS_PORT" xil_pn:valueState="default"/>
<property xil_pn:name="HDL Instantiation Template Target Language" xil_pn:value="Verilog" xil_pn:valueState="default"/>
<property xil_pn:name="Hierarchy Separator" xil_pn:value="/" xil_pn:valueState="default"/>
<property xil_pn:name="ISim UUT Instance Name" xil_pn:value="UUT" xil_pn:valueState="default"/>
<property xil_pn:name="Ignore User Timing Constraints Map" xil_pn:value="false" xil_pn:valueState="default"/>
<property xil_pn:name="Ignore User Timing Constraints Par" xil_pn:value="false" xil_pn:valueState="default"/>
<property xil_pn:name="Implementation Top" xil_pn:value="Module|Top" xil_pn:valueState="non-default"/>
<property xil_pn:name="Implementation Top File" xil_pn:value="src/Top.v" xil_pn:valueState="non-default"/>
<property xil_pn:name="Implementation Top Instance Path" xil_pn:value="/Top" xil_pn:valueState="non-default"/>
<property xil_pn:name="Include 'uselib Directive in Verilog File" xil_pn:value="false" xil_pn:valueState="default"/>
<property xil_pn:name="Include SIMPRIM Models in Verilog File" xil_pn:value="false" xil_pn:valueState="default"/>
<property xil_pn:name="Include UNISIM Models in Verilog File" xil_pn:value="false" xil_pn:valueState="default"/>
<property xil_pn:name="Include sdf_annotate task in Verilog File" xil_pn:value="true" xil_pn:valueState="default"/>
<property xil_pn:name="Incremental Compilation" xil_pn:value="true" xil_pn:valueState="default"/>
<property xil_pn:name="Insert Buffers to Prevent Pulse Swallowing" xil_pn:value="true" xil_pn:valueState="default"/>
<property xil_pn:name="Instantiation Template Target Language Xps" xil_pn:value="Verilog" xil_pn:valueState="default"/>
<property xil_pn:name="JTAG Pin TCK" xil_pn:value="Pull Up" xil_pn:valueState="default"/>
<property xil_pn:name="JTAG Pin TDI" xil_pn:value="Pull Up" xil_pn:valueState="default"/>
<property xil_pn:name="JTAG Pin TDO" xil_pn:value="Pull Up" xil_pn:valueState="default"/>
<property xil_pn:name="JTAG Pin TMS" xil_pn:value="Pull Up" xil_pn:valueState="default"/>
<property xil_pn:name="JTAG to System Monitor Connection" xil_pn:value="Enable" xil_pn:valueState="default"/>
<property xil_pn:name="Keep Hierarchy" xil_pn:value="No" xil_pn:valueState="default"/>
<property xil_pn:name="LUT Combining Map" xil_pn:value="Auto" xil_pn:valueState="non-default"/>
<property xil_pn:name="LUT Combining Xst" xil_pn:value="Auto" xil_pn:valueState="non-default"/>
<property xil_pn:name="Language" xil_pn:value="VHDL" xil_pn:valueState="default"/>
<property xil_pn:name="Last Applied Goal" xil_pn:value="Balanced" xil_pn:valueState="default"/>
<property xil_pn:name="Last Applied Strategy" xil_pn:value="Xilinx Default (unlocked)" xil_pn:valueState="default"/>
<property xil_pn:name="Last Unlock Status" xil_pn:value="false" xil_pn:valueState="default"/>
<property xil_pn:name="Launch SDK after Export" xil_pn:value="true" xil_pn:valueState="default"/>
<property xil_pn:name="Library for Verilog Sources" xil_pn:value="" xil_pn:valueState="default"/>
<property xil_pn:name="Load glbl" xil_pn:value="true" xil_pn:valueState="default"/>
<property xil_pn:name="Logical Shifter Extraction" xil_pn:value="true" xil_pn:valueState="default"/>
<property xil_pn:name="Manual Implementation Compile Order" xil_pn:value="false" xil_pn:valueState="default"/>
<property xil_pn:name="Map Slice Logic into Unused Block RAMs" xil_pn:value="false" xil_pn:valueState="default"/>
<property xil_pn:name="Max Fanout" xil_pn:value="100000" xil_pn:valueState="default"/>
<property xil_pn:name="Maximum Compression" xil_pn:value="false" xil_pn:valueState="default"/>
<property xil_pn:name="Maximum Number of Lines in Report" xil_pn:value="1000" xil_pn:valueState="default"/>
<property xil_pn:name="Maximum Signal Name Length" xil_pn:value="20" xil_pn:valueState="default"/>
<property xil_pn:name="Move First Flip-Flop Stage" xil_pn:value="true" xil_pn:valueState="default"/>
<property xil_pn:name="Move Last Flip-Flop Stage" xil_pn:value="true" xil_pn:valueState="default"/>
<property xil_pn:name="Mux Extraction" xil_pn:value="Yes" xil_pn:valueState="default"/>
<property xil_pn:name="Mux Style" xil_pn:value="Auto" xil_pn:valueState="default"/>
<property xil_pn:name="Netlist Hierarchy" xil_pn:value="As Optimized" xil_pn:valueState="default"/>
<property xil_pn:name="Netlist Translation Type" xil_pn:value="Timestamp" xil_pn:valueState="default"/>
<property xil_pn:name="Number of Clock Buffers" xil_pn:value="32" xil_pn:valueState="default"/>
<property xil_pn:name="Number of Paths in Error/Verbose Report" xil_pn:value="3" xil_pn:valueState="default"/>
<property xil_pn:name="Number of Paths in Error/Verbose Report Post Trace" xil_pn:value="3" xil_pn:valueState="default"/>
<property xil_pn:name="Optimization Effort" xil_pn:value="High" xil_pn:valueState="non-default"/>
<property xil_pn:name="Optimization Goal" xil_pn:value="Speed" xil_pn:valueState="default"/>
<property xil_pn:name="Optimization Strategy (Cover Mode)" xil_pn:value="Speed" xil_pn:valueState="non-default"/>
<property xil_pn:name="Optimize Instantiated Primitives" xil_pn:value="true" xil_pn:valueState="non-default"/>
<property xil_pn:name="Other Bitgen Command Line Options" xil_pn:value="" xil_pn:valueState="default"/>
<property xil_pn:name="Other Compiler Options" xil_pn:value="" xil_pn:valueState="default"/>
<property xil_pn:name="Other Compiler Options Map" xil_pn:value="" xil_pn:valueState="default"/>
<property xil_pn:name="Other Compiler Options Par" xil_pn:value="" xil_pn:valueState="default"/>
<property xil_pn:name="Other Compiler Options Translate" xil_pn:value="" xil_pn:valueState="default"/>
<property xil_pn:name="Other Compxlib Command Line Options" xil_pn:value="" xil_pn:valueState="default"/>
<property xil_pn:name="Other Map Command Line Options" xil_pn:value="" xil_pn:valueState="default"/>
<property xil_pn:name="Other NETGEN Command Line Options" xil_pn:value="" xil_pn:valueState="default"/>
<property xil_pn:name="Other Ngdbuild Command Line Options" xil_pn:value="" xil_pn:valueState="default"/>
<property xil_pn:name="Other Place &amp; Route Command Line Options" xil_pn:value="" xil_pn:valueState="default"/>
<property xil_pn:name="Other Simulator Commands Behavioral" xil_pn:value="" xil_pn:valueState="default"/>
<property xil_pn:name="Other Simulator Commands Post-Map" xil_pn:value="" xil_pn:valueState="default"/>
<property xil_pn:name="Other Simulator Commands Post-Route" xil_pn:value="" xil_pn:valueState="default"/>
<property xil_pn:name="Other Simulator Commands Post-Translate" xil_pn:value="" xil_pn:valueState="default"/>
<property xil_pn:name="Other XPWR Command Line Options" xil_pn:value="" xil_pn:valueState="default"/>
<property xil_pn:name="Other XST Command Line Options" xil_pn:value="" xil_pn:valueState="default"/>
<property xil_pn:name="Output Extended Identifiers" xil_pn:value="false" xil_pn:valueState="default"/>
<property xil_pn:name="Output File Name" xil_pn:value="Top" xil_pn:valueState="default"/>
<property xil_pn:name="Overwrite Compiled Libraries" xil_pn:value="false" xil_pn:valueState="default"/>
<property xil_pn:name="Pack I/O Registers into IOBs" xil_pn:value="Auto" xil_pn:valueState="default"/>
<property xil_pn:name="Pack I/O Registers/Latches into IOBs" xil_pn:value="Off" xil_pn:valueState="default"/>
<property xil_pn:name="Package" xil_pn:value="ff1136" xil_pn:valueState="default"/>
<property xil_pn:name="Perform Advanced Analysis" xil_pn:value="false" xil_pn:valueState="default"/>
<property xil_pn:name="Perform Advanced Analysis Post Trace" xil_pn:value="false" xil_pn:valueState="default"/>
<property xil_pn:name="Perform Timing-Driven Packing and Placement" xil_pn:value="false" xil_pn:valueState="default"/>
<property xil_pn:name="Place &amp; Route Effort Level (Overall)" xil_pn:value="High" xil_pn:valueState="default"/>
<property xil_pn:name="Place And Route Mode" xil_pn:value="Route Only" xil_pn:valueState="default"/>
<property xil_pn:name="Placer Effort Level Map" xil_pn:value="High" xil_pn:valueState="default"/>
<property xil_pn:name="Placer Extra Effort Map" xil_pn:value="Normal" xil_pn:valueState="non-default"/>
<property xil_pn:name="Port to be used" xil_pn:value="Auto - default" xil_pn:valueState="default"/>
<property xil_pn:name="Post Map Simulation Model Name" xil_pn:value="Top_map.v" xil_pn:valueState="default"/>
<property xil_pn:name="Post Place &amp; Route Simulation Model Name" xil_pn:value="Top_timesim.v" xil_pn:valueState="default"/>
<property xil_pn:name="Post Synthesis Simulation Model Name" xil_pn:value="Top_synthesis.v" xil_pn:valueState="default"/>
<property xil_pn:name="Post Translate Simulation Model Name" xil_pn:value="Top_translate.v" xil_pn:valueState="default"/>
<property xil_pn:name="Power Down Device if Over Safe Temperature" xil_pn:value="false" xil_pn:valueState="default"/>
<property xil_pn:name="Power Reduction Map" xil_pn:value="false" xil_pn:valueState="default"/>
<property xil_pn:name="Power Reduction Par" xil_pn:value="false" xil_pn:valueState="default"/>
<property xil_pn:name="Power Reduction Xst" xil_pn:value="false" xil_pn:valueState="default"/>
<property xil_pn:name="Preferred Language" xil_pn:value="Verilog" xil_pn:valueState="default"/>
<property xil_pn:name="Priority Encoder Extraction" xil_pn:value="Yes" xil_pn:valueState="default"/>
<property xil_pn:name="Produce Verbose Report" xil_pn:value="false" xil_pn:valueState="default"/>
<property xil_pn:name="Project Description" xil_pn:value="" xil_pn:valueState="default"/>
<property xil_pn:name="Property Specification in Project File" xil_pn:value="Store all values" xil_pn:valueState="default"/>
<property xil_pn:name="RAM Extraction" xil_pn:value="true" xil_pn:valueState="default"/>
<property xil_pn:name="RAM Style" xil_pn:value="Auto" xil_pn:valueState="default"/>
<property xil_pn:name="ROM Extraction" xil_pn:value="true" xil_pn:valueState="default"/>
<property xil_pn:name="ROM Style" xil_pn:value="Auto" xil_pn:valueState="default"/>
<property xil_pn:name="Read Cores" xil_pn:value="true" xil_pn:valueState="default"/>
<property xil_pn:name="Reduce Control Sets" xil_pn:value="Auto" xil_pn:valueState="non-default"/>
<property xil_pn:name="Regenerate Core" xil_pn:value="Under Current Project Setting" xil_pn:valueState="default"/>
<property xil_pn:name="Register Balancing" xil_pn:value="No" xil_pn:valueState="default"/>
<property xil_pn:name="Register Duplication Map" xil_pn:value="Off" xil_pn:valueState="default"/>
<property xil_pn:name="Register Duplication Xst" xil_pn:value="true" xil_pn:valueState="default"/>
<property xil_pn:name="Release Write Enable (Output Events)" xil_pn:value="Default (6)" xil_pn:valueState="default"/>
<property xil_pn:name="Rename Design Instance in Testbench File to" xil_pn:value="UUT" xil_pn:valueState="default"/>
<property xil_pn:name="Rename Top Level Architecture To" xil_pn:value="Structure" xil_pn:valueState="default"/>
<property xil_pn:name="Rename Top Level Entity to" xil_pn:value="" xil_pn:valueState="default"/>
<property xil_pn:name="Rename Top Level Module To" xil_pn:value="" xil_pn:valueState="default"/>
<property xil_pn:name="Report Fastest Path(s) in Each Constraint" xil_pn:value="true" xil_pn:valueState="default"/>
<property xil_pn:name="Report Fastest Path(s) in Each Constraint Post Trace" xil_pn:value="true" xil_pn:valueState="default"/>
<property xil_pn:name="Report Paths by Endpoint" xil_pn:value="3" xil_pn:valueState="default"/>
<property xil_pn:name="Report Paths by Endpoint Post Trace" xil_pn:value="3" xil_pn:valueState="default"/>
<property xil_pn:name="Report Type" xil_pn:value="Verbose Report" xil_pn:valueState="default"/>
<property xil_pn:name="Report Type Post Trace" xil_pn:value="Verbose Report" xil_pn:valueState="default"/>
<property xil_pn:name="Report Unconstrained Paths" xil_pn:value="" xil_pn:valueState="default"/>
<property xil_pn:name="Report Unconstrained Paths Post Trace" xil_pn:value="" xil_pn:valueState="default"/>
<property xil_pn:name="Reset On Configuration Pulse Width" xil_pn:value="100" xil_pn:valueState="default"/>
<property xil_pn:name="Resource Sharing" xil_pn:value="true" xil_pn:valueState="default"/>
<property xil_pn:name="Retain Hierarchy" xil_pn:value="true" xil_pn:valueState="default"/>
<property xil_pn:name="Revision Select" xil_pn:value="00" xil_pn:valueState="default"/>
<property xil_pn:name="Revision Select Tristate" xil_pn:value="Disable" xil_pn:valueState="default"/>
<property xil_pn:name="Run Design Rules Checker (DRC)" xil_pn:value="true" xil_pn:valueState="default"/>
<property xil_pn:name="Run for Specified Time" xil_pn:value="true" xil_pn:valueState="default"/>
<property xil_pn:name="Run for Specified Time Map" xil_pn:value="true" xil_pn:valueState="default"/>
<property xil_pn:name="Run for Specified Time Par" xil_pn:value="true" xil_pn:valueState="default"/>
<property xil_pn:name="Run for Specified Time Translate" xil_pn:value="true" xil_pn:valueState="default"/>
<property xil_pn:name="Safe Implementation" xil_pn:value="No" xil_pn:valueState="default"/>
<property xil_pn:name="Security" xil_pn:value="Enable Readback and Reconfiguration" xil_pn:valueState="default"/>
<property xil_pn:name="SelectMAP Abort Sequence" xil_pn:value="Enable" xil_pn:valueState="default"/>
<property xil_pn:name="Selected Module Instance Name" xil_pn:value="/Top_Tester" xil_pn:valueState="non-default"/>
<property xil_pn:name="Selected Simulation Root Source Node Behavioral" xil_pn:value="work.Top_Tester" xil_pn:valueState="non-default"/>
<property xil_pn:name="Selected Simulation Root Source Node Post-Map" xil_pn:value="" xil_pn:valueState="default"/>
<property xil_pn:name="Selected Simulation Root Source Node Post-Route" xil_pn:value="" xil_pn:valueState="default"/>
<property xil_pn:name="Selected Simulation Root Source Node Post-Translate" xil_pn:value="" xil_pn:valueState="default"/>
<property xil_pn:name="Selected Simulation Source Node" xil_pn:value="UUT" xil_pn:valueState="default"/>
<property xil_pn:name="Shift Register Extraction" xil_pn:value="true" xil_pn:valueState="default"/>
<property xil_pn:name="Show All Models" xil_pn:value="false" xil_pn:valueState="default"/>
<property xil_pn:name="Simulation Model Target" xil_pn:value="Verilog" xil_pn:valueState="default"/>
<property xil_pn:name="Simulation Run Time ISim" xil_pn:value="1000 ns" xil_pn:valueState="default"/>
<property xil_pn:name="Simulation Run Time Map" xil_pn:value="1000 ns" xil_pn:valueState="default"/>
<property xil_pn:name="Simulation Run Time Par" xil_pn:value="1000 ns" xil_pn:valueState="default"/>
<property xil_pn:name="Simulation Run Time Translate" xil_pn:value="1000 ns" xil_pn:valueState="default"/>
<property xil_pn:name="Simulator" xil_pn:value="ISim (VHDL/Verilog)" xil_pn:valueState="default"/>
<property xil_pn:name="Slice Packing" xil_pn:value="true" xil_pn:valueState="default"/>
<property xil_pn:name="Slice Utilization Ratio" xil_pn:value="100" xil_pn:valueState="default"/>
<property xil_pn:name="Specify 'define Macro Name and Value" xil_pn:value="" xil_pn:valueState="default"/>
<property xil_pn:name="Specify Top Level Instance Names Behavioral" xil_pn:value="work.Top_Tester" xil_pn:valueState="default"/>
<property xil_pn:name="Specify Top Level Instance Names Post-Map" xil_pn:value="Default" xil_pn:valueState="default"/>
<property xil_pn:name="Specify Top Level Instance Names Post-Route" xil_pn:value="Default" xil_pn:valueState="default"/>
<property xil_pn:name="Specify Top Level Instance Names Post-Translate" xil_pn:value="Default" xil_pn:valueState="default"/>
<property xil_pn:name="Speed Grade" xil_pn:value="-1" xil_pn:valueState="non-default"/>
<property xil_pn:name="Starting Placer Cost Table (1-100)" xil_pn:value="1" xil_pn:valueState="default"/>
<property xil_pn:name="Synthesis Tool" xil_pn:value="XST (VHDL/Verilog)" xil_pn:valueState="default"/>
<property xil_pn:name="Target Simulator" xil_pn:value="Please Specify" xil_pn:valueState="default"/>
<property xil_pn:name="Timing Mode Map" xil_pn:value="Performance Evaluation" xil_pn:valueState="default"/>
<property xil_pn:name="Timing Mode Par" xil_pn:value="Performance Evaluation" xil_pn:valueState="default"/>
<property xil_pn:name="Top-Level Module Name in Output Netlist" xil_pn:value="" xil_pn:valueState="default"/>
<property xil_pn:name="Top-Level Source Type" xil_pn:value="HDL" xil_pn:valueState="default"/>
<property xil_pn:name="Trim Unconnected Signals" xil_pn:value="true" xil_pn:valueState="default"/>
<property xil_pn:name="Tristate On Configuration Pulse Width" xil_pn:value="0" xil_pn:valueState="default"/>
<property xil_pn:name="Unused IOB Pins" xil_pn:value="Pull Down" xil_pn:valueState="default"/>
<property xil_pn:name="Use 64-bit PlanAhead on 64-bit Systems" xil_pn:value="true" xil_pn:valueState="default"/>
<property xil_pn:name="Use Clock Enable" xil_pn:value="Auto" xil_pn:valueState="default"/>
<property xil_pn:name="Use Custom Project File Behavioral" xil_pn:value="false" xil_pn:valueState="default"/>
<property xil_pn:name="Use Custom Project File Post-Map" xil_pn:value="false" xil_pn:valueState="default"/>
<property xil_pn:name="Use Custom Project File Post-Route" xil_pn:value="false" xil_pn:valueState="default"/>
<property xil_pn:name="Use Custom Project File Post-Translate" xil_pn:value="false" xil_pn:valueState="default"/>
<property xil_pn:name="Use Custom Simulation Command File Behavioral" xil_pn:value="false" xil_pn:valueState="default"/>
<property xil_pn:name="Use Custom Simulation Command File Map" xil_pn:value="false" xil_pn:valueState="default"/>
<property xil_pn:name="Use Custom Simulation Command File Par" xil_pn:value="false" xil_pn:valueState="default"/>
<property xil_pn:name="Use Custom Simulation Command File Translate" xil_pn:value="false" xil_pn:valueState="default"/>
<property xil_pn:name="Use Custom Waveform Configuration File Behav" xil_pn:value="true" xil_pn:valueState="non-default"/>
<property xil_pn:name="Use Custom Waveform Configuration File Map" xil_pn:value="false" xil_pn:valueState="default"/>
<property xil_pn:name="Use Custom Waveform Configuration File Par" xil_pn:value="false" xil_pn:valueState="default"/>
<property xil_pn:name="Use Custom Waveform Configuration File Translate" xil_pn:value="false" xil_pn:valueState="default"/>
<property xil_pn:name="Use DSP Block" xil_pn:value="Auto" xil_pn:valueState="default"/>
<property xil_pn:name="Use LOC Constraints" xil_pn:value="true" xil_pn:valueState="default"/>
<property xil_pn:name="Use RLOC Constraints" xil_pn:value="Yes" xil_pn:valueState="default"/>
<property xil_pn:name="Use Smart Guide" xil_pn:value="false" xil_pn:valueState="default"/>
<property xil_pn:name="Use Synchronous Reset" xil_pn:value="Auto" xil_pn:valueState="default"/>
<property xil_pn:name="Use Synchronous Set" xil_pn:value="Auto" xil_pn:valueState="default"/>
<property xil_pn:name="Use Synthesis Constraints File" xil_pn:value="true" xil_pn:valueState="default"/>
<property xil_pn:name="User Access Register Value" xil_pn:value="None" xil_pn:valueState="default"/>
<property xil_pn:name="User Browsed Strategy Files" xil_pn:value="" xil_pn:valueState="default"/>
<property xil_pn:name="UserID Code (8 Digit Hexadecimal)" xil_pn:value="0xFFFFFFFF" xil_pn:valueState="default"/>
<property xil_pn:name="VHDL Source Analysis Standard" xil_pn:value="VHDL-93" xil_pn:valueState="default"/>
<property xil_pn:name="Value Range Check" xil_pn:value="false" xil_pn:valueState="default"/>
<property xil_pn:name="Verilog 2001 Xst" xil_pn:value="true" xil_pn:valueState="default"/>
<property xil_pn:name="Verilog Macros" xil_pn:value="" xil_pn:valueState="default"/>
<property xil_pn:name="Wait for DCI Match (Output Events) virtex5" xil_pn:value="Auto" xil_pn:valueState="default"/>
<property xil_pn:name="Wait for DLL Lock (Output Events) virtex5" xil_pn:value="Default (NoWait)" xil_pn:valueState="default"/>
<property xil_pn:name="Watchdog Timer Mode virtex5" xil_pn:value="Off" xil_pn:valueState="default"/>
<property xil_pn:name="Watchdog Timer Value virtex5" xil_pn:value="0x000000" xil_pn:valueState="default"/>
<property xil_pn:name="Working Directory" xil_pn:value="." xil_pn:valueState="non-default"/>
<property xil_pn:name="Write Timing Constraints" xil_pn:value="false" xil_pn:valueState="default"/>
<property xil_pn:name="XOR Collapsing" xil_pn:value="true" xil_pn:valueState="default"/>
<!-- -->
<!-- The following properties are for internal use only. These should not be modified.-->
<!-- -->
<property xil_pn:name="PROP_BehavioralSimTop" xil_pn:value="Module|Top_Tester" xil_pn:valueState="non-default"/>
<property xil_pn:name="PROP_DesignName" xil_pn:value="MIPS32-Pipelined-Hw" xil_pn:valueState="non-default"/>
<property xil_pn:name="PROP_DevFamilyPMName" xil_pn:value="virtex5" xil_pn:valueState="default"/>
<property xil_pn:name="PROP_FPGAConfiguration" xil_pn:value="FPGAConfiguration" xil_pn:valueState="default"/>
<property xil_pn:name="PROP_PostMapSimTop" xil_pn:value="" xil_pn:valueState="default"/>
<property xil_pn:name="PROP_PostParSimTop" xil_pn:value="" xil_pn:valueState="default"/>
<property xil_pn:name="PROP_PostSynthSimTop" xil_pn:value="" xil_pn:valueState="default"/>
<property xil_pn:name="PROP_PostXlateSimTop" xil_pn:value="" xil_pn:valueState="default"/>
<property xil_pn:name="PROP_PreSynthesis" xil_pn:value="PreSynthesis" xil_pn:valueState="default"/>
<property xil_pn:name="PROP_intProjectCreationTimestamp" xil_pn:value="2012-09-08T00:00:44" xil_pn:valueState="non-default"/>
<property xil_pn:name="PROP_intWbtProjectID" xil_pn:value="AE9A2C604201437980E6BE5F7A73A833" xil_pn:valueState="non-default"/>
<property xil_pn:name="PROP_intWorkingDirLocWRTProjDir" xil_pn:value="Same" xil_pn:valueState="non-default"/>
<property xil_pn:name="PROP_intWorkingDirUsed" xil_pn:value="No" xil_pn:valueState="non-default"/>
</properties>
<bindings/>
<libraries/>
<autoManagedFiles>
<!-- The following files are identified by `include statements in verilog -->
<!-- source files and are automatically managed by Project Navigator. -->
<!-- -->
<!-- Do not hand-edit this section, as it will be overwritten when the -->
<!-- project is analyzed based on files automatically identified as -->
<!-- include files. -->
<file xil_pn:name="src/MIPS32/MIPS_Parameters.v" xil_pn:type="FILE_VERILOG"/>
</autoManagedFiles>
</project>
@@ -0,0 +1,8 @@
INTSTYLE=ise
INFILE=C:\root\Work\Gauss\opencores_svn\mips32r1\trunk\Hardware\XUPV5-LX110T_SoC\MIPS32-Pipelined-Hw\Top.ncd
OUTFILE=C:\root\Work\Gauss\opencores_svn\mips32r1\trunk\Hardware\XUPV5-LX110T_SoC\MIPS32-Pipelined-Hw\Top.bit
FAMILY=Virtex5
PART=xc5vlx110t-1ff1136
WORKINGDIR=C:\root\Work\Gauss\opencores_svn\mips32r1\trunk\Hardware\XUPV5-LX110T_SoC\MIPS32-Pipelined-Hw
LICENSE=ISE
USER_INFO=177303621_177303623_177303625_226
File diff suppressed because one or more lines are too long
@@ -0,0 +1,78 @@
<HTML><HEAD><TITLE>Xilinx Design Summary</TITLE></HEAD>
<BODY TEXT='#000000' BGCOLOR='#FFFFFF' LINK='#0000EE' VLINK='#551A8B' ALINK='#FF0000'>
<TABLE BORDER CELLSPACING=0 CELLPADDING=3 WIDTH='100%'>
<TR ALIGN=CENTER BGCOLOR='#99CCFF'>
<TD ALIGN=CENTER COLSPAN='4'><B>Top Project Status</B></TD></TR>
<TR ALIGN=LEFT>
<TD BGCOLOR='#FFFF99'><B>Project File:</B></TD>
<TD>MIPS32-Pipelined-Hw.xise</TD>
<TD BGCOLOR='#FFFF99'><b>Parser Errors:</b></TD>
</TR>
<TR ALIGN=LEFT>
<TD BGCOLOR='#FFFF99'><B>Module Name:</B></TD>
<TD>Top</TD>
<TD BGCOLOR='#FFFF99'><B>Implementation State:</B></TD>
<TD>New</TD>
</TR>
<TR ALIGN=LEFT>
<TD BGCOLOR='#FFFF99'><B>Target Device:</B></TD>
<TD>xc5vlx110t-1ff1136</TD>
<TD BGCOLOR='#FFFF99'><UL><LI><B>Errors:</B></LI></UL></TD>
<TD>&nbsp;</TD>
</TR>
<TR ALIGN=LEFT>
<TD BGCOLOR='#FFFF99'><B>Product Version:</B></TD><TD>ISE 14.1</TD>
<TD BGCOLOR='#FFFF99'><UL><LI><B>Warnings:</B></LI></UL></TD>
<TD>&nbsp;</TD>
</TR>
<TR ALIGN=LEFT>
<TD BGCOLOR='#FFFF99'><B>Design Goal:</B></dif></TD>
<TD>Balanced</TD>
<TD BGCOLOR='#FFFF99'><UL><LI><B>Routing Results:</B></LI></UL></TD>
<TD>
&nbsp;</TD>
</TR>
<TR ALIGN=LEFT>
<TD BGCOLOR='#FFFF99'><B>Design Strategy:</B></dif></TD>
<TD><A HREF_DISABLED='Xilinx Default (unlocked)?&DataKey=Strategy'>Xilinx Default (unlocked)</A></TD>
<TD BGCOLOR='#FFFF99'><UL><LI><B>Timing Constraints:</B></LI></UL></TD>
<TD>&nbsp;</TD>
</TR>
<TR ALIGN=LEFT>
<TD BGCOLOR='#FFFF99'><B>Environment:</B></dif></TD>
<TD>&nbsp;</TD>
<TD BGCOLOR='#FFFF99'><UL><LI><B>Final Timing Score:</B></LI></UL></TD>
<TD>&nbsp;&nbsp;</TD>
</TR>
</TABLE>
&nbsp;<BR><TABLE BORDER CELLSPACING=0 CELLPADDING=3 WIDTH='100%'>
<TR ALIGN=CENTER BGCOLOR='#99CCFF'><TD ALIGN=CENTER COLSPAN='6'><B>Detailed Reports</B></TD><TD ALIGN=RIGHT WIDTH='10%'COLSPAN=1> <A HREF_DISABLED="?&ExpandedTable=DetailedReports"><B>[-]</B></a></TD></TR>
<TR BGCOLOR='#FFFF99'><TD><B>Report Name</B></TD><TD><B>Status</B></TD><TD><B>Generated</B></TD>
<TD ALIGN=LEFT><B>Errors</B></TD><TD ALIGN=LEFT><B>Warnings</B></TD><TD ALIGN=LEFT COLSPAN='2'><B>Infos</B></TD></TR>
<TR ALIGN=LEFT><TD>Synthesis Report</TD><TD>&nbsp;</TD><TD>&nbsp;</TD><TD>&nbsp;</TD><TD>&nbsp;</TD><TD COLSPAN='2'>&nbsp;</TD></TR>
<TR ALIGN=LEFT><TD>Translation Report</TD><TD>&nbsp;</TD><TD>&nbsp;</TD><TD>&nbsp;</TD><TD>&nbsp;</TD><TD COLSPAN='2'>&nbsp;</TD></TR>
<TR ALIGN=LEFT><TD>Map Report</TD><TD>&nbsp;</TD><TD>&nbsp;</TD><TD>&nbsp;</TD><TD>&nbsp;</TD><TD COLSPAN='2'>&nbsp;</TD></TR>
<TR ALIGN=LEFT><TD>Place and Route Report</TD><TD>&nbsp;</TD><TD>&nbsp;</TD><TD>&nbsp;</TD><TD>&nbsp;</TD><TD COLSPAN='2'>&nbsp;</TD></TR>
<TR ALIGN=LEFT><TD>Power Report</TD><TD>&nbsp;</TD><TD>&nbsp;</TD><TD>&nbsp;</TD><TD>&nbsp;</TD><TD COLSPAN='2'>&nbsp;</TD></TR>
<TR ALIGN=LEFT><TD>Post-PAR Static Timing Report</TD><TD>&nbsp;</TD><TD>&nbsp;</TD><TD>&nbsp;</TD><TD>&nbsp;</TD><TD COLSPAN='2'>&nbsp;</TD></TR>
<TR ALIGN=LEFT><TD>Bitgen Report</TD><TD>&nbsp;</TD><TD>&nbsp;</TD><TD>&nbsp;</TD><TD>&nbsp;</TD><TD COLSPAN='2'>&nbsp;</TD></TR>
</TABLE>
&nbsp;<BR><TABLE BORDER CELLSPACING=0 CELLPADDING=3 WIDTH='100%'>
<TR ALIGN=CENTER BGCOLOR='#99CCFF'><TD ALIGN=CENTER COLSPAN='3'><B>Secondary Reports</B></TD><TD ALIGN=RIGHT WIDTH='10%'COLSPAN=1> <A HREF_DISABLED="?&ExpandedTable=SecondaryReports"><B>[-]</B></a></TD></TR>
<TR BGCOLOR='#FFFF99'><TD><B>Report Name</B></TD><TD><B>Status</B></TD><TD COLSPAN='2'><B>Generated</B></TD></TR>
</TABLE>
<br><center><b>Date Generated:</b> 11/18/2012 - 13:58:40</center>
</BODY></HTML>
@@ -0,0 +1,168 @@
<?xml version='1.0' encoding='utf-8'?>
<!--This is an ISE project configuration file.-->
<!--It holds project specific layout data for the projectmgr plugin.-->
<!--Copyright (c) 1995-2009 Xilinx, Inc. All rights reserved.-->
<Project version="2" owner="projectmgr" name="MIPS32-Pipelined-Hw" >
<!--This is an ISE project configuration file.-->
<ItemView engineview="SynthesisOnly" guiview="Source" compilemode="AutoCompile" >
<ClosedNodes>
<ClosedNodesVersion>2</ClosedNodesVersion>
<ClosedNode>/Automatic `includes</ClosedNode>
<ClosedNode>/FIFO_Clear C:|root|Work|Gauss|Final|Hardware|XUM_Singlecore|MIPS32-Pipelined-Hw|src|Common|FIFO_Clear.v</ClosedNode>
<ClosedNode>/Top C:|root|Work|Gauss|Final|Hardware|XUM_Singlecore|MIPS32-Pipelined-Hw|src|Top.v</ClosedNode>
<ClosedNode>/Top C:|root|Work|Gauss|Final|Hardware|XUM_Singlecore|MIPS32-Pipelined-Hw|src|Top.v/I2C - I2C_Controller</ClosedNode>
<ClosedNode>/Top C:|root|Work|Gauss|Final|Hardware|XUM_Singlecore|MIPS32-Pipelined-Hw|src|Top.v/LCD_Screen - LCD</ClosedNode>
<ClosedNode>/Top C:|root|Work|Gauss|Final|Hardware|XUM_Singlecore|MIPS32-Pipelined-Hw|src|Top.v/MIPS32 - Processor</ClosedNode>
<ClosedNode>/Top C:|root|Work|Gauss|Final|Hardware|XUM_Singlecore|MIPS32-Pipelined-Hw|src|Top.v/Memory - BRAM_592KB_Wrapper</ClosedNode>
<ClosedNode>/Top C:|root|Work|Gauss|Final|Hardware|XUM_Singlecore|MIPS32-Pipelined-Hw|src|Top.v/Switches - Switches</ClosedNode>
<ClosedNode>/Top C:|root|Work|Gauss|Final|Hardware|XUM_Singlecore|MIPS32-Pipelined-Hw|src|Top.v/UART - uart_bootloader</ClosedNode>
<ClosedNode>/Top C:|root|Work|Gauss|XUM_2|Hardware|XUM_Singlecore|MIPS32-Pipelined-Hw|src|Top.v/I2C - I2C_Controller</ClosedNode>
<ClosedNode>/Top C:|root|Work|Gauss|XUM_2|Hardware|XUM_Singlecore|MIPS32-Pipelined-Hw|src|Top.v/LCD_Screen - LCD</ClosedNode>
<ClosedNode>/Top C:|root|Work|Gauss|XUM_2|Hardware|XUM_Singlecore|MIPS32-Pipelined-Hw|src|Top.v/MIPS32 - Processor</ClosedNode>
<ClosedNode>/Top C:|root|Work|Gauss|XUM_2|Hardware|XUM_Singlecore|MIPS32-Pipelined-Hw|src|Top.v/Memory - BRAM_592KB_Wrapper</ClosedNode>
<ClosedNode>/Top C:|root|Work|Gauss|XUM_2|Hardware|XUM_Singlecore|MIPS32-Pipelined-Hw|src|Top.v/Switches - Switches</ClosedNode>
<ClosedNode>/Top C:|root|Work|Gauss|XUM_2|Hardware|XUM_Singlecore|MIPS32-Pipelined-Hw|src|Top.v/UART - uart_bootloader</ClosedNode>
<ClosedNode>/Top C:|root|Work|Gauss|opencores_svn|mips32r1|trunk|Hardware|XUPV5-LX110T_SoC|MIPS32-Pipelined-Hw|src|Top.v</ClosedNode>
<ClosedNode>/Top C:|root|Work|Gauss|opencores_svn|mips32r1|trunk|Hardware|XUPV5-LX110T_SoC|MIPS32-Pipelined-Hw|src|Top.v/I2C - I2C_Controller</ClosedNode>
<ClosedNode>/Top C:|root|Work|Gauss|opencores_svn|mips32r1|trunk|Hardware|XUPV5-LX110T_SoC|MIPS32-Pipelined-Hw|src|Top.v/I2C - I2C_Controller/PHY - I2C_Phy/FIFO - FIFO_Clear</ClosedNode>
<ClosedNode>/Top C:|root|Work|Gauss|opencores_svn|mips32r1|trunk|Hardware|XUPV5-LX110T_SoC|MIPS32-Pipelined-Hw|src|Top.v/LCD_Screen - LCD</ClosedNode>
<ClosedNode>/Top C:|root|Work|Gauss|opencores_svn|mips32r1|trunk|Hardware|XUPV5-LX110T_SoC|MIPS32-Pipelined-Hw|src|Top.v/MIPS32 - Processor</ClosedNode>
<ClosedNode>/Top C:|root|Work|Gauss|opencores_svn|mips32r1|trunk|Hardware|XUPV5-LX110T_SoC|MIPS32-Pipelined-Hw|src|Top.v/Switches - Switches</ClosedNode>
<ClosedNode>/Top C:|root|Work|Gauss|opencores_svn|mips32r1|trunk|Hardware|XUPV5-LX110T_SoC|MIPS32-Pipelined-Hw|src|Top.v/UART - uart_bootloader</ClosedNode>
<ClosedNode>/Top C:|root|Work|Gauss|opencores_svn|mips32r1|trunk|Hardware|XUPV5-LX110T_SoC|MIPS32-Pipelined-Hw|src|Top.v/UART - uart_bootloader/UART - uart_min/rx_buffer - FIFO_NoFull_Count</ClosedNode>
<ClosedNode>/Top C:|root|Work|Gauss|opencores_svn|mips32r1|trunk|Hardware|XUPV5-LX110T_SoC|MIPS32-Pipelined-Hw|src|Top.v/UART - uart_bootloader/UART - uart_min/tx_buffer - FIFO_NoFull_Count</ClosedNode>
</ClosedNodes>
<SelectedItems>
<SelectedItem>Top (C:/root/Work/Gauss/opencores_svn/mips32r1/trunk/Hardware/XUPV5-LX110T_SoC/MIPS32-Pipelined-Hw/src/Top.v)</SelectedItem>
</SelectedItems>
<ScrollbarPosition orientation="vertical" >0</ScrollbarPosition>
<ScrollbarPosition orientation="horizontal" >0</ScrollbarPosition>
<ViewHeaderState orientation="horizontal" >000000ff000000000000000100000001000000000000000000000000000000000202000000010000000100000064000000ae000000020000000000000000000000000200000064ffffffff000000810000000300000002000000ae0000000100000003000000000000000100000003</ViewHeaderState>
<UserChangedColumnWidths orientation="horizontal" >true</UserChangedColumnWidths>
<CurrentItem>Top (C:/root/Work/Gauss/opencores_svn/mips32r1/trunk/Hardware/XUPV5-LX110T_SoC/MIPS32-Pipelined-Hw/src/Top.v)</CurrentItem>
</ItemView>
<ItemView engineview="SynthesisOnly" sourcetype="" guiview="Process" >
<ClosedNodes>
<ClosedNodesVersion>1</ClosedNodesVersion>
<ClosedNode>Design Utilities</ClosedNode>
</ClosedNodes>
<SelectedItems>
<SelectedItem/>
</SelectedItems>
<ScrollbarPosition orientation="vertical" >0</ScrollbarPosition>
<ScrollbarPosition orientation="horizontal" >0</ScrollbarPosition>
<ViewHeaderState orientation="horizontal" >000000ff000000000000000100000001000000000000000000000000000000000000000000000000ed000000010000000100000000000000000000000064ffffffff000000810000000000000001000000ed0000000100000000</ViewHeaderState>
<UserChangedColumnWidths orientation="horizontal" >false</UserChangedColumnWidths>
<CurrentItem/>
</ItemView>
<ItemView guiview="File" >
<ClosedNodes>
<ClosedNodesVersion>1</ClosedNodesVersion>
</ClosedNodes>
<SelectedItems/>
<ScrollbarPosition orientation="vertical" >0</ScrollbarPosition>
<ScrollbarPosition orientation="horizontal" >0</ScrollbarPosition>
<ViewHeaderState orientation="horizontal" >000000ff000000000000000100000000000000000100000000000000000000000000000000000002f2000000040101000100000000000000000000000064ffffffff000000810000000000000004000000420000000100000000000000240000000100000000000000660000000100000000000002260000000100000000</ViewHeaderState>
<UserChangedColumnWidths orientation="horizontal" >false</UserChangedColumnWidths>
<CurrentItem>Add.v</CurrentItem>
</ItemView>
<ItemView guiview="Library" >
<ClosedNodes>
<ClosedNodesVersion>1</ClosedNodesVersion>
<ClosedNode>work</ClosedNode>
</ClosedNodes>
<SelectedItems/>
<ScrollbarPosition orientation="vertical" >0</ScrollbarPosition>
<ScrollbarPosition orientation="horizontal" >0</ScrollbarPosition>
<ViewHeaderState orientation="horizontal" >000000ff00000000000000010000000000000000010000000000000000000000000000000000000109000000010001000100000000000000000000000064ffffffff000000810000000000000001000001090000000100000000</ViewHeaderState>
<UserChangedColumnWidths orientation="horizontal" >false</UserChangedColumnWidths>
<CurrentItem>work</CurrentItem>
</ItemView>
<ItemView engineview="SynthesisOnly" sourcetype="DESUT_VERILOG" guiview="Process" >
<ClosedNodes>
<ClosedNodesVersion>1</ClosedNodesVersion>
<ClosedNode>Configure Target Device</ClosedNode>
<ClosedNode>Implement Design</ClosedNode>
<ClosedNode>Synthesize - XST</ClosedNode>
<ClosedNode>User Constraints</ClosedNode>
</ClosedNodes>
<SelectedItems>
<SelectedItem>Configure Target Device</SelectedItem>
</SelectedItems>
<ScrollbarPosition orientation="vertical" >0</ScrollbarPosition>
<ScrollbarPosition orientation="horizontal" >0</ScrollbarPosition>
<ViewHeaderState orientation="horizontal" >000000ff000000000000000100000001000000000000000000000000000000000000000000000000c9000000010000000100000000000000000000000064ffffffff000000810000000000000001000000c90000000100000000</ViewHeaderState>
<UserChangedColumnWidths orientation="horizontal" >false</UserChangedColumnWidths>
<CurrentItem>Configure Target Device</CurrentItem>
</ItemView>
<ItemView engineview="SynthesisOnly" sourcetype="DESUT_UCF" guiview="Process" >
<ClosedNodes>
<ClosedNodesVersion>1</ClosedNodesVersion>
<ClosedNode>User Constraints</ClosedNode>
</ClosedNodes>
<SelectedItems>
<SelectedItem/>
</SelectedItems>
<ScrollbarPosition orientation="vertical" >0</ScrollbarPosition>
<ScrollbarPosition orientation="horizontal" >0</ScrollbarPosition>
<ViewHeaderState orientation="horizontal" >000000ff000000000000000100000001000000000000000000000000000000000000000000000000ed000000010000000100000000000000000000000064ffffffff000000810000000000000001000000ed0000000100000000</ViewHeaderState>
<UserChangedColumnWidths orientation="horizontal" >false</UserChangedColumnWidths>
<CurrentItem/>
</ItemView>
<SourceProcessView>000000ff00000000000000020000011b0000011b01000000050100000002</SourceProcessView>
<CurrentView>Implementation</CurrentView>
<ItemView engineview="BehavioralSim" guiview="Source" compilemode="AutoCompile" >
<ClosedNodes>
<ClosedNodesVersion>2</ClosedNodesVersion>
<ClosedNode>/Top C:|root|Work|Gauss|Final|Hardware|XUM_Singlecore|MIPS32-Pipelined-Hw|src|Top.v</ClosedNode>
<ClosedNode>/Top_Tester C:|root|Work|Gauss|Final|Hardware|XUM_Singlecore|MIPS32-Pipelined-Hw|src|Simulation|Top_Tester.v</ClosedNode>
<ClosedNode>/Top_Tester C:|root|Work|Gauss|XUM_2|Hardware|XUM_Singlecore|MIPS32-Pipelined-Hw|src|Simulation|Top_Tester.v/uut - Top</ClosedNode>
</ClosedNodes>
<SelectedItems>
<SelectedItem>Unassigned User Library Modules</SelectedItem>
</SelectedItems>
<ScrollbarPosition orientation="vertical" >0</ScrollbarPosition>
<ScrollbarPosition orientation="horizontal" >0</ScrollbarPosition>
<ViewHeaderState orientation="horizontal" >000000ff000000000000000100000001000000000000000000000000000000000202000000010000000100000064000000c3000000020000000000000000000000000200000064ffffffff000000810000000300000002000000c30000000100000003000000000000000100000003</ViewHeaderState>
<UserChangedColumnWidths orientation="horizontal" >true</UserChangedColumnWidths>
<CurrentItem>Unassigned User Library Modules</CurrentItem>
</ItemView>
<ItemView engineview="BehavioralSim" sourcetype="" guiview="Process" >
<ClosedNodes>
<ClosedNodesVersion>1</ClosedNodesVersion>
<ClosedNode>Design Utilities</ClosedNode>
</ClosedNodes>
<SelectedItems>
<SelectedItem/>
</SelectedItems>
<ScrollbarPosition orientation="vertical" >0</ScrollbarPosition>
<ScrollbarPosition orientation="horizontal" >0</ScrollbarPosition>
<ViewHeaderState orientation="horizontal" >000000ff000000000000000100000001000000000000000000000000000000000000000000000000ed000000010000000100000000000000000000000064ffffffff000000810000000000000001000000ed0000000100000000</ViewHeaderState>
<UserChangedColumnWidths orientation="horizontal" >false</UserChangedColumnWidths>
<CurrentItem/>
</ItemView>
<ItemView engineview="BehavioralSim" sourcetype="DESUT_VERILOG" guiview="Process" >
<ClosedNodes>
<ClosedNodesVersion>1</ClosedNodesVersion>
</ClosedNodes>
<SelectedItems>
<SelectedItem>Simulate Behavioral Model</SelectedItem>
</SelectedItems>
<ScrollbarPosition orientation="vertical" >0</ScrollbarPosition>
<ScrollbarPosition orientation="horizontal" >0</ScrollbarPosition>
<ViewHeaderState orientation="horizontal" >000000ff000000000000000100000001000000000000000000000000000000000000000000000000ed000000010000000100000000000000000000000064ffffffff000000810000000000000001000000ed0000000100000000</ViewHeaderState>
<UserChangedColumnWidths orientation="horizontal" >false</UserChangedColumnWidths>
<CurrentItem>Simulate Behavioral Model</CurrentItem>
</ItemView>
<ItemView engineview="SynthesisOnly" sourcetype="DESUT_XCO" guiview="Process" >
<ClosedNodes>
<ClosedNodesVersion>1</ClosedNodesVersion>
</ClosedNodes>
<SelectedItems/>
<ScrollbarPosition orientation="vertical" >0</ScrollbarPosition>
<ScrollbarPosition orientation="horizontal" >0</ScrollbarPosition>
<ViewHeaderState orientation="horizontal" ></ViewHeaderState>
<UserChangedColumnWidths orientation="horizontal" >false</UserChangedColumnWidths>
<CurrentItem></CurrentItem>
</ItemView>
</Project>
@@ -0,0 +1,215 @@
<?xml version='1.0' encoding='UTF-8'?>
<report-views version="2.0" >
<header>
<DateModified>2012-11-18T13:58:40</DateModified>
<ModuleName>Top</ModuleName>
<SummaryTimeStamp>2012-11-18T13:55:48</SummaryTimeStamp>
<SavedFilePath>C:/root/Work/Gauss/opencores_svn/mips32r1/trunk/Hardware/XUPV5-LX110T_SoC/MIPS32-Pipelined-Hw/iseconfig/Top.xreport</SavedFilePath>
<ImplementationReportsDirectory>C:/root/Work/Gauss/opencores_svn/mips32r1/trunk/Hardware/XUPV5-LX110T_SoC/MIPS32-Pipelined-Hw\</ImplementationReportsDirectory>
<DateInitialized>2012-09-08T00:01:22</DateInitialized>
<EnableMessageFiltering>false</EnableMessageFiltering>
</header>
<body>
<viewgroup label="Design Overview" >
<view inputState="Unknown" program="implementation" ShowPartitionData="false" type="FPGASummary" file="Top_summary.html" label="Summary" >
<toc-item title="Design Overview" target="Design Overview" />
<toc-item title="Design Utilization Summary" target="Design Utilization Summary" />
<toc-item title="Performance Summary" target="Performance Summary" />
<toc-item title="Failing Constraints" target="Failing Constraints" />
<toc-item title="Detailed Reports" target="Detailed Reports" />
</view>
<view inputState="Unknown" program="implementation" contextTags="FPGA_ONLY" hidden="true" type="HTML" file="Top_envsettings.html" label="System Settings" />
<view inputState="Translated" program="map" locator="MAP_IOB_TABLE" contextTags="FPGA_ONLY" type="IOBProperties" file="Top_map.xrpt" label="IOB Properties" />
<view inputState="Translated" program="map" contextTags="FPGA_ONLY" hidden="true" type="Control_Sets" file="Top_map.xrpt" label="Control Set Information" />
<view inputState="Translated" program="map" locator="MAP_MODULE_HIERARCHY" contextTags="FPGA_ONLY" type="Module_Utilization" file="Top_map.xrpt" label="Module Level Utilization" />
<view inputState="Mapped" program="par" locator="CONSTRAINT_TABLE" contextTags="FPGA_ONLY" type="ConstraintsData" file="Top.ptwx" showConstraints="0" label="Timing Constraints" translator="ptwxToTableXML.xslt" />
<view inputState="Mapped" program="par" locator="PAR_PINOUT_BY_PIN_NUMBER" contextTags="FPGA_ONLY" type="PinoutData" file="Top_par.xrpt" label="Pinout Report" />
<view inputState="Mapped" program="par" locator="PAR_CLOCK_TABLE" contextTags="FPGA_ONLY" type="ClocksData" file="Top_par.xrpt" label="Clock Report" />
<view inputState="Mapped" program="par" contextTags="FPGA_ONLY,EDK_OFF" type="Timing_Analyzer" file="Top.twx" label="Static Timing" />
<view inputState="Translated" program="cpldfit" contextTags="CPLD_ONLY,EDK_OFF" hidden="true" type="EXTERNAL_HTML" file="Top_html/fit/report.htm" label="CPLD Fitter Report" />
<view inputState="Fitted" program="taengine" contextTags="CPLD_ONLY,EDK_OFF" hidden="true" type="EXTERNAL_HTML" file="Top_html/tim/report.htm" label="CPLD Timing Report" />
</viewgroup>
<viewgroup label="XPS Errors and Warnings" >
<view program="platgen" WrapMessages="true" contextTags="EDK_ON" hidden="true" type="MessageList" hideColumns="Filtered" file="__xps/ise/_xmsgs/platgen.xmsgs" label="Platgen Messages" />
<view program="simgen" WrapMessages="true" contextTags="EDK_ON" hidden="true" type="MessageList" hideColumns="Filtered" file="__xps/ise/_xmsgs/simgen.xmsgs" label="Simgen Messages" />
<view program="bitinit" WrapMessages="true" contextTags="EDK_ON" hidden="true" type="MessageList" hideColumns="Filtered" file="__xps/ise/_xmsgs/bitinit.xmsgs" label="BitInit Messages" />
</viewgroup>
<viewgroup label="XPS Reports" >
<view inputState="PreSynthesized" program="platgen" contextTags="EDK_ON" hidden="true" type="Secondary_Report" file="platgen.log" label="Platgen Log File" />
<view inputState="PreSynthesized" program="simgen" contextTags="EDK_ON" hidden="true" type="Secondary_Report" file="simgen.log" label="Simgen Log File" />
<view inputState="PreSynthesized" program="bitinit" contextTags="EDK_ON" hidden="true" type="Secondary_Report" file="bitinit.log" label="BitInit Log File" />
<view inputState="PreSynthesized" program="system" contextTags="EDK_ON" hidden="true" type="Secondary_Report" file="Top.log" label="System Log File" />
</viewgroup>
<viewgroup label="Errors and Warnings" >
<view program="pn" WrapMessages="true" contextTags="EDK_OFF" type="MessageList" hideColumns="Filtered, New" file="_xmsgs/pn_parser.xmsgs" label="Parser Messages" />
<view program="xst" WrapMessages="true" contextTags="XST_ONLY,EDK_OFF" hidden="false" type="MessageList" hideColumns="Filtered" file="_xmsgs/xst.xmsgs" label="Synthesis Messages" />
<view inputState="Synthesized" program="ngdbuild" WrapMessages="true" type="MessageList" hideColumns="Filtered" file="_xmsgs/ngdbuild.xmsgs" label="Translation Messages" />
<view inputState="Translated" program="map" WrapMessages="true" contextTags="FPGA_ONLY" type="MessageList" hideColumns="Filtered" file="_xmsgs/map.xmsgs" label="Map Messages" />
<view inputState="Mapped" program="par" WrapMessages="true" contextTags="FPGA_ONLY" type="MessageList" hideColumns="Filtered" file="_xmsgs/par.xmsgs" label="Place and Route Messages" />
<view inputState="Routed" program="trce" WrapMessages="true" contextTags="FPGA_ONLY" type="MessageList" hideColumns="Filtered" file="_xmsgs/trce.xmsgs" label="Timing Messages" />
<view inputState="Routed" program="xpwr" WrapMessages="true" contextTags="EDK_OFF" hidden="true" type="MessageList" hideColumns="Filtered" file="_xmsgs/xpwr.xmsgs" label="Power Messages" />
<view inputState="Routed" program="bitgen" WrapMessages="true" contextTags="FPGA_ONLY" type="MessageList" hideColumns="Filtered" file="_xmsgs/bitgen.xmsgs" label="Bitgen Messages" />
<view inputState="Translated" program="cpldfit" WrapMessages="true" contextTags="CPLD_ONLY,EDK_OFF" hidden="true" type="MessageList" hideColumns="Filtered" file="_xmsgs/cpldfit.xmsgs" label="Fitter Messages" />
<view inputState="Current" program="implementation" WrapMessages="true" fileList="_xmsgs/xst.xmsgs,_xmsgs/ngdbuild.xmsgs,_xmsgs/map.xmsgs,_xmsgs/par.xmsgs,_xmsgs/trce.xmsgs,_xmsgs/xpwr.xmsgs,_xmsgs/bitgen.xmsgs" contextTags="FPGA_ONLY" type="MessageList" hideColumns="Filtered" file="_xmsgs/*.xmsgs" label="All Implementation Messages" />
<view inputState="Current" program="fitting" WrapMessages="true" fileList="_xmsgs/xst.xmsgs,_xmsgs/ngdbuild.xmsgs,_xmsgs/cpldfit.xmsgs,_xmsgs/xpwr.xmsgs" contextTags="CPLD_ONLY,EDK_OFF" hidden="true" type="CPLD_MessageList" hideColumns="Filtered" file="_xmsgs/*.xmsgs" label="All Implementation Messages (CPLD)" />
</viewgroup>
<viewgroup label="Detailed Reports" >
<view program="xst" contextTags="XST_ONLY,EDK_OFF" hidden="false" type="Report" file="Top.syr" label="Synthesis Report" >
<toc-item title="Top of Report" target="Copyright " searchDir="Forward" />
<toc-item title="Synthesis Options Summary" target=" Synthesis Options Summary " />
<toc-item title="HDL Compilation" target=" HDL Compilation " />
<toc-item title="Design Hierarchy Analysis" target=" Design Hierarchy Analysis " />
<toc-item title="HDL Analysis" target=" HDL Analysis " />
<toc-item title="HDL Parsing" target=" HDL Parsing " />
<toc-item title="HDL Elaboration" target=" HDL Elaboration " />
<toc-item title="HDL Synthesis" target=" HDL Synthesis " />
<toc-item title="HDL Synthesis Report" target="HDL Synthesis Report" searchCnt="2" searchDir="Backward" subItemLevel="1" />
<toc-item title="Advanced HDL Synthesis" target=" Advanced HDL Synthesis " searchDir="Backward" />
<toc-item title="Advanced HDL Synthesis Report" target="Advanced HDL Synthesis Report" subItemLevel="1" />
<toc-item title="Low Level Synthesis" target=" Low Level Synthesis " />
<toc-item title="Partition Report" target=" Partition Report " />
<toc-item title="Final Report" target=" Final Report " />
<toc-item title="Design Summary" target=" Design Summary " />
<toc-item title="Primitive and Black Box Usage" target="Primitive and Black Box Usage:" subItemLevel="1" />
<toc-item title="Device Utilization Summary" target="Device utilization summary:" subItemLevel="1" />
<toc-item title="Partition Resource Summary" target="Partition Resource Summary:" subItemLevel="1" />
<toc-item title="Timing Report" target="Timing Report" subItemLevel="1" />
<toc-item title="Clock Information" target="Clock Information" subItemLevel="2" />
<toc-item title="Asynchronous Control Signals Information" target="Asynchronous Control Signals Information" subItemLevel="2" />
<toc-item title="Timing Summary" target="Timing Summary" subItemLevel="2" />
<toc-item title="Timing Details" target="Timing Details" subItemLevel="2" />
<toc-item title="Cross Clock Domains Report" target="Cross Clock Domains Report:" subItemLevel="2" />
</view>
<view program="synplify" contextTags="SYNPLIFY_ONLY,EDK_OFF" hidden="true" type="Report" file="Top.srr" label="Synplify Report" />
<view program="precision" contextTags="PRECISION_ONLY,EDK_OFF" hidden="true" type="Report" file="Top.prec_log" label="Precision Report" />
<view inputState="Synthesized" program="ngdbuild" type="Report" file="Top.bld" label="Translation Report" >
<toc-item title="Top of Report" target="Copyright (c)" searchDir="Forward" />
<toc-item title="Command Line" target="Command Line:" />
<toc-item title="Partition Status" target="Partition Implementation Status" />
<toc-item title="Final Summary" target="NGDBUILD Design Results Summary:" />
</view>
<view inputState="Translated" program="map" contextTags="FPGA_ONLY" type="Report" file="Top_map.mrp" label="Map Report" >
<toc-item title="Top of Report" target="Release" searchDir="Forward" />
<toc-item title="Section 1: Errors" target="Section 1 -" searchDir="Backward" />
<toc-item title="Section 2: Warnings" target="Section 2 -" searchDir="Backward" />
<toc-item title="Section 3: Infos" target="Section 3 -" searchDir="Backward" />
<toc-item title="Section 4: Removed Logic Summary" target="Section 4 -" searchDir="Backward" />
<toc-item title="Section 5: Removed Logic" target="Section 5 -" searchDir="Backward" />
<toc-item title="Section 6: IOB Properties" target="Section 6 -" searchDir="Backward" />
<toc-item title="Section 7: RPMs" target="Section 7 -" searchDir="Backward" />
<toc-item title="Section 8: Guide Report" target="Section 8 -" searchDir="Backward" />
<toc-item title="Section 9: Area Group and Partition Summary" target="Section 9 -" searchDir="Backward" />
<toc-item title="Section 10: Timing Report" target="Section 10 -" searchDir="Backward" />
<toc-item title="Section 11: Configuration String Details" target="Section 11 -" searchDir="Backward" />
<toc-item title="Section 12: Control Set Information" target="Section 12 -" searchDir="Backward" />
<toc-item title="Section 13: Utilization by Hierarchy" target="Section 13 -" searchDir="Backward" />
</view>
<view inputState="Mapped" program="par" contextTags="FPGA_ONLY" type="Report" file="Top.par" label="Place and Route Report" >
<toc-item title="Top of Report" target="Copyright (c)" searchDir="Forward" />
<toc-item title="Device Utilization" target="Device Utilization Summary:" />
<toc-item title="Router Information" target="Starting Router" />
<toc-item title="Partition Status" target="Partition Implementation Status" />
<toc-item title="Clock Report" target="Generating Clock Report" />
<toc-item title="Timing Results" target="Timing Score:" />
<toc-item title="Final Summary" target="Peak Memory Usage:" />
</view>
<view inputState="Routed" program="trce" contextTags="FPGA_ONLY" type="Report" file="Top.twr" label="Post-PAR Static Timing Report" >
<toc-item title="Top of Report" target="Copyright (c)" searchDir="Forward" />
<toc-item title="Timing Report Description" target="Device,package,speed:" />
<toc-item title="Informational Messages" target="INFO:" />
<toc-item title="Warning Messages" target="WARNING:" />
<toc-item title="Timing Constraints" target="Timing constraint:" />
<toc-item title="Derived Constraint Report" target="Derived Constraint Report" />
<toc-item title="Data Sheet Report" target="Data Sheet report:" />
<toc-item title="Timing Summary" target="Timing summary:" />
<toc-item title="Trace Settings" target="Trace Settings:" />
</view>
<view inputState="Translated" program="cpldfit" contextTags="CPLD_ONLY,EDK_OFF" hidden="true" type="Report" file="Top.rpt" label="CPLD Fitter Report (Text)" >
<toc-item title="Top of Report" target="cpldfit:" searchDir="Forward" />
<toc-item title="Resources Summary" target="** Mapped Resource Summary **" />
<toc-item title="Pin Resources" target="** Pin Resources **" />
<toc-item title="Global Resources" target="** Global Control Resources **" />
</view>
<view inputState="Fitted" program="taengine" contextTags="CPLD_ONLY,EDK_OFF" hidden="true" type="Report" file="Top.tim" label="CPLD Timing Report (Text)" >
<toc-item title="Top of Report" target="Performance Summary Report" searchDir="Forward" />
<toc-item title="Performance Summary" target="Performance Summary:" />
</view>
<view inputState="Routed" program="xpwr" contextTags="EDK_OFF" type="Report" file="Top.pwr" label="Power Report" >
<toc-item title="Top of Report" target="Copyright (c)" searchDir="Forward" />
<toc-item title="Power summary" target="Power summary" />
<toc-item title="Thermal summary" target="Thermal summary" />
</view>
<view inputState="Routed" program="bitgen" contextTags="FPGA_ONLY" type="Report" file="Top.bgn" label="Bitgen Report" >
<toc-item title="Top of Report" target="Copyright (c)" searchDir="Forward" />
<toc-item title="Bitgen Options" target="Summary of Bitgen Options:" />
<toc-item title="Final Summary" target="DRC detected" />
</view>
</viewgroup>
<viewgroup label="Secondary Reports" >
<view inputState="PreSynthesized" program="isim" hidden="if_missing" type="Secondary_Report" file="isim.log" label="ISIM Simulator Log" />
<view inputState="Synthesized" program="netgen" hidden="if_missing" type="Secondary_Report" file="netgen/synthesis/Top_synthesis.nlf" label="Post-Synthesis Simulation Model Report" >
<toc-item title="Top of Report" target="Release" searchDir="Forward" />
</view>
<view inputState="Translated" program="netgen" hidden="if_missing" type="Secondary_Report" file="netgen/translate/Top_translate.nlf" label="Post-Translate Simulation Model Report" >
<toc-item title="Top of Report" target="Release" searchDir="Forward" />
</view>
<view inputState="Translated" program="netgen" hidden="if_missing" type="Secondary_Report" file="Top_tran_fecn.nlf" label="Post-Translate Formality Netlist Report" />
<view inputState="Translated" program="map" contextTags="FPGA_ONLY" hidden="true" type="Secondary_Report" file="Top_map.map" label="Map Log File" >
<toc-item title="Top of Report" target="Release" searchDir="Forward" />
<toc-item title="Design Information" target="Design Information" />
<toc-item title="Design Summary" target="Design Summary" />
</view>
<view inputState="Routed" program="smartxplorer" contextTags="FPGA_ONLY" hidden="if_missing" type="Secondary_Report" file="smartxplorer_results/smartxplorer.txt" label="SmartXplorer Report" />
<view inputState="Mapped" program="trce" contextTags="FPGA_ONLY" hidden="if_missing" type="Secondary_Report" file="Top_preroute.twr" label="Post-Map Static Timing Report" >
<toc-item title="Top of Report" target="Copyright (c)" searchDir="Forward" />
<toc-item title="Timing Report Description" target="Device,package,speed:" />
<toc-item title="Informational Messages" target="INFO:" />
<toc-item title="Warning Messages" target="WARNING:" />
<toc-item title="Timing Constraints" target="Timing constraint:" />
<toc-item title="Derived Constraint Report" target="Derived Constraint Report" />
<toc-item title="Data Sheet Report" target="Data Sheet report:" />
<toc-item title="Timing Summary" target="Timing summary:" />
<toc-item title="Trace Settings" target="Trace Settings:" />
</view>
<view inputState="Mapped" program="netgen" hidden="if_missing" type="Secondary_Report" file="netgen/map/Top_map.nlf" label="Post-Map Simulation Model Report" />
<view inputState="Mapped" program="map" contextTags="FPGA_ONLY" hidden="if_missing" type="Secondary_Report" file="Top_map.psr" label="Physical Synthesis Report" >
<toc-item title="Top of Report" target="Copyright (c)" searchDir="Forward" />
</view>
<view inputState="Mapped" program="par" contextTags="FPGA_ONLY" hidden="true" type="Pad_Report" file="Top_pad.txt" label="Pad Report" >
<toc-item title="Top of Report" target="Copyright (c)" searchDir="Forward" />
</view>
<view inputState="Mapped" program="par" contextTags="FPGA_ONLY" hidden="true" type="Secondary_Report" file="Top.unroutes" label="Unroutes Report" >
<toc-item title="Top of Report" target="Copyright (c)" searchDir="Forward" />
</view>
<view inputState="Mapped" program="map" contextTags="FPGA_ONLY" hidden="if_missing" type="Secondary_Report" file="Top_preroute.tsi" label="Post-Map Constraints Interaction Report" >
<toc-item title="Top of Report" target="Release" searchDir="Forward" />
</view>
<view inputState="Mapped" program="par" contextTags="FPGA_ONLY" hidden="if_missing" type="Secondary_Report" file="Top.grf" label="Guide Results Report" />
<view inputState="Routed" program="par" contextTags="FPGA_ONLY" hidden="if_missing" type="Secondary_Report" file="Top.dly" label="Asynchronous Delay Report" />
<view inputState="Routed" program="par" contextTags="FPGA_ONLY" hidden="if_missing" type="Secondary_Report" file="Top.clk_rgn" label="Clock Region Report" />
<view inputState="Routed" program="par" contextTags="FPGA_ONLY" hidden="if_missing" type="Secondary_Report" file="Top.tsi" label="Post-Place and Route Constraints Interaction Report" >
<toc-item title="Top of Report" target="Copyright (c)" searchDir="Forward" />
</view>
<view inputState="Routed" program="netgen" hidden="if_missing" type="Secondary_Report" file="Top_par_fecn.nlf" label="Post-Place and Route Formality Netlist Report" />
<view inputState="Routed" program="netgen" contextTags="FPGA_ONLY" hidden="if_missing" type="Secondary_Report" file="netgen/par/Top_timesim.nlf" label="Post-Place and Route Simulation Model Report" />
<view inputState="Routed" program="netgen" hidden="if_missing" type="Secondary_Report" file="Top_sta.nlf" label="Primetime Netlist Report" >
<toc-item title="Top of Report" target="Release" searchDir="Forward" />
</view>
<view inputState="Routed" program="ibiswriter" hidden="if_missing" type="Secondary_Report" file="Top.ibs" label="IBIS Model" >
<toc-item title="Top of Report" target="IBIS Models for" searchDir="Forward" />
<toc-item title="Component" target="Component " />
</view>
<view inputState="Routed" program="pin2ucf" contextTags="FPGA_ONLY" hidden="if_missing" type="Secondary_Report" file="Top.lck" label="Back-annotate Pin Report" >
<toc-item title="Top of Report" target="pin2ucf Report File" searchDir="Forward" />
<toc-item title="Constraint Conflicts Information" target="Constraint Conflicts Information" />
</view>
<view inputState="Routed" program="pin2ucf" contextTags="FPGA_ONLY" hidden="if_missing" type="Secondary_Report" file="Top.lpc" label="Locked Pin Constraints" >
<toc-item title="Top of Report" target="top.lpc" searchDir="Forward" />
<toc-item title="Newly Added Constraints" target="The following constraints were newly added" />
</view>
<view inputState="Translated" program="netgen" contextTags="CPLD_ONLY,EDK_OFF" hidden="if_missing" type="Secondary_Report" file="netgen/fit/Top_timesim.nlf" label="Post-Fit Simulation Model Report" />
<view inputState="Routed" program="bitgen" contextTags="FPGA_ONLY" hidden="if_missing" type="HTML" file="usage_statistics_webtalk.html" label="WebTalk Report" />
<view inputState="Routed" program="bitgen" contextTags="FPGA_ONLY" hidden="if_missing" type="Secondary_Report" file="webtalk.log" label="WebTalk Log File" />
</viewgroup>
</body>
</report-views>
@@ -0,0 +1,79 @@
`timescale 1ns / 1ps
/*
* File : BRAM_592KB_Wrapper.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 6-Jun-2012 GEA Initial design.
*
* Standards/Formatting:
* Verilog 2001, 4 soft tab, wide column.
*
* Description:
* Provides access to Block Memory through a 4-way handshaking protocol,
* which allows for multi-cycle and variably-timed operations on the
* data bus.
*/
module BRAM_592KB_Wrapper(
input clock,
input reset,
input rea,
input [3:0] wea,
input [17:0] addra,
input [31:0] dina,
output [31:0] douta,
output reg dreadya,
input reb,
input [3:0] web,
input [17:0] addrb,
input [31:0] dinb,
output [31:0] doutb,
output reg dreadyb
);
/* Four-Way Memory Handshake Protocol:
1. Read/Write request goes high.
2. Ack goes high when data is available.
3. Read/Write request goes low.
4. Ack signal goes low.
____
R/W: __| |____
____
Ack: _____| |____
*/
// Writes require one clock cycle, and reads require 2 or 3 clock cycles (registered output).
// The following logic controls the Ready signal based on these latencies.
reg [1:0] delay_A, delay_B;
always @(posedge clock) begin
delay_A <= (reset | ~rea) ? 2'b00 : ((delay_A == 2'b10) ? delay_A : delay_A + 1);
delay_B <= (reset | ~reb) ? 2'b00 : ((delay_B == 2'b10) ? delay_B : delay_B + 1);
end
always @(posedge clock) begin
dreadya <= (reset) ? 0 : ((wea != 4'b0000) || ((delay_A == 2'b10) && rea)) ? 1 : 0;
dreadyb <= (reset) ? 0 : ((web != 4'b0000) || ((delay_B == 2'b10) && reb)) ? 1 : 0;
end
BRAM_592KB_2R RAM (
.clka (clock), // input clka
.rsta (reset), // input rsta
.wea (wea), // input [3 : 0] wea
.addra (addra), // input [17 : 0] addra
.dina (dina), // input [31 : 0] dina
.douta (douta), // output [31 : 0] douta
.clkb (clock), // input clkb
.rstb (reset), // input rstb
.web (web), // input [3 : 0] web
.addrb (addrb), // input [17 : 0] addrb
.dinb (dinb), // input [31 : 0] dinb
.doutb (doutb) // output [31 : 0] doutb
);
endmodule
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,90 @@
////////////////////////////////////////////////////////////////////////////////
// Copyright (c) 1995-2012 Xilinx, Inc. All rights reserved.
////////////////////////////////////////////////////////////////////////////////
// ____ ____
// / /\/ /
// /___/ \ / Vendor: Xilinx
// \ \ \/ Version : 14.1
// \ \ Application : xaw2verilog
// / / Filename : PLL_100MHz_to_33MHz_66MHz.v
// /___/ /\ Timestamp : 11/18/2012 13:35:59
// \ \ / \
// \___\/\___\
//
//Command: xaw2verilog -st C:\root\Work\Gauss\delclk\ipcore_dir\.\PLL_100MHz_to_33MHz_66MHz.xaw C:\root\Work\Gauss\delclk\ipcore_dir\.\PLL_100MHz_to_33MHz_66MHz
//Design Name: PLL_100MHz_to_33MHz_66MHz
//Device: xc5vlx110t-1ff1136
//
// Module PLL_100MHz_to_33MHz_66MHz
// Generated by Xilinx Architecture Wizard
// Written for synthesis tool: XST
// For block PLL_ADV_INST, Estimated PLL Jitter for CLKOUT0 = 0.186 ns
// For block PLL_ADV_INST, Estimated PLL Jitter for CLKOUT1 = 0.162 ns
`timescale 1ns / 1ps
module PLL_100MHz_to_33MHz_66MHz(CLKIN1_IN,
RST_IN,
CLKOUT0_OUT,
CLKOUT1_OUT,
LOCKED_OUT);
input CLKIN1_IN;
input RST_IN;
output CLKOUT0_OUT;
output CLKOUT1_OUT;
output LOCKED_OUT;
wire CLKFBOUT_CLKFBIN;
wire CLKIN1_IBUFG;
wire CLKOUT0_BUF;
wire CLKOUT1_BUF;
wire GND_BIT;
wire [4:0] GND_BUS_5;
wire [15:0] GND_BUS_16;
wire VCC_BIT;
assign GND_BIT = 0;
assign GND_BUS_5 = 5'b00000;
assign GND_BUS_16 = 16'b0000000000000000;
assign VCC_BIT = 1;
IBUFG CLKIN1_IBUFG_INST (.I(CLKIN1_IN),
.O(CLKIN1_IBUFG));
BUFG CLKOUT0_BUFG_INST (.I(CLKOUT0_BUF),
.O(CLKOUT0_OUT));
BUFG CLKOUT1_BUFG_INST (.I(CLKOUT1_BUF),
.O(CLKOUT1_OUT));
PLL_ADV #( .BANDWIDTH("OPTIMIZED"), .CLKIN1_PERIOD(10.000),
.CLKIN2_PERIOD(10.000), .CLKOUT0_DIVIDE(12), .CLKOUT1_DIVIDE(6),
.CLKOUT0_PHASE(0.000), .CLKOUT1_PHASE(0.000),
.CLKOUT0_DUTY_CYCLE(0.500), .CLKOUT1_DUTY_CYCLE(0.500),
.COMPENSATION("SYSTEM_SYNCHRONOUS"), .DIVCLK_DIVIDE(1),
.CLKFBOUT_MULT(4), .CLKFBOUT_PHASE(0.0), .REF_JITTER(0.005000) )
PLL_ADV_INST (.CLKFBIN(CLKFBOUT_CLKFBIN),
.CLKINSEL(VCC_BIT),
.CLKIN1(CLKIN1_IBUFG),
.CLKIN2(GND_BIT),
.DADDR(GND_BUS_5[4:0]),
.DCLK(GND_BIT),
.DEN(GND_BIT),
.DI(GND_BUS_16[15:0]),
.DWE(GND_BIT),
.REL(GND_BIT),
.RST(RST_IN),
.CLKFBDCM(),
.CLKFBOUT(CLKFBOUT_CLKFBIN),
.CLKOUTDCM0(),
.CLKOUTDCM1(),
.CLKOUTDCM2(),
.CLKOUTDCM3(),
.CLKOUTDCM4(),
.CLKOUTDCM5(),
.CLKOUT0(CLKOUT0_BUF),
.CLKOUT1(CLKOUT1_BUF),
.CLKOUT2(),
.CLKOUT3(),
.CLKOUT4(),
.CLKOUT5(),
.DO(),
.DRDY(),
.LOCKED(LOCKED_OUT));
endmodule
@@ -0,0 +1,90 @@
////////////////////////////////////////////////////////////////////////////////
// Copyright (c) 1995-2012 Xilinx, Inc. All rights reserved.
////////////////////////////////////////////////////////////////////////////////
// ____ ____
// / /\/ /
// /___/ \ / Vendor: Xilinx
// \ \ \/ Version : 14.1
// \ \ Application : xaw2verilog
// / / Filename : pll2.v
// /___/ /\ Timestamp : 06/15/2012 18:19:44
// \ \ / \
// \___\/\___\
//
//Command: xaw2verilog -intstyle C:/root/Work/Gauss/XUM/delz/ipcore_dir/pll2.xaw -st pll2.v
//Design Name: pll2
//Device: xc5vlx110t-2ff1136
//
// Module pll2
// Generated by Xilinx Architecture Wizard
// Written for synthesis tool: XST
// For block PLL_ADV_INST, Estimated PLL Jitter for CLKOUT0 = 0.171 ns
// For block PLL_ADV_INST, Estimated PLL Jitter for CLKOUT1 = 0.149 ns
`timescale 1ns / 1ps
module PLL_100MHz_to_50MHz_100MHz(CLKIN1_IN,
RST_IN,
CLKOUT0_OUT,
CLKOUT1_OUT,
LOCKED_OUT);
input CLKIN1_IN;
input RST_IN;
output CLKOUT0_OUT;
output CLKOUT1_OUT;
output LOCKED_OUT;
wire CLKFBOUT_CLKFBIN;
wire CLKIN1_IBUFG;
wire CLKOUT0_BUF;
wire CLKOUT1_BUF;
wire GND_BIT;
wire [4:0] GND_BUS_5;
wire [15:0] GND_BUS_16;
wire VCC_BIT;
assign GND_BIT = 0;
assign GND_BUS_5 = 5'b00000;
assign GND_BUS_16 = 16'b0000000000000000;
assign VCC_BIT = 1;
IBUFG CLKIN1_IBUFG_INST (.I(CLKIN1_IN),
.O(CLKIN1_IBUFG));
BUFG CLKOUT0_BUFG_INST (.I(CLKOUT0_BUF),
.O(CLKOUT0_OUT));
BUFG CLKOUT1_BUFG_INST (.I(CLKOUT1_BUF),
.O(CLKOUT1_OUT));
PLL_ADV #( .BANDWIDTH("OPTIMIZED"), .CLKIN1_PERIOD(10.000),
.CLKIN2_PERIOD(10.000), .CLKOUT0_DIVIDE(8), .CLKOUT1_DIVIDE(4),
.CLKOUT0_PHASE(0.000), .CLKOUT1_PHASE(0.000),
.CLKOUT0_DUTY_CYCLE(0.500), .CLKOUT1_DUTY_CYCLE(0.500),
.COMPENSATION("SYSTEM_SYNCHRONOUS"), .DIVCLK_DIVIDE(1),
.CLKFBOUT_MULT(4), .CLKFBOUT_PHASE(0.0), .REF_JITTER(0.005000) )
PLL_ADV_INST (.CLKFBIN(CLKFBOUT_CLKFBIN),
.CLKINSEL(VCC_BIT),
.CLKIN1(CLKIN1_IBUFG),
.CLKIN2(GND_BIT),
.DADDR(GND_BUS_5[4:0]),
.DCLK(GND_BIT),
.DEN(GND_BIT),
.DI(GND_BUS_16[15:0]),
.DWE(GND_BIT),
.REL(GND_BIT),
.RST(RST_IN),
.CLKFBDCM(),
.CLKFBOUT(CLKFBOUT_CLKFBIN),
.CLKOUTDCM0(),
.CLKOUTDCM1(),
.CLKOUTDCM2(),
.CLKOUTDCM3(),
.CLKOUTDCM4(),
.CLKOUTDCM5(),
.CLKOUT0(CLKOUT0_BUF),
.CLKOUT1(CLKOUT1_BUF),
.CLKOUT2(),
.CLKOUT3(),
.CLKOUT4(),
.CLKOUT5(),
.DO(),
.DRDY(),
.LOCKED(LOCKED_OUT));
endmodule
@@ -0,0 +1,97 @@
////////////////////////////////////////////////////////////////////////////////
// Copyright (c) 1995-2012 Xilinx, Inc. All rights reserved.
////////////////////////////////////////////////////////////////////////////////
// ____ ____
// / /\/ /
// /___/ \ / Vendor: Xilinx
// \ \ \/ Version : 14.1
// \ \ Application : xaw2verilog
// / / Filename : pl3.v
// /___/ /\ Timestamp : 06/15/2012 18:39:50
// \ \ / \
// \___\/\___\
//
//Command: xaw2verilog -intstyle C:/root/Work/Gauss/XUM/delz/ipcore_dir/pl3.xaw -st pl3.v
//Design Name: pl3
//Device: xc5vlx110t-2ff1136
//
// Module pl3
// Generated by Xilinx Architecture Wizard
// Written for synthesis tool: XST
// For block PLL_ADV_INST, Estimated PLL Jitter for CLKOUT0 = 0.171 ns
// For block PLL_ADV_INST, Estimated PLL Jitter for CLKOUT1 = 0.149 ns
// For block PLL_ADV_INST, Estimated PLL Jitter for CLKOUT2 = 0.162 ns
`timescale 1ns / 1ps
module PLL_100MHz_to_50MHz_100MHz_66MHz(CLKIN1_IN,
RST_IN,
CLKOUT0_OUT,
CLKOUT1_OUT,
CLKOUT2_OUT,
LOCKED_OUT);
input CLKIN1_IN;
input RST_IN;
output CLKOUT0_OUT;
output CLKOUT1_OUT;
output CLKOUT2_OUT;
output LOCKED_OUT;
wire CLKFBOUT_CLKFBIN;
wire CLKIN1_IBUFG;
wire CLKOUT0_BUF;
wire CLKOUT1_BUF;
wire CLKOUT2_BUF;
wire GND_BIT;
wire [4:0] GND_BUS_5;
wire [15:0] GND_BUS_16;
wire VCC_BIT;
assign GND_BIT = 0;
assign GND_BUS_5 = 5'b00000;
assign GND_BUS_16 = 16'b0000000000000000;
assign VCC_BIT = 1;
IBUFG CLKIN1_IBUFG_INST (.I(CLKIN1_IN),
.O(CLKIN1_IBUFG));
BUFG CLKOUT0_BUFG_INST (.I(CLKOUT0_BUF),
.O(CLKOUT0_OUT));
BUFG CLKOUT1_BUFG_INST (.I(CLKOUT1_BUF),
.O(CLKOUT1_OUT));
BUFG CLKOUT2_BUFG_INST (.I(CLKOUT2_BUF),
.O(CLKOUT2_OUT));
PLL_ADV #( .BANDWIDTH("OPTIMIZED"), .CLKIN1_PERIOD(10.000),
.CLKIN2_PERIOD(10.000), .CLKOUT0_DIVIDE(8), .CLKOUT1_DIVIDE(4),
.CLKOUT2_DIVIDE(6), .CLKOUT0_PHASE(0.000), .CLKOUT1_PHASE(0.000),
.CLKOUT2_PHASE(0.000), .CLKOUT0_DUTY_CYCLE(0.500),
.CLKOUT1_DUTY_CYCLE(0.500), .CLKOUT2_DUTY_CYCLE(0.500),
.COMPENSATION("SYSTEM_SYNCHRONOUS"), .DIVCLK_DIVIDE(1),
.CLKFBOUT_MULT(4), .CLKFBOUT_PHASE(0.0), .REF_JITTER(0.005000) )
PLL_ADV_INST (.CLKFBIN(CLKFBOUT_CLKFBIN),
.CLKINSEL(VCC_BIT),
.CLKIN1(CLKIN1_IBUFG),
.CLKIN2(GND_BIT),
.DADDR(GND_BUS_5[4:0]),
.DCLK(GND_BIT),
.DEN(GND_BIT),
.DI(GND_BUS_16[15:0]),
.DWE(GND_BIT),
.REL(GND_BIT),
.RST(RST_IN),
.CLKFBDCM(),
.CLKFBOUT(CLKFBOUT_CLKFBIN),
.CLKOUTDCM0(),
.CLKOUTDCM1(),
.CLKOUTDCM2(),
.CLKOUTDCM3(),
.CLKOUTDCM4(),
.CLKOUTDCM5(),
.CLKOUT0(CLKOUT0_BUF),
.CLKOUT1(CLKOUT1_BUF),
.CLKOUT2(CLKOUT2_BUF),
.CLKOUT3(),
.CLKOUT4(),
.CLKOUT5(),
.DO(),
.DRDY(),
.LOCKED(LOCKED_OUT));
endmodule
@@ -0,0 +1,82 @@
////////////////////////////////////////////////////////////////////////////////
// Copyright (c) 1995-2012 Xilinx, Inc. All rights reserved.
////////////////////////////////////////////////////////////////////////////////
// ____ ____
// / /\/ /
// /___/ \ / Vendor: Xilinx
// \ \ \/ Version : 14.1
// \ \ Application : xaw2verilog
// / / Filename : clk3.v
// /___/ /\ Timestamp : 06/06/2012 16:09:06
// \ \ / \
// \___\/\___\
//
//Command: xaw2verilog -intstyle C:/root/Work/Gauss/XUM/del/ipcore_dir/clk3.xaw -st clk3.v
//Design Name: clk3
//Device: xc5vlx110t-ff1136-2
//
// Module clk3
// Generated by Xilinx Architecture Wizard
// Written for synthesis tool: XST
// For block PLL_ADV_INST, Estimated PLL Jitter for CLKOUT0 = 0.162 ns
`timescale 1ns / 1ps
module PLL_100MHz_to_66MHz(CLKIN1_IN,
RST_IN,
CLKOUT0_OUT,
LOCKED_OUT);
input CLKIN1_IN;
input RST_IN;
output CLKOUT0_OUT;
output LOCKED_OUT;
wire CLKFBOUT_CLKFBIN;
wire CLKIN1_IBUFG;
wire CLKOUT0_BUF;
wire GND_BIT;
wire [4:0] GND_BUS_5;
wire [15:0] GND_BUS_16;
wire VCC_BIT;
assign GND_BIT = 0;
assign GND_BUS_5 = 5'b00000;
assign GND_BUS_16 = 16'b0000000000000000;
assign VCC_BIT = 1;
IBUFG CLKIN1_IBUFG_INST (.I(CLKIN1_IN),
.O(CLKIN1_IBUFG));
BUFG CLKOUT0_BUFG_INST (.I(CLKOUT0_BUF),
.O(CLKOUT0_OUT));
PLL_ADV #( .BANDWIDTH("OPTIMIZED"), .CLKIN1_PERIOD(10.000),
.CLKIN2_PERIOD(10.000), .CLKOUT0_DIVIDE(6), .CLKOUT0_PHASE(0.000),
.CLKOUT0_DUTY_CYCLE(0.500), .COMPENSATION("SYSTEM_SYNCHRONOUS"),
.DIVCLK_DIVIDE(1), .CLKFBOUT_MULT(4), .CLKFBOUT_PHASE(0.0),
.REF_JITTER(0.005000) ) PLL_ADV_INST (.CLKFBIN(CLKFBOUT_CLKFBIN),
.CLKINSEL(VCC_BIT),
.CLKIN1(CLKIN1_IBUFG),
.CLKIN2(GND_BIT),
.DADDR(GND_BUS_5[4:0]),
.DCLK(GND_BIT),
.DEN(GND_BIT),
.DI(GND_BUS_16[15:0]),
.DWE(GND_BIT),
.REL(GND_BIT),
.RST(RST_IN),
.CLKFBDCM(),
.CLKFBOUT(CLKFBOUT_CLKFBIN),
.CLKOUTDCM0(),
.CLKOUTDCM1(),
.CLKOUTDCM2(),
.CLKOUTDCM3(),
.CLKOUTDCM4(),
.CLKOUTDCM5(),
.CLKOUT0(CLKOUT0_BUF),
.CLKOUT1(),
.CLKOUT2(),
.CLKOUT3(),
.CLKOUT4(),
.CLKOUT5(),
.DO(),
.DRDY(),
.LOCKED(LOCKED_OUT));
endmodule
@@ -0,0 +1,90 @@
////////////////////////////////////////////////////////////////////////////////
// Copyright (c) 1995-2012 Xilinx, Inc. All rights reserved.
////////////////////////////////////////////////////////////////////////////////
// ____ ____
// / /\/ /
// /___/ \ / Vendor: Xilinx
// \ \ \/ Version : 14.1
// \ \ Application : xaw2verilog
// / / Filename : PLL2.v
// /___/ /\ Timestamp : 06/07/2012 10:56:40
// \ \ / \
// \___\/\___\
//
//Command: xaw2verilog -intstyle C:/root/Work/Gauss/XUM/del2/ipcore_dir/PLL2.xaw -st PLL2.v
//Design Name: PLL2
//Device: xc5vlx110t-ff1136-2
//
// Module PLL2
// Generated by Xilinx Architecture Wizard
// Written for synthesis tool: XST
// For block PLL_ADV_INST, Estimated PLL Jitter for CLKOUT0 = 0.162 ns
// For block PLL_ADV_INST, Estimated PLL Jitter for CLKOUT1 = 0.141 ns
`timescale 1ns / 1ps
module PLL_100MHz_to_66MHz_133MHz(CLKIN1_IN,
RST_IN,
CLKOUT0_OUT,
CLKOUT1_OUT,
LOCKED_OUT);
input CLKIN1_IN;
input RST_IN;
output CLKOUT0_OUT;
output CLKOUT1_OUT;
output LOCKED_OUT;
wire CLKFBOUT_CLKFBIN;
wire CLKIN1_IBUFG;
wire CLKOUT0_BUF;
wire CLKOUT1_BUF;
wire GND_BIT;
wire [4:0] GND_BUS_5;
wire [15:0] GND_BUS_16;
wire VCC_BIT;
assign GND_BIT = 0;
assign GND_BUS_5 = 5'b00000;
assign GND_BUS_16 = 16'b0000000000000000;
assign VCC_BIT = 1;
IBUFG CLKIN1_IBUFG_INST (.I(CLKIN1_IN),
.O(CLKIN1_IBUFG));
BUFG CLKOUT0_BUFG_INST (.I(CLKOUT0_BUF),
.O(CLKOUT0_OUT));
BUFG CLKOUT1_BUFG_INST (.I(CLKOUT1_BUF),
.O(CLKOUT1_OUT));
PLL_ADV #( .BANDWIDTH("OPTIMIZED"), .CLKIN1_PERIOD(10.000),
.CLKIN2_PERIOD(10.000), .CLKOUT0_DIVIDE(6), .CLKOUT1_DIVIDE(3),
.CLKOUT0_PHASE(0.000), .CLKOUT1_PHASE(0.000),
.CLKOUT0_DUTY_CYCLE(0.500), .CLKOUT1_DUTY_CYCLE(0.500),
.COMPENSATION("SYSTEM_SYNCHRONOUS"), .DIVCLK_DIVIDE(1),
.CLKFBOUT_MULT(4), .CLKFBOUT_PHASE(0.0), .REF_JITTER(0.005000) )
PLL_ADV_INST (.CLKFBIN(CLKFBOUT_CLKFBIN),
.CLKINSEL(VCC_BIT),
.CLKIN1(CLKIN1_IBUFG),
.CLKIN2(GND_BIT),
.DADDR(GND_BUS_5[4:0]),
.DCLK(GND_BIT),
.DEN(GND_BIT),
.DI(GND_BUS_16[15:0]),
.DWE(GND_BIT),
.REL(GND_BIT),
.RST(RST_IN),
.CLKFBDCM(),
.CLKFBOUT(CLKFBOUT_CLKFBIN),
.CLKOUTDCM0(),
.CLKOUTDCM1(),
.CLKOUTDCM2(),
.CLKOUTDCM3(),
.CLKOUTDCM4(),
.CLKOUTDCM5(),
.CLKOUT0(CLKOUT0_BUF),
.CLKOUT1(CLKOUT1_BUF),
.CLKOUT2(),
.CLKOUT3(),
.CLKOUT4(),
.CLKOUT5(),
.DO(),
.DRDY(),
.LOCKED(LOCKED_OUT));
endmodule
@@ -0,0 +1,95 @@
////////////////////////////////////////////////////////////////////////////////
// Copyright (c) 1995-2012 Xilinx, Inc. All rights reserved.
////////////////////////////////////////////////////////////////////////////////
// ____ ____
// / /\/ /
// /___/ \ / Vendor: Xilinx
// \ \ \/ Version : 14.1
// \ \ Application : xaw2verilog
// / / Filename : pll.v
// /___/ /\ Timestamp : 06/12/2012 10:24:28
// \ \ / \
// \___\/\___\
//
//Command: xaw2verilog -intstyle C:/root/Work/Gauss/XUM/delz/ipcore_dir/pll.xaw -st pll.v
//Design Name: pll
//Device: xc5vlx110t-ff1136-2
//
// Module pll
// Generated by Xilinx Architecture Wizard
// Written for synthesis tool: XST
// For block PLL_ADV_INST, Estimated PLL Jitter for CLKOUT0 = 0.174 ns
// For block PLL_ADV_INST, Estimated PLL Jitter for CLKOUT1 = 0.152 ns
// For block PLL_ADV_INST, Estimated PLL Jitter for CLKOUT2 = 0.133 ns
`timescale 1ns / 1ps
module PLL_100MHz_to_66MHz_133MHz_266MHz(CLKIN1_IN,
CLKOUT0_OUT,
CLKOUT1_OUT,
CLKOUT2_OUT,
LOCKED_OUT);
input CLKIN1_IN;
output CLKOUT0_OUT;
output CLKOUT1_OUT;
output CLKOUT2_OUT;
output LOCKED_OUT;
wire CLKFBOUT_CLKFBIN;
wire CLKIN1_IBUFG;
wire CLKOUT0_BUF;
wire CLKOUT1_BUF;
wire CLKOUT2_BUF;
wire GND_BIT;
wire [4:0] GND_BUS_5;
wire [15:0] GND_BUS_16;
wire VCC_BIT;
assign GND_BIT = 0;
assign GND_BUS_5 = 5'b00000;
assign GND_BUS_16 = 16'b0000000000000000;
assign VCC_BIT = 1;
IBUFG CLKIN1_IBUFG_INST (.I(CLKIN1_IN),
.O(CLKIN1_IBUFG));
BUFG CLKOUT0_BUFG_INST (.I(CLKOUT0_BUF),
.O(CLKOUT0_OUT));
BUFG CLKOUT1_BUFG_INST (.I(CLKOUT1_BUF),
.O(CLKOUT1_OUT));
BUFG CLKOUT2_BUFG_INST (.I(CLKOUT2_BUF),
.O(CLKOUT2_OUT));
PLL_ADV #( .BANDWIDTH("OPTIMIZED"), .CLKIN1_PERIOD(10.000),
.CLKIN2_PERIOD(10.000), .CLKOUT0_DIVIDE(12), .CLKOUT1_DIVIDE(6),
.CLKOUT2_DIVIDE(3), .CLKOUT0_PHASE(0.000), .CLKOUT1_PHASE(0.000),
.CLKOUT2_PHASE(0.000), .CLKOUT0_DUTY_CYCLE(0.500),
.CLKOUT1_DUTY_CYCLE(0.500), .CLKOUT2_DUTY_CYCLE(0.500),
.COMPENSATION("SYSTEM_SYNCHRONOUS"), .DIVCLK_DIVIDE(1),
.CLKFBOUT_MULT(8), .CLKFBOUT_PHASE(0.0), .REF_JITTER(0.005000) )
PLL_ADV_INST (.CLKFBIN(CLKFBOUT_CLKFBIN),
.CLKINSEL(VCC_BIT),
.CLKIN1(CLKIN1_IBUFG),
.CLKIN2(GND_BIT),
.DADDR(GND_BUS_5[4:0]),
.DCLK(GND_BIT),
.DEN(GND_BIT),
.DI(GND_BUS_16[15:0]),
.DWE(GND_BIT),
.REL(GND_BIT),
.RST(GND_BIT),
.CLKFBDCM(),
.CLKFBOUT(CLKFBOUT_CLKFBIN),
.CLKOUTDCM0(),
.CLKOUTDCM1(),
.CLKOUTDCM2(),
.CLKOUTDCM3(),
.CLKOUTDCM4(),
.CLKOUTDCM5(),
.CLKOUT0(CLKOUT0_BUF),
.CLKOUT1(CLKOUT1_BUF),
.CLKOUT2(CLKOUT2_BUF),
.CLKOUT3(),
.CLKOUT4(),
.CLKOUT5(),
.DO(),
.DRDY(),
.LOCKED(LOCKED_OUT));
endmodule
@@ -0,0 +1,39 @@
`timescale 1ns / 1ps
/*
* File : Decoder_2to4.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 14-Aug-2012 GEA Initial design.
*
* Standards/Formatting:
* 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
* 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
@@ -0,0 +1,80 @@
`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;
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 full;
reg [(ADDR_WIDTH-1):0] enQ_ptr, deQ_ptr; // Addresses for reading from and writing to internal memory
reg [(ADDR_WIDTH):0] count; // How many elements are in the FIFO (0->256)
assign empty = (count == 0);
assign 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
@@ -0,0 +1,81 @@
`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;
parameter ADDR_WIDTH = 8;
parameter RAM_DEPTH = 1 << ADDR_WIDTH;
input clock;
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 full;
reg [(ADDR_WIDTH-1):0] enQ_ptr, deQ_ptr; // Addresses for reading from and writing to internal memory
reg [(ADDR_WIDTH):0] count; // How many elements are in the FIFO (0->256)
assign empty = (count == 0);
assign 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 | clear) 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
@@ -0,0 +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
@@ -0,0 +1,26 @@
`timescale 1ns / 1ps
/*
* File : Mux2.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.
*
* Standards/Formatting:
* Verilog 2001, 4 soft tab, wide column.
*
* Description:
* 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
);
assign out = (sel) ? in1 : in0;
endmodule
@@ -0,0 +1,33 @@
`timescale 1ns / 1ps
/*
* File : Mux4.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.
*
* Standards/Formatting:
* Verilog 2001, 4 soft tab, wide column.
*
* Description:
* 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
);
always @(*) begin
case (sel)
2'b00 : out <= in0;
2'b01 : out <= in1;
2'b10 : out <= in2;
2'b11 : out <= in3;
endcase
end
endmodule
@@ -0,0 +1,38 @@
`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,
* 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.
*/
module SRAM(clock, wEn, rAddr, wAddr, dIn, dOut);
parameter DATA_WIDTH = 8;
parameter ADDR_WIDTH = 8;
parameter RAM_DEPTH = 1 << ADDR_WIDTH;
input clock;
input wEn;
input [(ADDR_WIDTH-1):0] rAddr;
input [(ADDR_WIDTH-1):0] wAddr;
input [(DATA_WIDTH-1):0] dIn;
output [(DATA_WIDTH-1):0] dOut;
reg [(DATA_WIDTH-1):0] mem [0:(RAM_DEPTH-1)];
assign dOut = mem[rAddr];
always @(posedge clock) begin
if (wEn) mem[wAddr] <= dIn;
end
endmodule
@@ -0,0 +1,55 @@
`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.
*/
module I2C_Clock(
input clock, // 100 (66) MHz
input reset,
inout scl, // A 100 (66) kHz clock
output scl_tick_90 // A pulse indicating the middle of the +/- scl levels
);
reg [7:0] count_4x;
always @(posedge clock) begin
//count_4x <= (reset) ? 8'h00 : (scl) ? count_4x + 1 : count_4x;
count_4x <= (reset) ? 8'h00 : count_4x + 1; // XXX SIMULATION ONLY
end
// A single pulse once every 250 cycles
wire tick_4x = (count_4x == 8'hFA);
reg [1:0] state;
always @(posedge clock) begin
if (reset) begin
state <= 2'b00;
end
else begin
case (state)
2'd0 : state <= (tick_4x) ? 2'd1 : 2'd0;
2'd1 : state <= (tick_4x) ? 2'd2 : 2'd1;
2'd2 : state <= (tick_4x) ? 2'd3 : 2'd2;
2'd3 : state <= (tick_4x) ? 2'd0 : 2'd3;
endcase
end
end
assign scl = ((state == 2'd0) || (state == 2'd1));
assign scl_tick_90 = tick_4x & ((state == 2'd0) || (state == 2'd2));
endmodule
@@ -0,0 +1,98 @@
`timescale 1ns / 1ps
/*
* File : I2C_Controller.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 25-Jun-2012 GEA Initial design.
*
* Standards/Formatting:
* Verilog 2001, 4 soft tab, wide column.
*
* Description:
* A top-level I2C controller which bridges the I2C physical layer with
* the data memory bus. This controller accepts the following commands:
*
* Clear : [Bit 8] Empties the I2C FIFO of all data.
* EnQ : [Bit 9] Enqueues a byte of data to the FIFO for transmission.
* Tx : [Bit 10] Transmits all bytes within the FIFO.
* Rx : [Bit 11] Transmits the first byte in the FIFO (bus address),
* then receives a requested number of bytes into the FIFO.
* RxN : [Bit 12] Sets the number of bytes to receive on an 'Rx' command.
*
* To read data from the FIFO, the data memory bus issues a Read command. The received
* data is arranged as follows:
*
* Bit 10 : 'Nack' which indicates if the last Tx/Rx command did not receive
* an acknowledgment from the slave device.
* Bit 9 : Indicates if the FIFO is currently full.
* Bit 8 : Indicates if the FIFO is currently empty.
* Bit 7-0 : The first byte in the FIFO.
*/
module I2C_Controller(
input clock,
input reset,
input Read,
input Write,
input [12:0] DataIn,
output [10:0] DataOut,
output Ack,
inout i2c_scl,
inout i2c_sda
);
// I2C Physical layer signals
wire I2C_Read, I2C_Write;
wire I2C_ReadCountSet;
wire I2C_EnQ, I2C_DeQ, I2C_Clear;
wire [7:0] I2C_DataIn, I2C_DataOut;
wire I2C_Ack, I2C_Nack;
wire I2C_FifoEmpty, I2C_FifoFull;
wire Cmd_Clear = DataIn[8];
wire Cmd_EnQ = DataIn[9];
wire Cmd_Tx = DataIn[10];
wire Cmd_Rx = DataIn[11];
wire Cmd_RxN = DataIn[12];
assign I2C_Read = Write & Cmd_Rx;
assign I2C_Write = Write & Cmd_Tx;
assign I2C_ReadCountSet = Write & Cmd_RxN;
assign I2C_EnQ = Write & Cmd_EnQ;
assign I2C_DeQ = Read;
assign I2C_Clear = Write & Cmd_Clear;
assign I2C_DataIn = DataIn[7:0];
assign DataOut[7:0] = I2C_DataOut;
assign DataOut[8] = I2C_FifoEmpty;
assign DataOut[9] = I2C_FifoFull;
assign DataOut[10] = I2C_Nack;
assign Ack = I2C_Ack;
// I2C Physical layer
I2C_Phy PHY (
.clock (clock),
.reset (reset),
.Read (I2C_Read),
.Write (I2C_Write),
.ReadCountSet (I2C_ReadCountSet),
.EnQ (I2C_EnQ),
.DeQ (I2C_DeQ),
.Clear (I2C_Clear),
.DataIn (I2C_DataIn),
.DataOut (I2C_DataOut),
.Ack (I2C_Ack),
.Nack (I2C_Nack),
.Fifo_Empty (I2C_FifoEmpty),
.Fifo_Full (I2C_FifoFull),
.i2c_scl (i2c_scl),
.i2c_sda (i2c_sda)
);
endmodule
@@ -0,0 +1,237 @@
`timescale 1ns / 1ps
/*
* File : I2C_Phy.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 25-Jun-2012 GEA Initial design.
*
* Standards/Formatting:
* Verilog 2001, 4 soft tab, wide column.
*
* Description:
* I2C Master controller made for a single-master I2C bus.
* Uses a FIFO to store transmit and receive data, and is made
* to be generic enough to use with a wide variety of I2C slave devices.
* A Read command sends a bus address byte then receives a requested number
* of bytes, while a Write command writes all bytes that are presently in
* the FIFO.
*/
module I2C_Phy(
input clock,
input reset,
input Read,
input Write,
input ReadCountSet,
input EnQ,
input DeQ,
input Clear,
input [7:0] DataIn,
output reg [7:0] DataOut,
output Ack,
output reg Nack,
output Fifo_Empty,
output Fifo_Full,
inout i2c_scl,
inout i2c_sda
);
localparam [5:0] IDLE=0, ENQ=1, DEQ=2, START=3, ADDR6=4, ADDR5=5, ADDR4=6, ADDR3=7, ADDR2=8,
ADDR1=9, ADDR0=10, RWBIT=11, A_DEQ=12, A_ACK=13, WDWAIT=14, WDATA7=15,
WDATA6=16, WDATA5=17, WDATA4=18, WDATA3=19, WDATA2=20, WDATA1=21, WDATA0=22,
W_DEQ=23, W_ACK=24, RDATA7=25, RDATA6=26, RDATA5=27, RDATA4=28, RDATA3=29,
RDATA2=30, RDATA1=31, RDATA0=32, R_ENQ=33, R_ACKW=34, R_ACK=35, NACK=36,
STOPW=37, STOP=38, BUSW=39, CLEAR=40, RNSET=41;
// FIFO signals
wire Fifo_Clear, Fifo_EnQ, Fifo_DeQ;
wire [7:0] Fifo_In, Fifo_Out;
wire scl, scl_tick_90;
reg [5:0] state;
reg [7:0] Rx_Data;
reg sda;
reg [7:0] Rx_Todo, Rx_Remain;
// The I2C bus is high-impedance instead of a driven 1.
assign i2c_sda = (sda) ? 1'bz : 1'b0;
assign i2c_scl = (scl | (state == IDLE)) ? 1'bz : 1'b0;
// Control logic : 4-way handshaking
assign Ack = (state == BUSW);
always @(posedge clock) begin
Rx_Todo <= (reset) ? 8'h00 : ((state == RNSET) ? DataIn : Rx_Todo);
Rx_Remain <= (reset) ? 8'h00 : ((state == IDLE) ? Rx_Todo : ((state == R_ENQ) ? Rx_Remain - 1 : Rx_Remain));
end
always @(posedge clock) begin
DataOut <= (reset) ? 8'h00 : ((state == DEQ) ? Fifo_Out : DataOut);
end
always @(posedge clock) begin
Nack <= (reset | (state == START)) ? 0 : ((state == NACK) ? 1 : Nack);
end
assign Fifo_EnQ = (state == ENQ) || (state == R_ENQ);
assign Fifo_DeQ = (state == DEQ) || (state == A_DEQ) || (state == W_DEQ);
assign Fifo_In = (state == R_ENQ) ? Rx_Data : DataIn;
assign Fifo_Clear = (state == CLEAR);
// Main state machine
always @(posedge clock) begin
if (reset) begin
state <= IDLE;
end
else begin
case (state)
IDLE: begin
if (EnQ) state <= ENQ;
else if (DeQ) state <= DEQ;
else if (Clear) state <= CLEAR;
else if (ReadCountSet) state <= RNSET;
else if ((Read | Write) & scl & scl_tick_90) state <= START;
else state <= IDLE;
end
ENQ: state <= BUSW;
DEQ: state <= BUSW;
CLEAR: state <= BUSW;
RNSET: state <= BUSW;
START: state <= (~scl & scl_tick_90) ? ADDR6 : START;
ADDR6: state <= (~scl & scl_tick_90) ? ADDR5 : ADDR6;
ADDR5: state <= (~scl & scl_tick_90) ? ADDR4 : ADDR5;
ADDR4: state <= (~scl & scl_tick_90) ? ADDR3 : ADDR4;
ADDR3: state <= (~scl & scl_tick_90) ? ADDR2 : ADDR3;
ADDR2: state <= (~scl & scl_tick_90) ? ADDR1 : ADDR2;
ADDR1: state <= (~scl & scl_tick_90) ? ADDR0 : ADDR1;
ADDR0: state <= (~scl & scl_tick_90) ? RWBIT : ADDR0;
RWBIT: state <= (~scl & scl_tick_90) ? A_DEQ : RWBIT;
A_DEQ: state <= A_ACK;
A_ACK: state <= ( scl & scl_tick_90) ? ((i2c_sda) ? NACK : ((Read) ? RDATA7 : WDWAIT)) : A_ACK;
// Writes
WDWAIT: state <= (~scl & scl_tick_90) ? WDATA7 : WDWAIT;
WDATA7: state <= (~scl & scl_tick_90) ? WDATA6 : WDATA7;
WDATA6: state <= (~scl & scl_tick_90) ? WDATA5 : WDATA6;
WDATA5: state <= (~scl & scl_tick_90) ? WDATA4 : WDATA5;
WDATA4: state <= (~scl & scl_tick_90) ? WDATA3 : WDATA4;
WDATA3: state <= (~scl & scl_tick_90) ? WDATA2 : WDATA3;
WDATA2: state <= (~scl & scl_tick_90) ? WDATA1 : WDATA2;
WDATA1: state <= (~scl & scl_tick_90) ? WDATA0 : WDATA1;
WDATA0: state <= (~scl & scl_tick_90) ? W_DEQ : WDATA0;
W_DEQ: state <= W_ACK;
W_ACK: state <= ( scl & scl_tick_90) ? ((i2c_sda) ? NACK : ((Fifo_Empty) ? STOPW : WDWAIT)) : W_ACK;
// Reads
RDATA7: state <= ( scl & scl_tick_90) ? RDATA6 : RDATA7;
RDATA6: state <= ( scl & scl_tick_90) ? RDATA5 : RDATA6;
RDATA5: state <= ( scl & scl_tick_90) ? RDATA4 : RDATA5;
RDATA4: state <= ( scl & scl_tick_90) ? RDATA3 : RDATA4;
RDATA3: state <= ( scl & scl_tick_90) ? RDATA2 : RDATA3;
RDATA2: state <= ( scl & scl_tick_90) ? RDATA1 : RDATA2;
RDATA1: state <= ( scl & scl_tick_90) ? RDATA0 : RDATA1;
RDATA0: state <= ( scl & scl_tick_90) ? R_ENQ : RDATA0;
R_ENQ: state <= R_ACKW;
R_ACKW: state <= (~scl & scl_tick_90) ? R_ACK : R_ACKW;
R_ACK: state <= (~scl & scl_tick_90) ? ((Rx_Remain != 8'h00) ? RDATA7 : STOP) : R_ACK;
// Termination
NACK: state <= STOPW;
STOPW: state <= (~scl & scl_tick_90) ? STOP : STOPW;
STOP: state <= ( scl & scl_tick_90) ? BUSW : STOP;
BUSW: state <= (Read | Write | EnQ | DeQ) ? BUSW : IDLE;
default: state <= 6'bxxxxxx;
endcase
end
end
// Incoming data capture
always @(posedge clock) begin
if (reset) begin
Rx_Data <= 8'h00;
end
else begin
Rx_Data[7] <= ((state == RDATA7) & scl & scl_tick_90) ? i2c_sda : Rx_Data[7];
Rx_Data[6] <= ((state == RDATA6) & scl & scl_tick_90) ? i2c_sda : Rx_Data[6];
Rx_Data[5] <= ((state == RDATA5) & scl & scl_tick_90) ? i2c_sda : Rx_Data[5];
Rx_Data[4] <= ((state == RDATA4) & scl & scl_tick_90) ? i2c_sda : Rx_Data[4];
Rx_Data[3] <= ((state == RDATA3) & scl & scl_tick_90) ? i2c_sda : Rx_Data[3];
Rx_Data[2] <= ((state == RDATA2) & scl & scl_tick_90) ? i2c_sda : Rx_Data[2];
Rx_Data[1] <= ((state == RDATA1) & scl & scl_tick_90) ? i2c_sda : Rx_Data[1];
Rx_Data[0] <= ((state == RDATA0) & scl & scl_tick_90) ? i2c_sda : Rx_Data[0];
end
end
// I2C data line assignment
always @(*) begin
case (state)
IDLE: sda <= 1;
ENQ: sda <= 1;
DEQ: sda <= 1;
CLEAR: sda <= 1;
START: sda <= 0;
ADDR6: sda <= Fifo_Out[6];
ADDR5: sda <= Fifo_Out[5];
ADDR4: sda <= Fifo_Out[4];
ADDR3: sda <= Fifo_Out[3];
ADDR2: sda <= Fifo_Out[2];
ADDR1: sda <= Fifo_Out[1];
ADDR0: sda <= Fifo_Out[0];
RWBIT: sda <= Read; // 0 is write, 1 is read
A_DEQ: sda <= 1;
A_ACK: sda <= 1;
WDWAIT: sda <= 1;
WDATA7: sda <= Fifo_Out[7];
WDATA6: sda <= Fifo_Out[6];
WDATA5: sda <= Fifo_Out[5];
WDATA4: sda <= Fifo_Out[4];
WDATA3: sda <= Fifo_Out[3];
WDATA2: sda <= Fifo_Out[2];
WDATA1: sda <= Fifo_Out[1];
WDATA0: sda <= Fifo_Out[0];
W_DEQ: sda <= 1;
W_ACK: sda <= 1;
RDATA7: sda <= 1;
RDATA6: sda <= 1;
RDATA5: sda <= 1;
RDATA4: sda <= 1;
RDATA3: sda <= 1;
RDATA2: sda <= 1;
RDATA1: sda <= 1;
RDATA0: sda <= 1;
R_ENQ: sda <= 1;
R_ACKW: sda <= 1;
R_ACK: sda <= (Rx_Remain == 8'h00); // Low for more data, high for done
NACK: sda <= 1;
STOPW: sda <= 1;
STOP: sda <= 0;
BUSW: sda <= 1;
default: sda <= 1;
endcase
end
// I2C Clock Generation
I2C_Clock I2C_Clock (
.clock (clock),
.reset (reset),
.scl (scl),
.scl_tick_90 (scl_tick_90)
);
FIFO_Clear FIFO (
.clock (clock),
.reset (reset),
.clear (Fifo_Clear),
.enQ (Fifo_EnQ),
.deQ (Fifo_DeQ),
.data_in (Fifo_In),
.data_out (Fifo_Out),
.empty (Fifo_Empty),
.full (Fifo_Full)
);
endmodule
@@ -0,0 +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]);
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
@@ -0,0 +1,139 @@
`timescale 1ns / 1ps
/*
* File : lcd_ctrl.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-2011 GEA Initial design.
*
* Standards/Formatting:
* Verilog 2001, 4 soft tab, wide column.
*
* Description:
* A controller for the common 16x2-character LCD screen based on the
* Sitronix ST7066U, Samsung S6A0069X / KS0066U, Hitachi HD44780, SMOS SED1278,
* or other compatible device. This controller uses a 4-bit data bus, is write-only,
* and requires a total of 7 output pins to the LCD. The timing must be adjusted for
* different input clock frequencies where noted. The primary version is based on a
* 100 MHz clock.
*/
module lcd_ctrl(
input clock,
input reset,
input [8:0] command,
input write,
output reg ack,
//---------------------------------
output reg [3:0] LCD_D, // 4-bit LCD data bus
output reg LCD_E, // Enable
output LCD_RS, // Register Select (0->Register; 1->Data)
output LCD_RW // Read/Write (0->Write; 1->Read)
);
localparam [4:0] INIT_1=1, INIT_2=2, INIT_3=3, INIT_4=4, INIT_5=5, INIT_6=6, INIT_7=7, INIT_8=8,
CMD_WAIT=9, NOP=10, U_SETUP=11, U_ENAB=12, U_HOLD=13, UL_WAIT=14, L_SETUP=15,
L_ENAB=16, L_HOLD=17;
reg [18:0] count;
reg [18:0] compare;
reg [4:0] state;
wire bell;
wire long_instr;
assign LCD_RW = 0; // There is no reason to read from the LCD screen.
assign LCD_RS = command[8];
assign bell = (count == compare);
assign long_instr = ((command == 9'b0_0000_0001) || (command[8:1] == 8'b0_0000_001));
/* The count register increments until it equals 'compare' */
always @(posedge clock) begin
count <= (reset | bell) ? 19'b0 : count + 1;
end
/* Time delays for various states */
always @(*) begin
case (state)
INIT_1 : compare <= 19'd410000; // 15ms (4.1ms OK due to power-up delay)
INIT_2 : compare <= 19'd24; // 240 ns
INIT_3 : compare <= 19'd410000; // 4.1 ms
INIT_4 : compare <= 19'd24; // 240 ns
INIT_5 : compare <= 19'd10000; // 100 us or longer
INIT_6 : compare <= 19'd24; // 240 ns
INIT_7 : compare <= 19'd4000; // 40 us or longer
INIT_8 : compare <= 19'd24; // 240 ns
CMD_WAIT : compare <= (long_instr) ? 19'd164000 : 19'd4000; // 40 us or 1.64 ms
NOP : compare <= 19'hxxxxx;
U_SETUP : compare <= 19'd4; // 40 ns
U_ENAB : compare <= 19'd23; // 230 ns
U_HOLD : compare <= 19'd1; // 10 ns
UL_WAIT : compare <= 19'd100; // 1 us
L_SETUP : compare <= 19'd4; // 40 ns
L_ENAB : compare <= 19'd23; // 230 ns
L_HOLD : compare <= 19'd1; // 10 ns
default : compare <= 19'hxxxxx;
endcase
end
/* The 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) ? INIT_5 : INIT_4;
INIT_5 : state <= (bell) ? INIT_6 : INIT_5;
INIT_6 : state <= (bell) ? INIT_7 : INIT_6;
INIT_7 : state <= (bell) ? INIT_8 : INIT_7;
INIT_8 : state <= (bell) ? CMD_WAIT : INIT_8;
CMD_WAIT : state <= (bell) ? NOP : CMD_WAIT;
NOP : state <= (write & ~ack) ? U_SETUP : NOP;
U_SETUP : state <= (bell) ? U_ENAB : U_SETUP;
U_ENAB : state <= (bell) ? U_HOLD : U_ENAB;
U_HOLD : state <= (bell) ? UL_WAIT : U_HOLD;
UL_WAIT : state <= (bell) ? L_SETUP : UL_WAIT;
L_SETUP : state <= (bell) ? L_ENAB : L_SETUP;
L_ENAB : state <= (bell) ? L_HOLD : L_ENAB;
L_HOLD : state <= (bell) ? CMD_WAIT : L_HOLD;
default : state <= 5'bxxxxx;
endcase
end
end
/* Combinatorial enable and data assignments */
always @(*) begin
case (state)
INIT_1 : begin LCD_E <= 0; LCD_D <= 4'b0000; end
INIT_2 : begin LCD_E <= 0; LCD_D <= 4'b0011; end
INIT_3 : begin LCD_E <= 0; LCD_D <= 4'b0000; end
INIT_4 : begin LCD_E <= 1; LCD_D <= 4'b0011; end
INIT_5 : begin LCD_E <= 0; LCD_D <= 4'b0000; end
INIT_6 : begin LCD_E <= 1; LCD_D <= 4'b0011; end
INIT_7 : begin LCD_E <= 0; LCD_D <= 4'b0000; end
INIT_8 : begin LCD_E <= 1; LCD_D <= 4'b0010; end
CMD_WAIT : begin LCD_E <= 0; LCD_D <= 4'b0000; end
NOP : begin LCD_E <= 0; LCD_D <= 4'b0000; end
U_SETUP : begin LCD_E <= 0; LCD_D <= command[7:4]; end
U_ENAB : begin LCD_E <= 1; LCD_D <= command[7:4]; end
U_HOLD : begin LCD_E <= 0; LCD_D <= command[7:4]; end
UL_WAIT : begin LCD_E <= 0; LCD_D <= 4'b0000; end
L_SETUP : begin LCD_E <= 0; LCD_D <= command[3:0]; end
L_ENAB : begin LCD_E <= 1; LCD_D <= command[3:0]; end
L_HOLD : begin LCD_E <= 0; LCD_D <= command[3:0]; end
default : begin LCD_E <= 0; LCD_D <= 4'b0000; end
endcase
end
/* Full 4-way Handshake */
always @(posedge clock) begin
ack <= (reset | ~write) ? 0 : (((state == L_HOLD) && (bell == 1'b1)) ? 1 : ack);
end
endmodule
@@ -0,0 +1,49 @@
`timescale 1ns / 1ps
/*
* File : LED.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 13-Jul-2012 GEA Initial design.
*
* Standards/Formatting:
* Verilog 2001, 4 soft tab, wide column.
*
* Description:
* A read/write interface between a 4-way handshaking data bus and
* 8 LEDs.
*
* An optional mode allows the LEDs to show current interrupts
* instead of bus data.
*/
module LED(
input clock,
input reset,
input [14:0] dataIn,
input [7:0] IP,
input Write,
input Read,
output [13:0] dataOut,
output reg Ack,
output [13:0] LED
);
reg [13:0] data;
reg useInterrupts;
always @(posedge clock) begin
data <= (reset) ? 14'b0 : ((Write) ? dataIn[13:0] : data);
useInterrupts <= (reset) ? 0 : ((Write) ? dataIn[14] : useInterrupts);
end
always @(posedge clock) begin
Ack <= (reset) ? 0 : (Write | Read);
end
assign LED = (useInterrupts) ? {6'b0, IP[7:0]} : data;
assign dataOut = data;
endmodule
@@ -0,0 +1,290 @@
`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,
output ALU_Stall // Stalls due to long ALU operations
);
`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.
***/
/***
Divider Logic:
The hardware divider requires 32 cycles to complete. Because it writes its
results to HILO and not to the pipeline, the pipeline can proceed without
stalling. When a later instruction tries to access HILO, the pipeline will
stall if the divide operation has not yet completed.
***/
// Internal state registers
reg [63:0] HILO;
reg HILO_Access; // Behavioral; not DFFs
reg [5:0] CLO_Result, CLZ_Result; // Behavioral; not DFFs
reg div_fsm;
// Internal signals
wire [31:0] HI, LO;
wire HILO_Commit;
wire signed [31:0] As, Bs;
wire AddSub_Add;
wire signed [31:0] AddSub_Result;
wire signed [63:0] Mult_Result;
wire [63:0] Multu_Result;
wire [31:0] Quotient;
wire [31:0] Remainder;
wire Div_Stall;
wire Div_Start, Divu_Start;
wire DivOp;
wire Div_Commit;
// Assignments
assign HI = HILO[63:32];
assign LO = HILO[31:0];
assign HILO_Commit = ~(EX_Stall | EX_Flush);
assign As = A;
assign Bs = B;
assign AddSub_Add = ((Operation == AluOp_Add) | (Operation == AluOp_Addu));
assign AddSub_Result = (AddSub_Add) ? (A + B) : (A - B);
assign Mult_Result = As * Bs;
assign Multu_Result = A * B;
assign BZero = (B == 32'h00000000);
assign DivOp = (Operation == AluOp_Div) || (Operation == AluOp_Divu);
assign Div_Commit = (div_fsm == 1'b1) && (Div_Stall == 1'b0);
assign Div_Start = (div_fsm == 1'b0) && (Operation == AluOp_Div) && (HILO_Commit == 1'b1);
assign Divu_Start = (div_fsm == 1'b0) && (Operation == AluOp_Divu) && (HILO_Commit == 1'b1);
assign ALU_Stall = (div_fsm == 1'b1) && (HILO_Access == 1'b1);
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_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 (Div_Commit) begin
HILO <= {Remainder, Quotient};
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 accesses to HILO. RAW and WAW hazards are possible while a
// divide operation is computing, so reads and writes to HILO must stall
// while the divider is busy.
// (This logic could be put into an earlier pipeline stage or into the
// datapath bits to improve timing.)
always @(Operation) begin
case (Operation)
AluOp_Div : HILO_Access <= 1;
AluOp_Divu : HILO_Access <= 1;
AluOp_Mfhi : HILO_Access <= 1;
AluOp_Mflo : HILO_Access <= 1;
AluOp_Mult : HILO_Access <= 1;
AluOp_Multu : HILO_Access <= 1;
AluOp_Madd : HILO_Access <= 1;
AluOp_Maddu : HILO_Access <= 1;
AluOp_Msub : HILO_Access <= 1;
AluOp_Msubu : HILO_Access <= 1;
AluOp_Mthi : HILO_Access <= 1;
AluOp_Mtlo : HILO_Access <= 1;
default : HILO_Access <= 0;
endcase
end
// Divider FSM: The divide unit is either available or busy.
always @(posedge clock) begin
if (reset) begin
div_fsm <= 2'd0;
end
else begin
case (div_fsm)
1'd0 : div_fsm <= (DivOp & HILO_Commit) ? 1'd1 : 1'd0;
1'd1 : div_fsm <= (~Div_Stall) ? 1'd0 : 1'd1;
endcase
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
// Multicycle divide unit
Divide Divider (
.clock (clock),
.reset (reset),
.OP_div (Div_Start),
.OP_divu (Divu_Start),
.Dividend (A),
.Divisor (B),
.Quotient (Quotient),
.Remainder (Remainder),
.Stall (Div_Stall)
);
endmodule
@@ -0,0 +1,26 @@
`timescale 1ns / 1ps
/*
* File : Add.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.
*
* Standards/Formatting:
* Verilog 2001, 4 soft tab, wide column.
*
* Description:
* 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);
endmodule
@@ -0,0 +1,529 @@
`timescale 1ns / 1ps
/*
* File : CPZero.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-Sep-2011 GEA Initial design.
* 2.0 14-May-2012 GEA Complete rework.
*
* Standards/Formatting:
* Verilog 2001, 4 soft tab, wide column.
*
* Description:
* The MIPS-32 Coprocessor 0 (CP0). This is the processor management unit that allows
* interrupts, traps, system calls, and other exceptions. It distinguishes
* user and kernel modes, provides status information, and can override program
* flow. This processor is designed for "bare metal" memory access and thus does
* not have virtual memory hardware as a part of it. However, the subset of CP0
* is MIPS-32-compliant.
*/
module CPZero(
input clock,
//-- CP0 Functionality --//
input Mfc0, // CPU instruction is Mfc0
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 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
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)
// input EXC_SReset, // Soft Reset (not implemented)
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 [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
input ID_IsFlushed,
input IF_IsBD, // Indicator of IF exception being a branch delay slot instruction
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_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)
input M_CanErr, // Memory stage can error (i.e. cause exception)
//-- Exception Control Flow --/
output IF_Exception_Stall,
output ID_Exception_Stall,
output EX_Exception_Stall,
output M_Exception_Stall,
output IF_Exception_Flush,
output ID_Exception_Flush,
output EX_Exception_Flush,
output M_Exception_Flush,
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"
/***
Exception Control Flow Notes
- Exceptions can occur in every pipeline stage. This implies that more than one exception
can be raised in a single cycle. When this occurs, only the forward-most exception
(i.e. MEM over EX) is handled. This and the following note guarantee program order.
- An exception in any pipeline stage must stall that stage until all following stages are
exception-free. This is because it only makes sense for exceptions to occur in program order.
- A pipeline stage which causes an exception must flush, i.e. prevent any commits it would
have normally made and convert itself to a NOP for the next pipeline stage. Furthermore,
it must flush all previous pipeline stages as well in order to retain program order.
- Instructions reading CP0 (mtc0) read in ID without further action. Writes to CP0 (mtc0,
eret) also write in ID, but only after forward pipeline stages have been cleared
of possible exceptions. This prevents many insidious bugs, such as switching to User Mode
in ID when a legitimate memory access in kernel mode is processing in MEM, or conversely
a switch to Kernel Mode in ID when an instruction in User Mode is attempting a kernel region
memory access (when a kernel mode signal does not propagate through the pipeline).
- Commits occur in ID (CP0), EX (HILO), MEM, and WB (registers).
- Hardware interrupts are detected and inserted in the ID stage, but only when there are no
other possible exceptions in the pipeline. Because they appear 'asynchronous' to the
processor, the remaining instructions in forward stages (EX, MEM, WB) can either be
flushed or completed. It is simplest to have them complete to avoid restarts, but the
interrupt latency is higher if e.g. the MEM stage stalls on a memory access (this would
be unavoidable on single-cycle processors). This implementation allows all forward instructions
to complete, for a greater instruction throughput but higher interrupt latency.
- Software interrupts should appear synchronous in the program order, meaning that all
instructions previous to them should complete and no instructions after them should start
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
***/
// Exceptions Generated Internally
wire EXC_CpU;
// Hardware Interrupt #5, caused by Timer/Perf counter
wire Int5;
// Top-level Authoritative Interrupt Signal
wire EXC_Int;
// General Exception detection (all but Interrupts, Reset, Soft Reset, and NMI)
wire EXC_General = EXC_AdIF | EXC_AdEL | EXC_AdES | EXC_Ov | EXC_Tr | EXC_Sys | EXC_Bp | EXC_RI | EXC_CpU;
// Misc
wire CP0_WriteCond;
reg [3:0] Cause_ExcCode_bits;
reg reset_r;
always @(posedge clock) begin
reset_r <= reset;
end
/***
MIPS-32 COPROCESSOR 0 (Cp0) REGISTERS
These are defined in "MIPS32 Architecture for Programmers Volume III:
The MIPS32 Privileged Resource Architecture" from MIPS Technologies, Inc.
Optional registers are omitted. Changes to the processor (such as adding
an MMU/TLB, etc. must be reflected in these registers.
*/
// BadVAddr Register (Register 8, Select 0)
reg [31:0] BadVAddr;
// Count Register (Register 9, Select 0)
reg [31:0] Count;
// Compare Register (Register 11, Select 0)
reg [31:0] Compare;
// Status Register (Register 12, Select 0)
wire [2:0] Status_CU_321 = 3'b000;
reg Status_CU_0; // Access Control to CPs, [2]->Cp3, ... [0]->Cp0
wire Status_RP = 0;
wire Status_FR = 0;
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)
wire Status_TS = 0;
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;
reg [7:0] Status_IM; // Interrupt mask
wire Status_KX = 0;
wire Status_SX = 0;
wire Status_UX = 0;
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_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,
Status_PX, Status_BEV, Status_TS, Status_SR, Status_NMI, Status_RES,
Status_Custom, Status_IM, Status_KX, Status_SX, Status_UX,
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)
wire Cause_WP = 0;
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,
6'b000000, Cause_IP, 1'b0, Cause_ExcCode4, Cause_ExcCode30, 2'b00};
// Exception Program Counter (Register 14, Select 0)
reg [31:0] EPC;
// Processor Identification (Register 15, Select 0)
wire [7:0] ID_Options = 8'b0000_0000;
wire [7:0] ID_CID = 8'b0000_0000;
wire [7:0] ID_PID = 8'b0000_0000;
wire [7:0] ID_Rev = 8'b0000_0001;
wire [31:0] PRId = {ID_Options, ID_CID, ID_PID, ID_Rev};
// 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 [1:0] Config_AT = 2'b00;
wire [2:0] Config_AR = 3'b000;
wire [2:0] Config_MT = 3'b000;
wire [2:0] Config_K0 = 3'b000;
wire [31:0] Config = {Config_M, Config_Impl, Config_BE, Config_AT, Config_AR, Config_MT,
4'b0000, Config_K0};
// Configuration Register 1 (Register 16, Select 1)
wire Config1_M = 0;
wire [5:0] Config1_MMU = 6'b000000;
wire [2:0] Config1_IS = 3'b000;
wire [2:0] Config1_IL = 3'b000;
wire [2:0] Config1_IA = 3'b000;
wire [2:0] Config1_DS = 3'b000;
wire [2:0] Config1_DL = 3'b000;
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_CA = 0;
wire Config1_EP = 0;
wire Config1_FP = 0;
wire [31:0] Config1 = {Config1_M, Config1_MMU, Config1_IS, Config1_IL, Config1_IA,
Config1_DS, Config1_DL, Config1_DA, Config1_C2,
Config1_MD, Config1_PC, Config1_WR, Config1_CA,
Config1_EP, Config1_FP};
// Performance Counter Register (Register 25) XXX TODO
// ErrorEPC Register (Register 30, Select 0)
reg [31:0] ErrorEPC;
// Exception Detection and Processing
wire M_Exception_Detect, EX_Exception_Detect, ID_Exception_Detect, IF_Exception_Detect;
wire M_Exception_Mask, EX_Exception_Mask, ID_Exception_Mask, IF_Exception_Mask;
wire M_Exception_Ready, EX_Exception_Ready, ID_Exception_Ready, IF_Exception_Ready;
assign IP = Cause_IP;
/*** Coprocessor Unusable Exception ***/
assign EXC_CpU = COP1 | COP2 | COP3 | ((Mtc0 | Mfc0 | ERET) & ~(Status_CU_0 | KernelMode));
/*** Kernel Mode Signal ***/
assign KernelMode = ~Status_UM | Status_EXL | Status_ERL;
/*** Reverse Endian for User Mode ***/
assign ReverseEndian = Status_RE;
/*** Interrupts ***/
assign Int5 = (Count == Compare);
//assign EXC_Int = ((Cause_IP[7:0] & Status_IM[7:0]) != 8'h00) & Status_IE & ~Status_EXL & ~Status_ERL & ~ID_IsFlushed;
wire Enabled_Interrupt = EXC_NMI | (Status_IE & ((Cause_IP[7:0] & Status_IM[7:0]) != 8'h00));
assign EXC_Int = Enabled_Interrupt & ~Status_EXL & ~Status_ERL & ~ID_IsFlushed;
assign CP0_WriteCond = (Status_CU_0 | KernelMode) & Mtc0 & ~ID_Stall;
/***
Exception Hazard Flow Control Explanation:
- An exception at any time in any stage causes its own and any previous stages to
flush (clear own commits, NOPS to fwd stages).
- An exception in a stage can also stall that stage (and inherently all previous stages) if and only if:
1. A forward stage is capable of causing an exception AND
2. A forward stage is not currently causing an exception.
- An exception is ready to process when it is detected and not stalled in a stage.
Flush specifics per pipeline stage:
MEM: Mask 'MemWrite' and 'MemRead' (for performance) after EX/M and before data memory. NOPs to M/WB.
EX : Mask writes to HI/LO. NOPs to EX/M.
ID : Mask writes (reads?) to CP0. NOPs to ID/EX.
IF : NOP to IF/ID.
***/
/*** Exceptions grouped by pipeline stage ***/
assign M_Exception_Detect = EXC_AdEL | EXC_AdES | EXC_Tr;
assign EX_Exception_Detect = EXC_Ov;
assign ID_Exception_Detect = EXC_Sys | EXC_Bp | EXC_RI | EXC_CpU | EXC_Int;
assign IF_Exception_Detect = EXC_AdIF;
/*** Exception mask conditions ***/
// A potential bug would occur if e.g. EX stalls, MEM has data, but MEM is not stalled and finishes
// going through the pipeline so forwarding would fail. This is not a problem however because
// EX would not need data since it would flush on an exception.
assign M_Exception_Mask = IF_Stall;
assign EX_Exception_Mask = IF_Stall | M_CanErr;
assign ID_Exception_Mask = IF_Stall | M_CanErr | EX_CanErr;
assign IF_Exception_Mask = M_CanErr | EX_CanErr | ID_CanErr | EXC_Int;
/***
Exceptions which must wait for forward stages. A stage will not stall if a forward stage has an exception.
These stalls must be inserted as stall conditions in the hazard unit so that it will take care of chaining.
All writes to CP0 must also wait for forward hazard conditions to clear.
*/
assign M_Exception_Stall = M_Exception_Detect & M_Exception_Mask;
assign EX_Exception_Stall = EX_Exception_Detect & EX_Exception_Mask & ~M_Exception_Detect;
assign ID_Exception_Stall = (ID_Exception_Detect | ERET | Mtc0) & ID_Exception_Mask & ~(EX_Exception_Detect | M_Exception_Detect);
assign IF_Exception_Stall = IF_Exception_Detect & IF_Exception_Mask & ~(ID_Exception_Detect | EX_Exception_Detect | M_Exception_Detect);
/*** Exceptions which are ready to process (mutually exclusive) ***/
// XXX can remove ~ID_Stall since in mask now (?)
assign M_Exception_Ready = ~ID_Stall & M_Exception_Detect & ~M_Exception_Mask;
assign EX_Exception_Ready = ~ID_Stall & EX_Exception_Detect & ~EX_Exception_Mask;
assign ID_Exception_Ready = ~ID_Stall & ID_Exception_Detect & ~ID_Exception_Mask;
assign IF_Exception_Ready = ~ID_Stall & IF_Exception_Detect & ~IF_Exception_Mask;
/***
Flushes. A flush clears a pipeline stage's control signals and prevents the stage from committing any changes.
Data such as 'RestartPC' and the detected exception must remain.
*/
assign M_Exception_Flush = M_Exception_Detect;
assign EX_Exception_Flush = M_Exception_Detect | EX_Exception_Detect;
assign ID_Exception_Flush = M_Exception_Detect | EX_Exception_Detect | ID_Exception_Detect;
assign IF_Exception_Flush = M_Exception_Detect | EX_Exception_Detect | ID_Exception_Detect | IF_Exception_Detect | (ERET & ~ID_Stall) | reset_r;
/*** Software reads of CP0 Registers ***/
always @(*) begin
if (Mfc0 & (Status_CU_0 | KernelMode)) begin
case (Rd)
5'd8 : Reg_Out <= BadVAddr;
5'd9 : Reg_Out <= Count;
5'd11 : Reg_Out <= Compare;
5'd12 : Reg_Out <= Status;
5'd13 : Reg_Out <= Cause;
5'd14 : Reg_Out <= EPC;
5'd15 : Reg_Out <= PRId;
5'd16 : Reg_Out <= (Sel == 3'b000) ? Config : Config1;
5'd30 : Reg_Out <= ErrorEPC;
default : Reg_Out <= 32'h0000_0000;
endcase
end
else begin
Reg_Out <= 32'h0000_0000;
end
end
/*** Cp0 Register Assignments: Non-general exceptions (Reset, Soft Reset, NMI...) ***/
always @(posedge clock) begin
if (reset) begin
Status_BEV <= 1;
Status_NMI <= 0;
Status_ERL <= 1;
ErrorEPC <= 32'b0;
end
else if (ID_Exception_Ready & EXC_NMI) begin
Status_BEV <= 1;
Status_NMI <= 1;
Status_ERL <= 1;
ErrorEPC <= ID_RestartPC;
end
else begin
Status_BEV <= (CP0_WriteCond & (Rd == 5'd12) & (Sel == 3'b000)) ? Reg_In[22] : Status_BEV;
Status_NMI <= (CP0_WriteCond & (Rd == 5'd12) & (Sel == 3'b000)) ? Reg_In[19] : Status_NMI;
Status_ERL <= (CP0_WriteCond & (Rd == 5'd12) & (Sel == 3'b000)) ? Reg_In[2] : ((Status_ERL & ERET & ~ID_Stall) ? 0 : Status_ERL);
ErrorEPC <= (CP0_WriteCond & (Rd == 5'd30) & (Sel == 3'b000)) ? Reg_In : ErrorEPC;
end
end
/*** Cp0 Register Assignments: All other registers ***/
always @(posedge clock) begin
if (reset) begin
Count <= 32'b0;
Compare <= 32'b0;
Status_CU_0 <= 0;
Status_RE <= 0;
Status_IM <= 8'b0;
Status_UM <= 0;
Status_IE <= 0;
Cause_IV <= 0;
Cause_IP <= 8'b0;
end
else begin
Count <= (CP0_WriteCond & (Rd == 5'd9 ) & (Sel == 3'b000)) ? Reg_In : ((Count == Compare) ? 32'b0 : Count + 1);
Compare <= (CP0_WriteCond & (Rd == 5'd11) & (Sel == 3'b000)) ? Reg_In : Compare;
Status_CU_0 <= (CP0_WriteCond & (Rd == 5'd12) & (Sel == 3'b000)) ? Reg_In[28] : Status_CU_0;
Status_RE <= (CP0_WriteCond & (Rd == 5'd12) & (Sel == 3'b000)) ? Reg_In[25] : Status_RE;
Status_IM <= (CP0_WriteCond & (Rd == 5'd12) & (Sel == 3'b000)) ? Reg_In[15:8] : Status_IM;
Status_UM <= (CP0_WriteCond & (Rd == 5'd12) & (Sel == 3'b000)) ? Reg_In[4] : Status_UM;
Status_IE <= (CP0_WriteCond & (Rd == 5'd12) & (Sel == 3'b000)) ? Reg_In[0] : Status_IE;
Cause_IV <= (CP0_WriteCond & (Rd == 5'd13) & (Sel == 3'b000)) ? Reg_In[23] : Cause_IV;
/* Cause_IP indicates 8 interrupts:
[7] is set by the timer comparison, and cleared by reading 'Count'.
[6:2] are set and cleared by external hardware.
[1:0] are set and cleared by software.
*/
// If reading -> 0, Otherwise if 0 -> Int5.
Cause_IP[7] <= ((Status_CU_0 | KernelMode) & Mfc0 & (Rd == 5'd9) & (Sel == 3'b000)) ? 0 : ((Cause_IP[7] == 0) ? Int5 : Cause_IP[7]);
Cause_IP[6:2] <= Int[4:0];
Cause_IP[1:0] <= (CP0_WriteCond & (Rd == 5'd13) & (Sel == 3'b000)) ? Reg_In[9:8] : Cause_IP[1:0];
end
end
/*** Cp0 Register Assignments: General Exception and Interrupt Processing ***/
always @(posedge clock) begin
if (reset) begin
Cause_BD <= 0;
Cause_CE <= 2'b00;
Cause_ExcCode30 <= 4'b0000;
Status_EXL <= 0;
EPC <= 32'h0;
BadVAddr <= 32'h0;
end
else begin
// MEM stage
if (M_Exception_Ready) begin
Cause_BD <= (Status_EXL) ? Cause_BD : M_IsBD;
Cause_CE <= (COP3) ? 2'b11 : ((COP2) ? 2'b10 : ((COP1) ? 2'b01 : 2'b00));
Cause_ExcCode30 <= Cause_ExcCode_bits;
Status_EXL <= 1;
EPC <= (Status_EXL) ? EPC : M_RestartPC;
BadVAddr <= BadAddr_M;
end
// EX stage
else if (EX_Exception_Ready) begin
Cause_BD <= (Status_EXL) ? Cause_BD : EX_IsBD;
Cause_CE <= (COP3) ? 2'b11 : ((COP2) ? 2'b10 : ((COP1) ? 2'b01 : 2'b00));
Cause_ExcCode30 <= Cause_ExcCode_bits;
Status_EXL <= 1;
EPC <= (Status_EXL) ? EPC : EX_RestartPC;
BadVAddr <= BadVAddr;
end
// ID stage
else if (ID_Exception_Ready) begin
Cause_BD <= (Status_EXL) ? Cause_BD : ID_IsBD;
Cause_CE <= (COP3) ? 2'b11 : ((COP2) ? 2'b10 : ((COP1) ? 2'b01 : 2'b00));
Cause_ExcCode30 <= Cause_ExcCode_bits;
Status_EXL <= 1;
EPC <= (Status_EXL) ? EPC : ID_RestartPC;
BadVAddr <= BadVAddr;
end
// IF stage
else if (IF_Exception_Ready) begin
Cause_BD <= (Status_EXL) ? Cause_BD : IF_IsBD;
Cause_CE <= (COP3) ? 2'b11 : ((COP2) ? 2'b10 : ((COP1) ? 2'b01 : 2'b00));
Cause_ExcCode30 <= Cause_ExcCode_bits;
Status_EXL <= 1;
EPC <= (Status_EXL) ? EPC : BadAddr_IF;
BadVAddr <= BadAddr_IF;
end
// No exceptions this cycle
else begin
Cause_BD <= 1'b0;
Cause_CE <= Cause_CE;
Cause_ExcCode30 <= Cause_ExcCode30;
// Without new exceptions, 'Status_EXL' is set by software or cleared by ERET.
Status_EXL <= (CP0_WriteCond & (Rd == 5'd12) & (Sel == 3'b000)) ? Reg_In[1] : ((Status_EXL & ERET & ~ID_Stall) ? 0 : Status_EXL);
// The EPC is also writable by software
EPC <= (CP0_WriteCond & (Rd == 5'd14) & (Sel == 3'b000)) ? Reg_In : EPC;
BadVAddr <= BadVAddr;
end
end
end
/*** Program Counter for all Exceptions/Interrupts ***/
always @(*) begin
// Following is redundant since PC has initial value now.
if (reset) begin
Exc_PC_Out <= EXC_Vector_Base_Reset;
end
else if (ERET & ~ID_Stall) begin
Exc_PC_Out <= (Status_ERL) ? ErrorEPC : EPC;
end
else if (EXC_General) begin
Exc_PC_Out <= (Status_BEV) ? (EXC_Vector_Base_Other_Boot + EXC_Vector_Offset_General) :
(EXC_Vector_Base_Other_NoBoot + EXC_Vector_Offset_General);
end
else if (EXC_NMI) begin
Exc_PC_Out <= EXC_Vector_Base_Reset;
end
else if (EXC_Int & Cause_IV) begin
Exc_PC_Out <= (Status_BEV) ? (EXC_Vector_Base_Other_Boot + EXC_Vector_Offset_Special) :
(EXC_Vector_Base_Other_NoBoot + EXC_Vector_Offset_Special);
end
else begin
Exc_PC_Out <= (Status_BEV) ? (EXC_Vector_Base_Other_Boot + EXC_Vector_Offset_General) :
(EXC_Vector_Base_Other_NoBoot + EXC_Vector_Offset_General);
end
end
//assign Exc_PC_Sel = (reset | (ERET & ~ID_Stall) | EXC_General | EXC_Int);
assign Exc_PC_Sel = reset | (ERET & ~ID_Stall) | IF_Exception_Ready | ID_Exception_Ready | EX_Exception_Ready | M_Exception_Ready;
/*** Cause Register ExcCode Field ***/
always @(*) begin
// Ordered by Pipeline Stage with Interrupts last
if (EXC_AdEL) Cause_ExcCode_bits <= 4'h4; // 00100
else if (EXC_AdES) Cause_ExcCode_bits <= 4'h5; // 00101
else if (EXC_Tr) Cause_ExcCode_bits <= 4'hd; // 01101
else if (EXC_Ov) Cause_ExcCode_bits <= 4'hc; // 01100
else if (EXC_Sys) Cause_ExcCode_bits <= 4'h8; // 01000
else if (EXC_Bp) Cause_ExcCode_bits <= 4'h9; // 01001
else if (EXC_RI) Cause_ExcCode_bits <= 4'ha; // 01010
else if (EXC_CpU) Cause_ExcCode_bits <= 4'hb; // 01011
else if (EXC_AdIF) Cause_ExcCode_bits <= 4'h4; // 00100
else if (EXC_Int) Cause_ExcCode_bits <= 4'h0; // 00000 // OK that NMI writes this.
else Cause_ExcCode_bits <= 4'bxxxx;
end
endmodule
@@ -0,0 +1,41 @@
`timescale 1ns / 1ps
/*
* File : Compare.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 15-Jun-2011 GEA Initial design.
*
* Standards/Formatting:
* Verilog 2001, 4 soft tab, wide column.
*
* Description:
* Compares two 32-bit values and outputs the following information about them:
* EQ : A and B are equal
* GZ : A is greater than zero
* LZ : A is less than zero
* GEZ : A is greater than or equal to zero
* 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
);
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);
endmodule
@@ -0,0 +1,509 @@
`timescale 1ns / 1ps
/*
* File : Control.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-May-2012 GEA Release version with CP0.
*
* Standards/Formatting:
* Verilog 2001, 4 soft tab, wide column.
*
* Description:
* The Datapath Controller. This module sets the datapath control
* bits for an incoming instruction. These control bits follow the
* instruction through each pipeline stage as needed, and constitute
* 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,
output Movz,
output Mfc0,
output Mtc0,
output CP1,
output CP2,
output CP3,
output Eret,
output Trap,
output TrapCond,
output EXC_Sys,
output EXC_Bp,
output EXC_RI,
output ID_CanErr,
output EX_CanErr,
output M_CanErr,
output NextIsDelay,
output RegDst,
output ALUSrcImm,
output reg [4:0] ALUOp,
output LLSC,
output MemWrite,
output MemRead,
output MemByte,
output MemHalf,
output MemSignExtend,
output Left,
output Right,
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 Unaligned_Mem;
reg [15:0] Datapath;
assign PCSrc[0] = Datapath[14];
assign Link = Datapath[13];
assign ALUSrcImm = Datapath[12];
assign Movc = Datapath[11];
assign Trap = Datapath[10];
assign TrapCond = Datapath[9];
assign RegDst = Datapath[8];
assign LLSC = Datapath[7];
assign MemRead = Datapath[6];
assign MemWrite = Datapath[5];
assign MemHalf = Datapath[4];
assign MemByte = Datapath[3];
assign MemSignExtend = Datapath[2];
assign RegWrite = Datapath[1];
assign MemtoReg = Datapath[0];
reg [2:0] DP_Exceptions;
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;
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
// 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
// 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
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
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
/***
These remaining options cover portions of the datapath that are not
controlled directly by the datapath bits. Note that some refer to bits of
the opcode or other fields, which breaks the otherwise fully-abstracted view
of instruction encodings. Make sure when adding custom instructions that
no false positives/negatives are generated here.
***/
// Branch Detection: Options are mutually exclusive.
assign Branch_EQ = OpCode[2] & ~OpCode[1] & ~OpCode[0] & Cmp_EQ;
assign Branch_GTZ = OpCode[2] & OpCode[1] & OpCode[0] & Cmp_GZ;
assign Branch_LEZ = OpCode[2] & OpCode[1] & ~OpCode[0] & Cmp_LEZ;
assign Branch_NEQ = OpCode[2] & ~OpCode[1] & OpCode[0] & ~Cmp_EQ;
assign Branch_GEZ = ~OpCode[2] & Rt[0] & Cmp_GEZ;
assign Branch_LTZ = ~OpCode[2] & ~Rt[0] & Cmp_LZ;
assign Branch = Branch_EQ | Branch_GTZ | Branch_LEZ | Branch_NEQ | Branch_GEZ | Branch_LTZ;
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;
// 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.
assign SignExtend = (OpCode[5:2] != 4'b0011);
// Move Conditional
assign Movn = Movc & Funct[0];
assign Movz = Movc & ~Funct[0];
// 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 Eret = ((OpCode == Op_Type_CP0) && (Rs == OpRs_ERET) && (Funct == Funct_ERET));
// Coprocessor 1,2,3 accesses (not implemented)
assign CP1 = (OpCode == Op_Type_CP1);
assign CP2 = (OpCode == Op_Type_CP2);
assign CP3 = (OpCode == Op_Type_CP3);
// Exceptions found in ID
assign EXC_Sys = ((OpCode == Op_Type_R) && (Funct == Funct_Syscall));
assign EXC_Bp = ((OpCode == Op_Type_R) && (Funct == Funct_Break));
// Unaligned Memory Accesses (lwl, lwr, swl, swr)
assign Unaligned_Mem = OpCode[5] & ~OpCode[4] & OpCode[1] & ~OpCode[0];
assign Left = Unaligned_Mem & ~OpCode[2];
assign Right = Unaligned_Mem & OpCode[2];
// TODO: Reserved Instruction Exception must still be implemented
assign EXC_RI = 0;
endmodule
@@ -0,0 +1,100 @@
`timescale 1ns / 1ns
/*
* File : Divide.v
* Project : University of Utah, XUM Project MIPS32 core
* Creator(s) : Neil Russell
*
* Modification History:
* Rev Date Initials Description of Change
* 1.0 6-Nov-2012 NJR Initial design.
*
* Description:
* A multi-cycle 32-bit divider.
*
* On any cycle that one of OP_div or OP_divu are true, the Dividend and
* Divisor will be captured and a multi-cycle divide operation initiated.
* Stall will go true on the next cycle and the first cycle of the divide
* operation completed. After some time (about 32 cycles), Stall will go
* false on the same cycle that the result becomes valid. OP_div or OP_divu
* will abort any currently running divide operation and initiate a new one.
*/
module Divide(
input clock,
input reset,
input OP_div, // True to initiate a signed divide
input OP_divu, // True to initiate an unsigned divide
input [31:0] Dividend,
input [31:0] Divisor,
output [31:0] Quotient,
output [31:0] Remainder,
output Stall // True while calculating
);
reg active; // True if the divider is running
reg neg; // True if the result will be negative
reg [4:0] cycle; // Number of cycles to go
reg [31:0] result; // Begin with dividend, end with quotient
reg [31:0] denom; // Divisor
reg [31:0] work; // Running remainder
// Calculate the current digit
wire [32:0] sub = { work[30:0], result[31] } - denom;
// Send the results to our master
assign Quotient = !neg ? result : -result;
assign Remainder = work;
assign Stall = active;
// The state machine
always @(posedge clock) begin
if (reset) begin
active <= 0;
neg <= 0;
cycle <= 0;
result <= 0;
denom <= 0;
work <= 0;
end
else begin
if (OP_div) begin
// Set up for a signed divide. Remember the resulting sign,
// and make the operands positive.
cycle <= 5'd31;
result <= (Dividend[31] == 0) ? Dividend : -Dividend;
denom <= (Divisor[31] == 0) ? Divisor : -Divisor;
work <= 32'b0;
neg <= Dividend[31] ^ Divisor[31];
active <= 1;
end
else if (OP_divu) begin
// Set up for an unsigned divide.
cycle <= 5'd31;
result <= Dividend;
denom <= Divisor;
work <= 32'b0;
neg <= 0;
active <= 1;
end
else if (active) begin
// Run an iteration of the divide.
if (sub[32] == 0) begin
work <= sub[31:0];
result <= {result[30:0], 1'b1};
end
else begin
work <= {work[30:0], result[31]};
result <= {result[30:0], 1'b0};
end
if (cycle == 0) begin
active <= 0;
end
cycle <= cycle - 5'd1;
end
end
end
endmodule
@@ -0,0 +1,116 @@
`timescale 1ns / 1ps
/*
* File : EXMEM_Stage.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 9-Jun-2011 GEA Initial design.
* 2.0 26-Jul-2012 GEA Many updates have been made.
*
* Standards/Formatting:
* Verilog 2001, 4 soft tab, wide column.
*
* Description:
* The Pipeline Register to bridge the Execute and Memory stages.
*/
module EXMEM_Stage(
input clock,
input reset,
input EX_Flush,
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_ReverseEndian,
input EX_LLSC,
input EX_MemRead,
input EX_MemWrite,
input EX_MemByte,
input EX_MemHalf,
input EX_MemSignExtend,
input EX_Left,
input EX_Right,
// Exception Control/Info
input EX_KernelMode,
input [31:0] EX_RestartPC,
input EX_IsBDS,
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,
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_Left,
output reg M_Right,
output reg M_KernelMode,
output reg [31:0] M_RestartPC,
output reg M_IsBDS,
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
);
/***
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
of delay, but reduces the combinatorial path length of signals which allows for
higher clock speeds.
All pipeline registers update unless the forward stage is stalled. When this occurs
or when the current stage is being flushed, the forward stage will receive data that
is effectively a NOP and causes nothing to happen throughout the remaining pipeline
traversal. In other words:
A stall masks all control signals to forward stages. A flush permanently clears
control signals to forward stages (but not certain data for exception purposes).
***/
// Mask of RegWrite if a Move Conditional failed.
wire MovcRegWrite = (EX_Movn & ~EX_BZero) | (EX_Movz & EX_BZero);
always @(posedge clock) begin
M_RegWrite <= (reset) ? 0 : ((M_Stall) ? M_RegWrite : ((EX_Stall | EX_Flush) ? 0 : EX_RegWrite));
M_RegWrite <= (reset) ? 0 : ((M_Stall) ? M_RegWrite : ((EX_Stall | EX_Flush) ? 0 : ((EX_Movn | EX_Movz) ? MovcRegWrite : EX_RegWrite)));
M_MemtoReg <= (reset) ? 0 : ((M_Stall) ? M_MemtoReg : EX_MemtoReg);
M_ReverseEndian <= (reset) ? 0 : ((M_Stall) ? M_ReverseEndian : EX_ReverseEndian);
M_LLSC <= (reset) ? 0 : ((M_Stall) ? M_LLSC : EX_LLSC);
M_MemRead <= (reset) ? 0 : ((M_Stall) ? M_MemRead : ((EX_Stall | EX_Flush) ? 0 : EX_MemRead));
M_MemWrite <= (reset) ? 0 : ((M_Stall) ? M_MemWrite : ((EX_Stall | EX_Flush) ? 0 : EX_MemWrite));
M_MemByte <= (reset) ? 0 : ((M_Stall) ? M_MemByte : EX_MemByte);
M_MemHalf <= (reset) ? 0 : ((M_Stall) ? M_MemHalf : EX_MemHalf);
M_MemSignExtend <= (reset) ? 0 : ((M_Stall) ? M_MemSignExtend : EX_MemSignExtend);
M_Left <= (reset) ? 0 : ((M_Stall) ? M_Left : EX_Left);
M_Right <= (reset) ? 0 : ((M_Stall) ? M_Right : EX_Right);
M_KernelMode <= (reset) ? 0 : ((M_Stall) ? M_KernelMode : EX_KernelMode);
M_RestartPC <= (reset) ? 32'b0 : ((M_Stall) ? M_RestartPC : EX_RestartPC);
M_IsBDS <= (reset) ? 0 : ((M_Stall) ? M_IsBDS : EX_IsBDS);
M_Trap <= (reset) ? 0 : ((M_Stall) ? M_Trap : ((EX_Stall | EX_Flush) ? 0 : EX_Trap));
M_TrapCond <= (reset) ? 0 : ((M_Stall) ? M_TrapCond : EX_TrapCond);
M_M_CanErr <= (reset) ? 0 : ((M_Stall) ? M_M_CanErr : ((EX_Stall | EX_Flush) ? 0 : EX_M_CanErr));
M_ALU_Result <= (reset) ? 32'b0 : ((M_Stall) ? M_ALU_Result : EX_ALU_Result);
M_ReadData2 <= (reset) ? 32'b0 : ((M_Stall) ? M_ReadData2 : EX_ReadData2);
M_RtRd <= (reset) ? 5'b0 : ((M_Stall) ? M_RtRd : EX_RtRd);
end
endmodule
@@ -0,0 +1,175 @@
`timescale 1ns / 1ps
/*
* File : Hazard_Detection.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 23-Jul-2011 GEA Initial design.
* 2.0 26-May-2012 GEA Release version with CP0.
* 2.01 1-Nov-2012 GEA Fixed issue with Jal.
*
* Standards/Formatting:
* Verilog 2001, 4 soft tab, wide column.
*
* Description:
* Hazard Detection and Forward Control. This is the glue that allows a
* pipelined processor to operate efficiently and correctly in the presence
* of data, structural, and control hazards. For each pipeline stage, it
* detects whether that stage requires data that is still in the pipeline,
* and whether that data may be forwarded or if the pipeline must be stalled.
*
* 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 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 IF_Exception_Stall,
input ID_Exception_Stall,
input EX_Exception_Stall,
input EX_ALU_Stall,
input M_Stall_Controller, // Determined by data memory controller
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.
*
* 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
* and thus are never needed for a data dependence, so the signal 'MEM_MemRead'
* 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];
// 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);
// 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) | EX_ALU_Stall | M_Stall;
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_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_Link) ? 2'b11 : ((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;
endmodule
@@ -0,0 +1,159 @@
`timescale 1ns / 1ps
/*
* File : IDEX_Stage.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 9-Jun-2011 GEA Initial design.
* 2.0 26-Jul-2012 GEA Many updates have been made.
*
* Standards/Formatting:
* Verilog 2001, 4 soft tab, wide column.
*
* Description:
* The Pipeline Register to bridge the Instruction Decode
* and Execute stages.
*/
module IDEX_Stage(
input clock,
input reset,
input ID_Flush,
input ID_Stall,
input EX_Stall,
// Control Signals
input ID_Link,
input ID_RegDst,
input ID_ALUSrcImm,
input [4:0] ID_ALUOp,
input ID_Movn,
input ID_Movz,
input ID_LLSC,
input ID_MemRead,
input ID_MemWrite,
input ID_MemByte,
input ID_MemHalf,
input ID_MemSignExtend,
input ID_Left,
input ID_Right,
input ID_RegWrite,
input ID_MemtoReg,
input ID_ReverseEndian,
// Hazard & Forwarding
input [4:0] ID_Rs,
input [4:0] ID_Rt,
input ID_WantRsByEX,
input ID_NeedRsByEX,
input ID_WantRtByEX,
input ID_NeedRtByEX,
// Exception Control/Info
input ID_KernelMode,
input [31:0] ID_RestartPC,
input ID_IsBDS,
input ID_Trap,
input ID_TrapCond,
input ID_EX_CanErr,
input ID_M_CanErr,
// Data Signals
input [31:0] ID_ReadData1,
input [31:0] ID_ReadData2,
input [16:0] ID_SignExtImm, // ID_Rd, ID_Shamt included here
// ----------------
output reg EX_Link,
output [1:0] EX_LinkRegDst,
output reg EX_ALUSrcImm,
output reg [4:0] EX_ALUOp,
output reg EX_Movn,
output reg EX_Movz,
output reg EX_LLSC,
output reg EX_MemRead,
output reg EX_MemWrite,
output reg EX_MemByte,
output reg EX_MemHalf,
output reg EX_MemSignExtend,
output reg EX_Left,
output reg EX_Right,
output reg EX_RegWrite,
output reg EX_MemtoReg,
output reg EX_ReverseEndian,
output reg [4:0] EX_Rs,
output reg [4:0] EX_Rt,
output reg EX_WantRsByEX,
output reg EX_NeedRsByEX,
output reg EX_WantRtByEX,
output reg EX_NeedRtByEX,
output reg EX_KernelMode,
output reg [31:0] EX_RestartPC,
output reg EX_IsBDS,
output reg EX_Trap,
output reg EX_TrapCond,
output reg EX_EX_CanErr,
output reg EX_M_CanErr,
output reg [31:0] EX_ReadData1,
output reg [31:0] EX_ReadData2,
output [31:0] EX_SignExtImm,
output [4:0] EX_Rd,
output [4:0] EX_Shamt
);
/***
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
of delay, but reduces the combinatorial path length of signals which allows for
higher clock speeds.
All pipeline registers update unless the forward stage is stalled. When this occurs
or when the current stage is being flushed, the forward stage will receive data that
is effectively a NOP and causes nothing to happen throughout the remaining pipeline
traversal. In other words:
A stall masks all control signals to forward stages. A flush permanently clears
control signals to forward stages (but not certain data for exception purposes).
***/
reg [16:0] EX_SignExtImm_pre;
reg EX_RegDst;
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]};
always @(posedge clock) begin
EX_Link <= (reset) ? 0 : ((EX_Stall) ? EX_Link : ID_Link);
EX_RegDst <= (reset) ? 0 : ((EX_Stall) ? EX_RegDst : ID_RegDst);
EX_ALUSrcImm <= (reset) ? 0 : ((EX_Stall) ? EX_ALUSrcImm : ID_ALUSrcImm);
EX_ALUOp <= (reset) ? 5'b0 : ((EX_Stall) ? EX_ALUOp : ((ID_Stall | ID_Flush) ? 5'b0 : ID_ALUOp));
EX_Movn <= (reset) ? 0 : ((EX_Stall) ? EX_Movn : ID_Movn);
EX_Movz <= (reset) ? 0 : ((EX_Stall) ? EX_Movz : ID_Movz);
EX_LLSC <= (reset) ? 0 : ((EX_Stall) ? EX_LLSC : ID_LLSC);
EX_MemRead <= (reset) ? 0 : ((EX_Stall) ? EX_MemRead : ((ID_Stall | ID_Flush) ? 0 : ID_MemRead));
EX_MemWrite <= (reset) ? 0 : ((EX_Stall) ? EX_MemWrite : ((ID_Stall | ID_Flush) ? 0 : ID_MemWrite));
EX_MemByte <= (reset) ? 0 : ((EX_Stall) ? EX_MemByte : ID_MemByte);
EX_MemHalf <= (reset) ? 0 : ((EX_Stall) ? EX_MemHalf : ID_MemHalf);
EX_MemSignExtend <= (reset) ? 0 : ((EX_Stall) ? EX_MemSignExtend : ID_MemSignExtend);
EX_Left <= (reset) ? 0 : ((EX_Stall) ? EX_Left : ID_Left);
EX_Right <= (reset) ? 0 : ((EX_Stall) ? EX_Right : ID_Right);
EX_RegWrite <= (reset) ? 0 : ((EX_Stall) ? EX_RegWrite : ((ID_Stall | ID_Flush) ? 0 : ID_RegWrite));
EX_MemtoReg <= (reset) ? 0 : ((EX_Stall) ? EX_MemtoReg : ID_MemtoReg);
EX_ReverseEndian <= (reset) ? 0 : ((EX_Stall) ? EX_ReverseEndian : ID_ReverseEndian);
EX_RestartPC <= (reset) ? 32'b0 : ((EX_Stall) ? EX_RestartPC : ID_RestartPC);
EX_IsBDS <= (reset) ? 0 : ((EX_Stall) ? EX_IsBDS : ID_IsBDS);
EX_Trap <= (reset) ? 0 : ((EX_Stall) ? EX_Trap : ((ID_Stall | ID_Flush) ? 0 : ID_Trap));
EX_TrapCond <= (reset) ? 0 : ((EX_Stall) ? EX_TrapCond : ID_TrapCond);
EX_EX_CanErr <= (reset) ? 0 : ((EX_Stall) ? EX_EX_CanErr : ((ID_Stall | ID_Flush) ? 0 : ID_EX_CanErr));
EX_M_CanErr <= (reset) ? 0 : ((EX_Stall) ? EX_M_CanErr : ((ID_Stall | ID_Flush) ? 0 : ID_M_CanErr));
EX_ReadData1 <= (reset) ? 32'b0 : ((EX_Stall) ? EX_ReadData1 : ID_ReadData1);
EX_ReadData2 <= (reset) ? 32'b0 : ((EX_Stall) ? EX_ReadData2 : ID_ReadData2);
EX_SignExtImm_pre <= (reset) ? 17'b0 : ((EX_Stall) ? EX_SignExtImm_pre : ID_SignExtImm);
EX_Rs <= (reset) ? 5'b0 : ((EX_Stall) ? EX_Rs : ID_Rs);
EX_Rt <= (reset) ? 5'b0 : ((EX_Stall) ? EX_Rt : ID_Rt);
EX_WantRsByEX <= (reset) ? 0 : ((EX_Stall) ? EX_WantRsByEX : ((ID_Stall | ID_Flush) ? 0 : ID_WantRsByEX));
EX_NeedRsByEX <= (reset) ? 0 : ((EX_Stall) ? EX_NeedRsByEX : ((ID_Stall | ID_Flush) ? 0 : ID_NeedRsByEX));
EX_WantRtByEX <= (reset) ? 0 : ((EX_Stall) ? EX_WantRtByEX : ((ID_Stall | ID_Flush) ? 0 : ID_WantRtByEX));
EX_NeedRtByEX <= (reset) ? 0 : ((EX_Stall) ? EX_NeedRtByEX : ((ID_Stall | ID_Flush) ? 0 : ID_NeedRtByEX));
EX_KernelMode <= (reset) ? 0 : ((EX_Stall) ? EX_KernelMode : ID_KernelMode);
end
endmodule
@@ -0,0 +1,75 @@
`timescale 1ns / 1ps
/*
* File : IFID_Stage.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 9-Jun-2011 GEA Initial design.
* 2.0 26-Jul-2012 GEA Many updates have been made.
*
* Standards/Formatting:
* Verilog 2001, 4 soft tab, wide column.
*
* Description:
* The Pipeline Register to bridge the Instruction Fetch
* and Instruction Decode stages.
*/
module IFID_Stage(
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 [31:0] IF_PC,
input IF_IsBDS,
// ------------------
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
of delay, but reduces the combinatorial path length of signals which allows for
higher clock speeds.
All pipeline registers update unless the forward stage is stalled. When this occurs
or when the current stage is being flushed, the forward stage will receive data that
is effectively a NOP and causes nothing to happen throughout the remaining pipeline
traversal. In other words:
A stall masks all control signals to forward stages. A flush permanently clears
control signals to forward stages (but not certain data for exception purposes).
***/
/***
The signal 'ID_IsFlushed' is needed because of interrupts. Normally, a flushed instruction
is a NOP which will never cause an exception and thus its restart PC will never be needed
or used. However, interrupts are detected in ID and may occur when any instruction, flushed
or not, is in the ID stage. It is an error to save the restart PC of a flushed instruction
since it was never supposed to execute (such as the "delay slot" after ERET or the branch
delay slot after a canceled Branch Likely instruction). A simple way to prevent this is to
pass a signal to ID indicating that its instruction was flushed. Interrupt detection is then
masked when this signal is high, and the interrupt will trigger on the next instruction load to ID.
***/
always @(posedge clock) begin
ID_Instruction <= (reset) ? 32'b0 : ((ID_Stall) ? ID_Instruction : ((IF_Stall | IF_Flush) ? 32'b0 : IF_Instruction));
ID_PCAdd4 <= (reset) ? 32'b0 : ((ID_Stall) ? ID_PCAdd4 : IF_PCAdd4);
ID_IsBDS <= (reset) ? 0 : ((ID_Stall) ? ID_IsBDS : IF_IsBDS);
ID_RestartPC <= (reset) ? 32'b0 : ((ID_Stall | IF_IsBDS) ? ID_RestartPC : IF_PC);
ID_IsFlushed <= (reset) ? 0 : ((ID_Stall) ? ID_IsFlushed : IF_Flush);
end
endmodule
@@ -0,0 +1,74 @@
`timescale 1ns / 1ps
/*
* File : MEMWB_Stage.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 9-Jun-2011 GEA Initial design.
* 2.0 26-Jul-2012 GEA Many updates have been made.
*
* Standards/Formatting:
* Verilog 2001, 4 soft tab, wide column.
*
* Description:
* The Pipeline Register to bridge the Memory and Writeback stages.
*/
module MEMWB_Stage(
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
);
/***
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
of delay, but reduces the combinatorial path length of signals which allows for
higher clock speeds.
All pipeline registers update unless the forward stage is stalled. When this occurs
or when the current stage is being flushed, the forward stage will receive data that
is effectively a NOP and causes nothing to happen throughout the remaining pipeline
traversal. In other words:
A stall masks all control signals to forward stages. A flush permanently clears
control signals to forward stages (but not certain data for exception purposes).
Since WB is the final stage in the pipeline, it would normally never stall.
However, because the MEM stage may be using data forwarded from WB, WB must stall
when MEM is stalled. If it didn't, the forward data would not be preserved. If
the processor didn't forward any data, a stall would not be needed.
In practice, the only time WB stalls is when forwarding for a Lw->Sw sequence, since
MEM doesn't need the data until its stage, but it does not latch the forwarded data.
This means WB_Stall is probably identical to M_Stall. There is no speed difference by
allowing WB to stall.
***/
always @(posedge clock) begin
WB_RegWrite <= (reset) ? 0 : ((WB_Stall) ? WB_RegWrite : ((M_Stall | M_Flush) ? 0 : M_RegWrite));
WB_MemtoReg <= (reset) ? 0 : ((WB_Stall) ? WB_MemtoReg : M_MemtoReg);
WB_ReadData <= (reset) ? 32'b0 : ((WB_Stall) ? WB_ReadData : M_ReadData);
WB_ALU_Result <= (reset) ? 32'b0 : ((WB_Stall) ? WB_ALU_Result : M_ALU_Result);
WB_RtRd <= (reset) ? 5'b0 : ((WB_Stall) ? WB_RtRd : M_RtRd);
end
endmodule
@@ -0,0 +1,631 @@
/*
* 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 ***
The MIPS Configuration Register (CP0 Register 16 Select 0) specifies the processor's
endianness. A processor in user mode may switch to reverse endianness, which will be
the opposite of this parameter.
*/
parameter Big_Endian = 1;
/*** 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;
parameter [15:0] DP_Addu = DP_RType;
parameter [15:0] DP_And = DP_RType;
parameter [15:0] DP_Andi = DP_IType;
parameter [15:0] DP_Beq = DP_Branch;
parameter [15:0] DP_Bgez = DP_Branch;
parameter [15:0] DP_Bgezal = DP_BranchLink;
parameter [15:0] DP_Bgtz = DP_Branch;
parameter [15:0] DP_Blez = DP_Branch;
parameter [15:0] DP_Bltz = DP_Branch;
parameter [15:0] DP_Bltzal = DP_BranchLink;
parameter [15:0] DP_Bne = DP_Branch;
parameter [15:0] DP_Break = DP_None;
parameter [15:0] DP_Clo = DP_RType;
parameter [15:0] DP_Clz = DP_RType;
parameter [15:0] DP_Div = DP_HiLoWr;
parameter [15:0] DP_Divu = DP_HiLoWr;
parameter [15:0] DP_Eret = DP_None;
parameter [15:0] DP_J = DP_Jump;
parameter [15:0] DP_Jal = DP_JumpLink;
parameter [15:0] DP_Jalr = DP_JumpLinkReg;
parameter [15:0] DP_Jr = DP_JumpReg;
parameter [15:0] DP_Lb = DP_LoadByteS;
parameter [15:0] DP_Lbu = DP_LoadByteU;
parameter [15:0] DP_Lh = DP_LoadHalfS;
parameter [15:0] DP_Lhu = DP_LoadHalfU;
parameter [15:0] DP_Ll = DP_LoadLinked;
parameter [15:0] DP_Lui = DP_IType;
parameter [15:0] DP_Lw = DP_LoadWord;
parameter [15:0] DP_Lwl = DP_LoadWord;
parameter [15:0] DP_Lwr = DP_LoadWord;
parameter [15:0] DP_Madd = DP_HiLoWr;
parameter [15:0] DP_Maddu = DP_HiLoWr;
parameter [15:0] DP_Mfc0 = DP_ExtWrRt;
parameter [15:0] DP_Mfhi = DP_ExtWrRd;
parameter [15:0] DP_Mflo = DP_ExtWrRd;
parameter [15:0] DP_Movn = DP_Movc;
parameter [15:0] DP_Movz = DP_Movc;
parameter [15:0] DP_Msub = DP_HiLoWr;
parameter [15:0] DP_Msubu = DP_HiLoWr;
parameter [15:0] DP_Mtc0 = DP_None;
parameter [15:0] DP_Mthi = DP_HiLoWr;
parameter [15:0] DP_Mtlo = DP_HiLoWr;
parameter [15:0] DP_Mul = DP_RType;
parameter [15:0] DP_Mult = DP_HiLoWr;
parameter [15:0] DP_Multu = DP_HiLoWr;
parameter [15:0] DP_Nor = DP_RType;
parameter [15:0] DP_Or = DP_RType;
parameter [15:0] DP_Ori = DP_IType;
parameter [15:0] DP_Pref = DP_None; // Not Implemented
parameter [15:0] DP_Sb = DP_StoreByte;
parameter [15:0] DP_Sc = DP_StoreCond;
parameter [15:0] DP_Sh = DP_StoreHalf;
parameter [15:0] DP_Sll = DP_RType;
parameter [15:0] DP_Sllv = DP_RType;
parameter [15:0] DP_Slt = DP_RType;
parameter [15:0] DP_Slti = DP_IType;
parameter [15:0] DP_Sltiu = DP_IType;
parameter [15:0] DP_Sltu = DP_RType;
parameter [15:0] DP_Sra = DP_RType;
parameter [15:0] DP_Srav = DP_RType;
parameter [15:0] DP_Srl = DP_RType;
parameter [15:0] DP_Srlv = DP_RType;
parameter [15:0] DP_Sub = DP_RType;
parameter [15:0] DP_Subu = DP_RType;
parameter [15:0] DP_Sw = DP_StoreWord;
parameter [15:0] DP_Swl = DP_StoreWord;
parameter [15:0] DP_Swr = DP_StoreWord;
parameter [15:0] DP_Syscall = DP_None;
parameter [15:0] DP_Teq = DP_TrapRegCZ;
parameter [15:0] DP_Teqi = DP_TrapImmCZ;
parameter [15:0] DP_Tge = DP_TrapRegCZ;
parameter [15:0] DP_Tgei = DP_TrapImmCZ;
parameter [15:0] DP_Tgeiu = DP_TrapImmCZ;
parameter [15:0] DP_Tgeu = DP_TrapRegCZ;
parameter [15:0] DP_Tlt = DP_TrapRegCNZ;
parameter [15:0] DP_Tlti = DP_TrapImmCNZ;
parameter [15:0] DP_Tltiu = DP_TrapImmCNZ;
parameter [15:0] DP_Tltu = DP_TrapRegCNZ;
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;
@@ -0,0 +1,233 @@
`timescale 1ns / 1ps
/*
* File : MemControl.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-Jun-2011 GEA Initial design.
* 2.0 28-Jun-2012 GEA Expanded from a simple byte/half/word unit to
* An advanced data memory controller capable of
* handling big/little endian, atomic and unaligned
* memory accesses.
*
* Standards/Formatting:
* Verilog 2001, 4 soft tab, wide column.
*
* Description:
* A Data Memory Controller which handles all read and write requests from the
* processor to data memory. All data accesses--whether big endian, little endian,
* byte, half, word, or unaligned transfers--are transformed into a simple read
* and write command to data memory over a 32-bit data bus, where the read command
* is one bit and the write command is 4 bits, one for each byte in the 32-bit word.
*/
module MemControl(
input clock,
input reset,
input [31:0] DataIn, // Data from CPU
input [31:0] Address, // From CPU
input [31:0] MReadData, // Data from Memory
input MemRead, // Memory Read command from CPU
input MemWrite, // Memory Write command from CPU
input DataMem_Ready, // Ready signal from Memory
input Byte, // Load/Store is Byte (8-bit)
input Half, // Load/Store is Half (16-bit)
input SignExtend, // Sub-word load should be sign extended
input KernelMode, // (Exception logic)
input ReverseEndian, // Reverse Endian Memory for User Mode
input LLSC, // (LLSC logic)
input ERET, // (LLSC logic)
input Left, // Unaligned Load/Store Word Left
input Right, // Unaligned Load/Store Word Right
input M_Exception_Stall,
input IF_Stall, // XXX Clean this up between this module and HAZ/FWD
output reg [31:0] DataOut, // Data to CPU
output [31:0] MWriteData, // Data to Memory
output reg [3:0] WriteEnable, // Write Enable to Memory for each of 4 bytes of Memory
output ReadEnable, // Read Enable to Memory
output M_Stall,
output EXC_AdEL, // Load Exception
output EXC_AdES // Store Exception
);
`include "MIPS_Parameters.v"
/*** Reverse Endian Mode
Normal memory accesses in the processor are Big Endian. The endianness can be reversed
to Little Endian in User Mode only.
*/
wire BE = KernelMode | ~ReverseEndian;
/*** Indicator that the current memory reference must be word-aligned ***/
wire Word = ~(Half | Byte | Left | Right);
// Exception Detection
wire EXC_KernelMem = ~KernelMode & (Address < UMem_Lower);
wire EXC_Word = Word & (Address[1] | Address[0]);
wire EXC_Half = Half & Address[0];
assign EXC_AdEL = MemRead & (EXC_KernelMem | EXC_Word | EXC_Half);
assign EXC_AdES = MemWrite & (EXC_KernelMem | EXC_Word | EXC_Half);
/*** Load Linked and Store Conditional logic ***
A 32-bit register keeps track of the address for atomic Load Linked / Store Conditional
operations. This register can be updated during stalls since it is not visible to
forward stages. It does not need to be flushed during exceptions, since ERET destroys
the atomicity condition and there are no detrimental effects in an exception handler.
The atomic condition is set with a Load Linked instruction, and cleared on an ERET
instruction or when any store instruction writes to one or more bytes covered by
the word address register. It does not update on a stall condition.
The MIPS32 spec states that an ERET instruction between LL and SC will cause the
atomicity condition to fail. This implementation uses the ERET signal from the ID
stage, which means instruction sequences such as "LL SC" could appear to have an
ERET instruction between them even though they don't. One way to fix this is to pass
the ERET signal through the pipeline to the MEM stage. However, because of the nature
of LL/SC operations (they occur in a loop which checks the result at each iteration),
an ERET will normally never be inserted into the pipeline programmatically until the
LL/SC sequence has completed (exceptions such as interrupts can still cause ERET, but
they can still cause them in the LL SC sequence as well). In other words, by not passing
ERET through the pipeline, the only possible effect is a performance penalty. Also this
may be irrelevant since currently ERET stalls for forward stages which can cause exceptions,
which includes LL and SC.
*/
reg [29:0] LLSC_Address;
reg LLSC_Atomic;
wire LLSC_MemWrite_Mask;
always @(posedge clock) begin
LLSC_Address <= (reset) ? 30'b0 : (MemRead & LLSC) ? Address[31:2] : LLSC_Address;
end
always @(posedge clock) begin
if (reset) begin
LLSC_Atomic <= 0;
end
else if (MemRead) begin
LLSC_Atomic <= (LLSC) ? 1 : LLSC_Atomic;
end
// XXX GEA Bug for Ganesh: remove "& ~IF_Stall" from below, then SC will always fail:
else if (ERET | (~M_Stall & ~IF_Stall & MemWrite & (Address[31:2] == LLSC_Address))) begin
LLSC_Atomic <= 0;
end
else begin
LLSC_Atomic <= LLSC_Atomic;
end
end
assign LLSC_MemWrite_Mask = (LLSC & MemWrite & (~LLSC_Atomic | (Address[31:2] != LLSC_Address)));
wire WriteCondition = MemWrite & ~(EXC_KernelMem | EXC_Word | EXC_Half) & ~LLSC_MemWrite_Mask;
wire ReadCondition = MemRead & ~(EXC_KernelMem | EXC_Word | EXC_Half);
reg RW_Mask;
always @(posedge clock) begin
RW_Mask <= (reset) ? 0 : (((MemWrite | MemRead) & DataMem_Ready) ? 1 : ((~M_Stall & ~IF_Stall) ? 0 : RW_Mask));
end
assign M_Stall = ReadEnable | (WriteEnable != 4'b0000) | DataMem_Ready | M_Exception_Stall;
assign ReadEnable = ReadCondition & ~RW_Mask;
wire Half_Access_L = (Address[1] ^ BE);
wire Half_Access_R = (Address[1] ~^ BE);
wire Byte_Access_LL = Half_Access_L & (Address[1] ~^ Address[0]);
wire Byte_Access_LM = Half_Access_L & (Address[0] ~^ BE);
wire Byte_Access_RM = Half_Access_R & (Address[0] ^ BE);
wire Byte_Access_RR = Half_Access_R & (Address[1] ~^ Address[0]);
// Write-Enable Signals to Memory
always @(*) begin
if (WriteCondition & ~RW_Mask) begin
if (Byte) begin
WriteEnable[3] <= Byte_Access_LL;
WriteEnable[2] <= Byte_Access_LM;
WriteEnable[1] <= Byte_Access_RM;
WriteEnable[0] <= Byte_Access_RR;
end
else if (Half) begin
WriteEnable[3] <= Half_Access_L;
WriteEnable[2] <= Half_Access_L;
WriteEnable[1] <= Half_Access_R;
WriteEnable[0] <= Half_Access_R;
end
else if (Left) begin
case (Address[1:0])
2'b00 : WriteEnable <= (BE) ? 4'b1111 : 4'b0001;
2'b01 : WriteEnable <= (BE) ? 4'b0111 : 4'b0011;
2'b10 : WriteEnable <= (BE) ? 4'b0011 : 4'b0111;
2'b11 : WriteEnable <= (BE) ? 4'b0001 : 4'b1111;
endcase
end
else if (Right) begin
case (Address[1:0])
2'b00 : WriteEnable <= (BE) ? 4'b1000 : 4'b1111;
2'b01 : WriteEnable <= (BE) ? 4'b1100 : 4'b1110;
2'b10 : WriteEnable <= (BE) ? 4'b1110 : 4'b1100;
2'b11 : WriteEnable <= (BE) ? 4'b1111 : 4'b1000;
endcase
end
else begin
WriteEnable <= 4'b1111;
end
end
else begin
WriteEnable <= 4'b0000;
end
end
// Data Going to Memory
assign MWriteData[31:24] = (Byte) ? DataIn[7:0] : ((Half) ? DataIn[15:8] : DataIn[31:24]);
assign MWriteData[23:16] = (Byte | Half) ? DataIn[7:0] : DataIn[23:16];
assign MWriteData[15:8] = (Byte) ? DataIn[7:0] : DataIn[15:8];
assign MWriteData[7:0] = DataIn[7:0];
// Data Read from Memory
always @(*) begin
if (Byte) begin
if (Byte_Access_LL) begin
DataOut <= (SignExtend & MReadData[31]) ? {24'hFFFFFF, MReadData[31:24]} : {24'h000000, MReadData[31:24]};
end
else if (Byte_Access_LM) begin
DataOut <= (SignExtend & MReadData[23]) ? {24'hFFFFFF, MReadData[23:16]} : {24'h000000, MReadData[23:16]};
end
else if (Byte_Access_RM) begin
DataOut <= (SignExtend & MReadData[15]) ? {24'hFFFFFF, MReadData[15:8]} : {24'h000000, MReadData[15:8]};
end
else begin
DataOut <= (SignExtend & MReadData[7]) ? {24'hFFFFFF, MReadData[7:0]} : {24'h000000, MReadData[7:0]};
end
end
else if (Half) begin
if (Half_Access_L) begin
DataOut <= (SignExtend & MReadData[31]) ? {16'hFFFF, MReadData[31:16]} : {16'h0000, MReadData[31:16]};
end
else begin
DataOut <= (SignExtend & MReadData[15]) ? {16'hFFFF, MReadData[15:0]} : {16'h0000, MReadData[15:0]};
end
end
else if (LLSC & MemWrite) begin
DataOut <= (LLSC_Atomic & (Address[31:2] == LLSC_Address)) ? 32'h0000_0001 : 32'h0000_0000;
end
else if (Left) begin
case (Address[1:0])
2'b00 : DataOut <= (BE) ? MReadData : {MReadData[7:0], DataIn[23:0]};
2'b01 : DataOut <= (BE) ? {MReadData[23:0], DataIn[7:0]} : {MReadData[15:0], DataIn[15:0]};
2'b10 : DataOut <= (BE) ? {MReadData[15:0], DataIn[15:0]} : {MReadData[23:0], DataIn[7:0]};
2'b11 : DataOut <= (BE) ? {MReadData[7:0], DataIn[23:0]} : MReadData;
endcase
end
else if (Right) begin
case (Address[1:0])
2'b00 : DataOut <= (BE) ? {DataIn[31:8], MReadData[31:24]} : MReadData;
2'b01 : DataOut <= (BE) ? {DataIn[31:16], MReadData[31:16]} : {DataIn[31:24], MReadData[31:8]};
2'b10 : DataOut <= (BE) ? {DataIn[31:24], MReadData[31:8]} : {DataIn[31:16], MReadData[31:16]};
2'b11 : DataOut <= (BE) ? MReadData : {DataIn[31:8], MReadData[31:24]};
endcase
end
else begin
DataOut <= MReadData;
end
end
endmodule
@@ -0,0 +1,679 @@
`timescale 1ns / 1ps
/*
* File : Processor.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 23-Jul-2011 GEA Initial design.
* 2.0 26-May-2012 GEA Release version with CP0.
* 2.01 1-Nov-2012 GEA Fixed issue with Jal.
*
* Standards/Formatting:
* Verilog 2001, 4 soft tab, wide column.
*
* Description:
* The top-level MIPS32 Processor. This file is mostly the instantiation
* and wiring of the building blocks of the processor according to the
* hardware design diagram. It contains very little logic itself.
*/
module Processor(
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,
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 [7:0] IP // Pending interrupts (diagnostic)
);
`include "MIPS_Parameters.v"
/*** MIPS Instruction and Components (ID Stage) ***/
wire [31:0] Instruction;
wire [5:0] OpCode = Instruction[31:26];
wire [4:0] Rs = Instruction[25:21];
wire [4:0] Rt = Instruction[20:16];
wire [4:0] Rd = Instruction[15:11];
wire [5:0] Funct = Instruction[5:0];
wire [15:0] Immediate = Instruction[15:0];
wire [25:0] JumpAddress = Instruction[25:0];
wire [2:0] Cp0_Sel = Instruction[2:0];
/*** IF (Instruction Fetch) Signals ***/
wire IF_Stall, IF_Flush;
wire IF_EXC_AdIF;
wire IF_Exception_Stall;
wire IF_Exception_Flush;
wire IF_IsBDS;
wire [31:0] IF_PCAdd4, IF_PC_PreExc, IF_PCIn, IF_PCOut, IF_Instruction;
/*** ID (Instruction Decode) Signals ***/
wire ID_Stall;
wire [1:0] ID_PCSrc;
wire [1:0] ID_RsFwdSel, ID_RtFwdSel;
wire ID_Link, ID_Movn, ID_Movz;
wire ID_SignExtend;
wire ID_LLSC;
wire ID_RegDst, ID_ALUSrcImm, ID_MemWrite, ID_MemRead, ID_MemByte, ID_MemHalf, ID_MemSignExtend, ID_RegWrite, ID_MemtoReg;
wire [4:0] ID_ALUOp;
wire ID_Mfc0, ID_Mtc0, ID_Eret;
wire ID_NextIsDelay;
wire ID_CanErr, ID_ID_CanErr, ID_EX_CanErr, ID_M_CanErr;
wire ID_KernelMode;
wire ID_ReverseEndian;
wire ID_Trap, ID_TrapCond;
wire ID_EXC_Sys, ID_EXC_Bp, ID_EXC_RI;
wire ID_Exception_Stall;
wire ID_Exception_Flush;
wire ID_PCSrc_Exc;
wire [31:0] ID_ExceptionPC;
wire ID_CP1, ID_CP2, ID_CP3;
wire [31:0] ID_PCAdd4;
wire [31:0] ID_ReadData1_RF, ID_ReadData1_End;
wire [31:0] ID_ReadData2_RF, ID_ReadData2_End;
wire [31:0] CP0_RegOut;
wire ID_CmpEQ, ID_CmpGZ, ID_CmpLZ, ID_CmpGEZ, ID_CmpLEZ;
wire [29:0] ID_SignExtImm = (ID_SignExtend & Immediate[15]) ? {14'h3FFF, Immediate} : {14'h0000, Immediate};
wire [31:0] ID_ImmLeftShift2 = {ID_SignExtImm[29:0], 2'b00};
wire [31:0] ID_JumpAddress = {ID_PCAdd4[31:28], JumpAddress[25:0], 2'b00};
wire [31:0] ID_BranchAddress;
wire [31:0] ID_RestartPC;
wire ID_IsBDS;
wire ID_Left, ID_Right;
wire ID_IsFlushed;
/*** EX (Execute) Signals ***/
wire EX_ALU_Stall, EX_Stall;
wire [1:0] EX_RsFwdSel, EX_RtFwdSel;
wire EX_Link;
wire [1:0] EX_LinkRegDst;
wire EX_ALUSrcImm;
wire [4:0] EX_ALUOp;
wire EX_Movn, EX_Movz;
wire EX_LLSC;
wire EX_MemRead, EX_MemWrite, EX_MemByte, EX_MemHalf, EX_MemSignExtend, EX_RegWrite, EX_MemtoReg;
wire [4:0] EX_Rs, EX_Rt;
wire EX_WantRsByEX, EX_NeedRsByEX, EX_WantRtByEX, EX_NeedRtByEX;
wire EX_Trap, EX_TrapCond;
wire EX_CanErr, EX_EX_CanErr, EX_M_CanErr;
wire EX_KernelMode;
wire EX_ReverseEndian;
wire EX_Exception_Stall;
wire EX_Exception_Flush;
wire [31:0] EX_ReadData1_PR, EX_ReadData1_Fwd, EX_ReadData2_PR, EX_ReadData2_Fwd, EX_ReadData2_Imm;
wire [31:0] EX_SignExtImm;
wire [4:0] EX_Rd, EX_RtRd, EX_Shamt;
wire [31:0] EX_ALUResult;
wire EX_BZero;
wire EX_EXC_Ov;
wire [31:0] EX_RestartPC;
wire EX_IsBDS;
wire EX_Left, EX_Right;
/*** MEM (Memory) Signals ***/
wire M_Stall, M_Stall_Controller;
wire M_LLSC;
wire M_MemRead, M_MemWrite, M_MemByte, M_MemHalf, M_MemSignExtend;
wire M_RegWrite, M_MemtoReg;
wire M_WriteDataFwdSel;
wire M_EXC_AdEL, M_EXC_AdES;
wire M_M_CanErr;
wire M_KernelMode;
wire M_ReverseEndian;
wire M_Trap, M_TrapCond;
wire M_EXC_Tr;
wire M_Exception_Flush;
wire [31:0] M_ALUResult, M_ReadData2_PR;
wire [4:0] M_RtRd;
wire [31:0] M_MemReadData;
wire [31:0] M_RestartPC;
wire M_IsBDS;
wire [31:0] M_WriteData_Pre;
wire M_Left, M_Right;
wire M_Exception_Stall;
/*** WB (Writeback) Signals ***/
wire WB_Stall, WB_RegWrite;
wire [31:0] WB_ReadData, WB_ALUResult;
wire [4:0] WB_RtRd;
wire [31:0] WB_WriteData;
/*** Other Signals ***/
wire [7:0] ID_DP_Hazards, HAZ_DP_Hazards;
/*** Assignments ***/
assign IF_Instruction = (IF_Stall) ? 32'h00000000 : InstMem_In;
assign IF_IsBDS = ID_NextIsDelay;
assign HAZ_DP_Hazards = {ID_DP_Hazards[7:4], EX_WantRsByEX, EX_NeedRsByEX, EX_WantRtByEX, EX_NeedRtByEX};
assign IF_EXC_AdIF = IF_PCOut[1] | IF_PCOut[0];
assign ID_CanErr = ID_ID_CanErr | ID_EX_CanErr | ID_M_CanErr;
assign EX_CanErr = EX_EX_CanErr | EX_M_CanErr;
assign M_CanErr = M_M_CanErr;
// External Memory Interface
reg IRead, IReadMask;
assign InstMem_Address = IF_PCOut[31:2];
assign DataMem_Address = M_ALUResult[31:2];
always @(posedge clock) begin
IRead <= (reset) ? 1 : ~InstMem_Ready;
IReadMask <= (reset) ? 0 : ((IRead & InstMem_Ready) ? 1 : ((~IF_Stall) ? 0 : IReadMask));
end
assign InstMem_Read = IRead & ~IReadMask;
/*** Datapath Controller ***/
Control Controller (
.ID_Stall (ID_Stall),
.OpCode (OpCode),
.Funct (Funct),
.Rs (Rs),
.Rt (Rt),
.Cmp_EQ (ID_CmpEQ),
.Cmp_GZ (ID_CmpGZ),
.Cmp_GEZ (ID_CmpGEZ),
.Cmp_LZ (ID_CmpLZ),
.Cmp_LEZ (ID_CmpLEZ),
.IF_Flush (IF_Flush),
.DP_Hazards (ID_DP_Hazards),
.PCSrc (ID_PCSrc),
.SignExtend (ID_SignExtend),
.Link (ID_Link),
.Movn (ID_Movn),
.Movz (ID_Movz),
.Mfc0 (ID_Mfc0),
.Mtc0 (ID_Mtc0),
.CP1 (ID_CP1),
.CP2 (ID_CP2),
.CP3 (ID_CP3),
.Eret (ID_Eret),
.Trap (ID_Trap),
.TrapCond (ID_TrapCond),
.EXC_Sys (ID_EXC_Sys),
.EXC_Bp (ID_EXC_Bp),
.EXC_RI (ID_EXC_RI),
.ID_CanErr (ID_ID_CanErr),
.EX_CanErr (ID_EX_CanErr),
.M_CanErr (ID_M_CanErr),
.NextIsDelay (ID_NextIsDelay),
.RegDst (ID_RegDst),
.ALUSrcImm (ID_ALUSrcImm),
.ALUOp (ID_ALUOp),
.LLSC (ID_LLSC),
.MemWrite (ID_MemWrite),
.MemRead (ID_MemRead),
.MemByte (ID_MemByte),
.MemHalf (ID_MemHalf),
.MemSignExtend (ID_MemSignExtend),
.Left (ID_Left),
.Right (ID_Right),
.RegWrite (ID_RegWrite),
.MemtoReg (ID_MemtoReg)
);
/*** Hazard and Forward Control Unit ***/
Hazard_Detection HazardControl (
.DP_Hazards (HAZ_DP_Hazards),
.ID_Rs (Rs),
.ID_Rt (Rt),
.EX_Rs (EX_Rs),
.EX_Rt (EX_Rt),
.EX_RtRd (EX_RtRd),
.MEM_RtRd (M_RtRd),
.WB_RtRd (WB_RtRd),
.EX_Link (EX_Link),
.EX_RegWrite (EX_RegWrite),
.MEM_RegWrite (M_RegWrite),
.WB_RegWrite (WB_RegWrite),
.MEM_MemRead (M_MemRead),
.MEM_MemWrite (M_MemWrite),
.InstMem_Read (InstMem_Read),
.InstMem_Ready (InstMem_Ready),
.Mfc0 (ID_Mfc0),
.IF_Exception_Stall (IF_Exception_Stall),
.ID_Exception_Stall (ID_Exception_Stall),
.EX_Exception_Stall (EX_Exception_Stall),
.EX_ALU_Stall (EX_ALU_Stall),
.M_Stall_Controller (M_Stall_Controller),
.IF_Stall (IF_Stall),
.ID_Stall (ID_Stall),
.EX_Stall (EX_Stall),
.M_Stall (M_Stall),
.WB_Stall (WB_Stall),
.ID_RsFwdSel (ID_RsFwdSel),
.ID_RtFwdSel (ID_RtFwdSel),
.EX_RsFwdSel (EX_RsFwdSel),
.EX_RtFwdSel (EX_RtFwdSel),
.M_WriteDataFwdSel (M_WriteDataFwdSel)
);
/*** Coprocessor 0: Exceptions and Interrupts ***/
CPZero CP0 (
.clock (clock),
.Mfc0 (ID_Mfc0),
.Mtc0 (ID_Mtc0),
.IF_Stall (IF_Stall),
.ID_Stall (ID_Stall),
.COP1 (ID_CP1),
.COP2 (ID_CP2),
.COP3 (ID_CP3),
.ERET (ID_Eret),
.Rd (Rd),
.Sel (Cp0_Sel),
.Reg_In (ID_ReadData2_End),
.Reg_Out (CP0_RegOut),
.KernelMode (ID_KernelMode),
.ReverseEndian (ID_ReverseEndian),
.Int (Interrupts),
.reset (reset),
.EXC_NMI (NMI),
.EXC_AdIF (IF_EXC_AdIF),
.EXC_AdEL (M_EXC_AdEL),
.EXC_AdES (M_EXC_AdES),
.EXC_Ov (EX_EXC_Ov),
.EXC_Tr (M_EXC_Tr),
.EXC_Sys (ID_EXC_Sys),
.EXC_Bp (ID_EXC_Bp),
.EXC_RI (ID_EXC_RI),
.ID_RestartPC (ID_RestartPC),
.EX_RestartPC (EX_RestartPC),
.M_RestartPC (M_RestartPC),
.ID_IsFlushed (ID_IsFlushed),
.IF_IsBD (IF_IsBDS),
.ID_IsBD (ID_IsBDS),
.EX_IsBD (EX_IsBDS),
.M_IsBD (M_IsBDS),
.BadAddr_M (M_ALUResult),
.BadAddr_IF (IF_PCOut),
.ID_CanErr (ID_CanErr),
.EX_CanErr (EX_CanErr),
.M_CanErr (M_CanErr),
.IF_Exception_Stall (IF_Exception_Stall),
.ID_Exception_Stall (ID_Exception_Stall),
.EX_Exception_Stall (EX_Exception_Stall),
.M_Exception_Stall (M_Exception_Stall),
.IF_Exception_Flush (IF_Exception_Flush),
.ID_Exception_Flush (ID_Exception_Flush),
.EX_Exception_Flush (EX_Exception_Flush),
.M_Exception_Flush (M_Exception_Flush),
.Exc_PC_Sel (ID_PCSrc_Exc),
.Exc_PC_Out (ID_ExceptionPC),
.IP (IP)
);
/*** PC Source Non-Exception Mux ***/
Mux4 #(.WIDTH(32)) PCSrcStd_Mux (
.sel (ID_PCSrc),
.in0 (IF_PCAdd4),
.in1 (ID_JumpAddress),
.in2 (ID_BranchAddress),
.in3 (ID_ReadData1_End),
.out (IF_PC_PreExc)
);
/*** PC Source Exception Mux ***/
Mux2 #(.WIDTH(32)) PCSrcExc_Mux (
.sel (ID_PCSrc_Exc),
.in0 (IF_PC_PreExc),
.in1 (ID_ExceptionPC),
.out (IF_PCIn)
);
/*** Program Counter (MIPS spec is 0xBFC00000 starting address) ***/
Register #(.WIDTH(32), .INIT(EXC_Vector_Base_Reset)) PC (
.clock (clock),
.reset (reset),
//.enable (~IF_Stall), // XXX verify. HERE. Was 1 but on stall latches PC+4, ad nauseum.
.enable (~(IF_Stall | ID_Stall)),
.D (IF_PCIn),
.Q (IF_PCOut)
);
/*** PC +4 Adder ***/
Add PC_Add4 (
.A (IF_PCOut),
.B (32'h00000004),
.C (IF_PCAdd4)
);
/*** Instruction Fetch -> Instruction Decode Stage Register ***/
IFID_Stage IFID (
.clock (clock),
.reset (reset),
.IF_Flush (IF_Exception_Flush | IF_Flush),
.IF_Stall (IF_Stall),
.ID_Stall (ID_Stall),
.IF_Instruction (IF_Instruction),
.IF_PCAdd4 (IF_PCAdd4),
.IF_PC (IF_PCOut),
.IF_IsBDS (IF_IsBDS),
.ID_Instruction (Instruction),
.ID_PCAdd4 (ID_PCAdd4),
.ID_RestartPC (ID_RestartPC),
.ID_IsBDS (ID_IsBDS),
.ID_IsFlushed (ID_IsFlushed)
);
/*** Register File ***/
RegisterFile RegisterFile (
.clock (clock),
.reset (reset),
.ReadReg1 (Rs),
.ReadReg2 (Rt),
.WriteReg (WB_RtRd),
.WriteData (WB_WriteData),
.RegWrite (WB_RegWrite),
.ReadData1 (ID_ReadData1_RF),
.ReadData2 (ID_ReadData2_RF)
);
/*** ID Rs Forwarding/Link Mux ***/
Mux4 #(.WIDTH(32)) IDRsFwd_Mux (
.sel (ID_RsFwdSel),
.in0 (ID_ReadData1_RF),
.in1 (M_ALUResult),
.in2 (WB_WriteData),
.in3 (32'hxxxxxxxx),
.out (ID_ReadData1_End)
);
/*** ID Rt Forwarding/CP0 Mfc0 Mux ***/
Mux4 #(.WIDTH(32)) IDRtFwd_Mux (
.sel (ID_RtFwdSel),
.in0 (ID_ReadData2_RF),
.in1 (M_ALUResult),
.in2 (WB_WriteData),
.in3 (CP0_RegOut),
.out (ID_ReadData2_End)
);
/*** Condition Compare Unit ***/
Compare Compare (
.A (ID_ReadData1_End),
.B (ID_ReadData2_End),
.EQ (ID_CmpEQ),
.GZ (ID_CmpGZ),
.LZ (ID_CmpLZ),
.GEZ (ID_CmpGEZ),
.LEZ (ID_CmpLEZ)
);
/*** Branch Address Adder ***/
Add BranchAddress_Add (
.A (ID_PCAdd4),
.B (ID_ImmLeftShift2),
.C (ID_BranchAddress)
);
/*** Instruction Decode -> Execute Pipeline Stage ***/
IDEX_Stage IDEX (
.clock (clock),
.reset (reset),
.ID_Flush (ID_Exception_Flush),
.ID_Stall (ID_Stall),
.EX_Stall (EX_Stall),
.ID_Link (ID_Link),
.ID_RegDst (ID_RegDst),
.ID_ALUSrcImm (ID_ALUSrcImm),
.ID_ALUOp (ID_ALUOp),
.ID_Movn (ID_Movn),
.ID_Movz (ID_Movz),
.ID_LLSC (ID_LLSC),
.ID_MemRead (ID_MemRead),
.ID_MemWrite (ID_MemWrite),
.ID_MemByte (ID_MemByte),
.ID_MemHalf (ID_MemHalf),
.ID_MemSignExtend (ID_MemSignExtend),
.ID_Left (ID_Left),
.ID_Right (ID_Right),
.ID_RegWrite (ID_RegWrite),
.ID_MemtoReg (ID_MemtoReg),
.ID_ReverseEndian (ID_ReverseEndian),
.ID_Rs (Rs),
.ID_Rt (Rt),
.ID_WantRsByEX (ID_DP_Hazards[3]),
.ID_NeedRsByEX (ID_DP_Hazards[2]),
.ID_WantRtByEX (ID_DP_Hazards[1]),
.ID_NeedRtByEX (ID_DP_Hazards[0]),
.ID_KernelMode (ID_KernelMode),
.ID_RestartPC (ID_RestartPC),
.ID_IsBDS (ID_IsBDS),
.ID_Trap (ID_Trap),
.ID_TrapCond (ID_TrapCond),
.ID_EX_CanErr (ID_EX_CanErr),
.ID_M_CanErr (ID_M_CanErr),
.ID_ReadData1 (ID_ReadData1_End),
.ID_ReadData2 (ID_ReadData2_End),
.ID_SignExtImm (ID_SignExtImm[16:0]),
.EX_Link (EX_Link),
.EX_LinkRegDst (EX_LinkRegDst),
.EX_ALUSrcImm (EX_ALUSrcImm),
.EX_ALUOp (EX_ALUOp),
.EX_Movn (EX_Movn),
.EX_Movz (EX_Movz),
.EX_LLSC (EX_LLSC),
.EX_MemRead (EX_MemRead),
.EX_MemWrite (EX_MemWrite),
.EX_MemByte (EX_MemByte),
.EX_MemHalf (EX_MemHalf),
.EX_MemSignExtend (EX_MemSignExtend),
.EX_Left (EX_Left),
.EX_Right (EX_Right),
.EX_RegWrite (EX_RegWrite),
.EX_MemtoReg (EX_MemtoReg),
.EX_ReverseEndian (EX_ReverseEndian),
.EX_Rs (EX_Rs),
.EX_Rt (EX_Rt),
.EX_WantRsByEX (EX_WantRsByEX),
.EX_NeedRsByEX (EX_NeedRsByEX),
.EX_WantRtByEX (EX_WantRtByEX),
.EX_NeedRtByEX (EX_NeedRtByEX),
.EX_KernelMode (EX_KernelMode),
.EX_RestartPC (EX_RestartPC),
.EX_IsBDS (EX_IsBDS),
.EX_Trap (EX_Trap),
.EX_TrapCond (EX_TrapCond),
.EX_EX_CanErr (EX_EX_CanErr),
.EX_M_CanErr (EX_M_CanErr),
.EX_ReadData1 (EX_ReadData1_PR),
.EX_ReadData2 (EX_ReadData2_PR),
.EX_SignExtImm (EX_SignExtImm),
.EX_Rd (EX_Rd),
.EX_Shamt (EX_Shamt)
);
/*** EX Rs Forwarding Mux ***/
Mux4 #(.WIDTH(32)) EXRsFwd_Mux (
.sel (EX_RsFwdSel),
.in0 (EX_ReadData1_PR),
.in1 (M_ALUResult),
.in2 (WB_WriteData),
.in3 (EX_RestartPC),
.out (EX_ReadData1_Fwd)
);
/*** EX Rt Forwarding / Link Mux ***/
Mux4 #(.WIDTH(32)) EXRtFwdLnk_Mux (
.sel (EX_RtFwdSel),
.in0 (EX_ReadData2_PR),
.in1 (M_ALUResult),
.in2 (WB_WriteData),
.in3 (32'h00000008),
.out (EX_ReadData2_Fwd)
);
/*** EX ALU Immediate Mux ***/
Mux2 #(.WIDTH(32)) EXALUImm_Mux (
.sel (EX_ALUSrcImm),
.in0 (EX_ReadData2_Fwd),
.in1 (EX_SignExtImm),
.out (EX_ReadData2_Imm)
);
/*** EX RtRd / Link Mux ***/
Mux4 #(.WIDTH(5)) EXRtRdLnk_Mux (
.sel (EX_LinkRegDst),
.in0 (EX_Rt),
.in1 (EX_Rd),
.in2 (5'b11111),
.in3 (5'bxxxxx),
.out (EX_RtRd)
);
/*** Arithmetic Logic Unit ***/
ALU ALU (
.clock (clock),
.reset (reset),
.EX_Stall (EX_Stall),
.EX_Flush (EX_Exception_Flush),
.A (EX_ReadData1_Fwd),
.B (EX_ReadData2_Imm),
.Operation (EX_ALUOp),
.Shamt (EX_Shamt),
.Result (EX_ALUResult),
.BZero (EX_BZero),
.EXC_Ov (EX_EXC_Ov),
.ALU_Stall (EX_ALU_Stall)
);
/*** Execute -> Memory Pipeline Stage ***/
EXMEM_Stage EXMEM (
.clock (clock),
.reset (reset),
.EX_Flush (EX_Exception_Flush),
.EX_Stall (EX_Stall),
.M_Stall (M_Stall),
.EX_Movn (EX_Movn),
.EX_Movz (EX_Movz),
.EX_BZero (EX_BZero),
.EX_RegWrite (EX_RegWrite),
.EX_MemtoReg (EX_MemtoReg),
.EX_ReverseEndian (EX_ReverseEndian),
.EX_LLSC (EX_LLSC),
.EX_MemRead (EX_MemRead),
.EX_MemWrite (EX_MemWrite),
.EX_MemByte (EX_MemByte),
.EX_MemHalf (EX_MemHalf),
.EX_MemSignExtend (EX_MemSignExtend),
.EX_Left (EX_Left),
.EX_Right (EX_Right),
.EX_KernelMode (EX_KernelMode),
.EX_RestartPC (EX_RestartPC),
.EX_IsBDS (EX_IsBDS),
.EX_Trap (EX_Trap),
.EX_TrapCond (EX_TrapCond),
.EX_M_CanErr (EX_M_CanErr),
.EX_ALU_Result (EX_ALUResult),
.EX_ReadData2 (EX_ReadData2_Fwd),
.EX_RtRd (EX_RtRd),
.M_RegWrite (M_RegWrite),
.M_MemtoReg (M_MemtoReg),
.M_ReverseEndian (M_ReverseEndian),
.M_LLSC (M_LLSC),
.M_MemRead (M_MemRead),
.M_MemWrite (M_MemWrite),
.M_MemByte (M_MemByte),
.M_MemHalf (M_MemHalf),
.M_MemSignExtend (M_MemSignExtend),
.M_Left (M_Left),
.M_Right (M_Right),
.M_KernelMode (M_KernelMode),
.M_RestartPC (M_RestartPC),
.M_IsBDS (M_IsBDS),
.M_Trap (M_Trap),
.M_TrapCond (M_TrapCond),
.M_M_CanErr (M_M_CanErr),
.M_ALU_Result (M_ALUResult),
.M_ReadData2 (M_ReadData2_PR),
.M_RtRd (M_RtRd)
);
/*** Trap Detection Unit ***/
TrapDetect TrapDetect (
.Trap (M_Trap),
.TrapCond (M_TrapCond),
.ALUResult (M_ALUResult),
.EXC_Tr (M_EXC_Tr)
);
/*** MEM Write Data Mux ***/
Mux2 #(.WIDTH(32)) MWriteData_Mux (
.sel (M_WriteDataFwdSel),
.in0 (M_ReadData2_PR),
.in1 (WB_WriteData),
.out (M_WriteData_Pre)
);
/*** Data Memory Controller ***/
MemControl DataMem_Controller (
.clock (clock),
.reset (reset),
.DataIn (M_WriteData_Pre),
.Address (M_ALUResult),
.MReadData (DataMem_In),
.MemRead (M_MemRead),
.MemWrite (M_MemWrite),
.DataMem_Ready (DataMem_Ready),
.Byte (M_MemByte),
.Half (M_MemHalf),
.SignExtend (M_MemSignExtend),
.KernelMode (M_KernelMode),
.ReverseEndian (M_ReverseEndian),
.LLSC (M_LLSC),
.ERET (ID_Eret),
.Left (M_Left),
.Right (M_Right),
.M_Exception_Stall (M_Exception_Stall),
.IF_Stall (IF_Stall),
.DataOut (M_MemReadData),
.MWriteData (DataMem_Out),
.WriteEnable (DataMem_Write),
.ReadEnable (DataMem_Read),
.M_Stall (M_Stall_Controller),
.EXC_AdEL (M_EXC_AdEL),
.EXC_AdES (M_EXC_AdES)
);
/*** Memory -> Writeback Pipeline Stage ***/
MEMWB_Stage MEMWB (
.clock (clock),
.reset (reset),
.M_Flush (M_Exception_Flush),
.M_Stall (M_Stall),
.WB_Stall (WB_Stall),
.M_RegWrite (M_RegWrite),
.M_MemtoReg (M_MemtoReg),
.M_ReadData (M_MemReadData),
.M_ALU_Result (M_ALUResult),
.M_RtRd (M_RtRd),
.WB_RegWrite (WB_RegWrite),
.WB_MemtoReg (WB_MemtoReg),
.WB_ReadData (WB_ReadData),
.WB_ALU_Result (WB_ALUResult),
.WB_RtRd (WB_RtRd)
);
/*** WB MemtoReg Mux ***/
Mux2 #(.WIDTH(32)) WBMemtoReg_Mux (
.sel (WB_MemtoReg),
.in0 (WB_ALUResult),
.in1 (WB_ReadData),
.out (WB_WriteData)
);
endmodule
@@ -0,0 +1,34 @@
`timescale 1ns / 1ps
/*
* File : Register.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.
*
* Standards/Formatting:
* Verilog 2001, 4 soft tab, wide column.
*
* Description:
* A variable-width register (d flip-flop) with configurable initial
* 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;
always @(posedge clock) begin
Q <= (reset) ? INIT : ((enable) ? D : Q);
end
endmodule
@@ -0,0 +1,58 @@
`timescale 1ns / 1ps
/*
* File : RegisterFile.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.
*
* Standards/Formatting:
* Verilog 2001, 4 soft tab, wide column.
*
* Description:
* A Register File for a MIPS processor. Contains 32 general-purpose
* 32-bit wide registers and two read ports. Register 0 always reads
* as zero.
*/
module RegisterFile(
input clock,
input reset,
input [4:0] ReadReg1, ReadReg2, WriteReg,
input [31:0] WriteData,
input RegWrite,
output [31:0] ReadData1, ReadData2
);
// Register file of 32 32-bit registers. Register 0 is hardwired to 0s
reg [31:0] registers [1:31];
// Initialize all to zero
integer i;
initial begin
for (i=1; i<32; i=i+1) begin
registers[i] <= 0;
end
end
// Sequential (clocked) write.
// 'WriteReg' is the register index to write. 'RegWrite' is the command.
always @(posedge clock) begin
if (reset) begin
for (i=1; i<32; i=i+1) begin
registers[i] <= 0;
end
end
else begin
if (WriteReg != 0)
registers[WriteReg] <= (RegWrite) ? WriteData : registers[WriteReg];
end
end
// Combinatorial Read. Register 0 is all 0s.
assign ReadData1 = (ReadReg1 == 0) ? 32'h00000000 : registers[ReadReg1];
assign ReadData2 = (ReadReg2 == 0) ? 32'h00000000 : registers[ReadReg2];
endmodule
@@ -0,0 +1,28 @@
`timescale 1ns / 1ps
/*
* File : TrapDetect.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 15-May-2012 GEA Initial design.
*
* Standards/Formatting:
* Verilog 2001, 4 soft tab, wide column.
*
* Description:
* Detects a Trap Exception in the pipeline.
*/
module TrapDetect(
input Trap,
input TrapCond,
input [31:0] ALUResult,
output EXC_Tr
);
wire ALUZero = (ALUResult == 32'h00000000);
assign EXC_Tr = Trap & (TrapCond ^ ALUZero);
endmodule
@@ -0,0 +1,43 @@
`timescale 1ns / 1ps
/*
* File : Piezo.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 11-Jun-2012 GEA Initial design.
*
* Standards/Formatting:
* Verilog 2001, 4 soft tab, wide column.
*
* Description:
* A sound driver for a piezo-electric transducer (or other
* oscillating device). When enabled, the output oscillates
* between high and low, switching at a rate determined by the
* 'count' register and clock frequency. The output is enabled
* when the highest bit is set on a Write.
*/
module Piezo_Driver(
input clock,
input reset,
input [24:0] data,
input Write,
output reg Ack,
output reg Piezo
);
reg [23:0] count;
reg [23:0] compare;
reg enabled;
always @(posedge clock) begin
count <= (reset | (count == compare)) ? 24'h000000 : count + 1;
compare <= (reset) ? 24'h000000 : ((Write) ? data[23:0] : compare);
enabled <= (reset) ? 0 : ((Write) ? data[24] : enabled);
Piezo <= (reset | ~enabled) ? 0 : ((count == compare) ? ~Piezo : Piezo);
Ack <= (reset) ? 0 : Write;
end
endmodule
@@ -0,0 +1,79 @@
`timescale 1ns / 1ps
////////////////////////////////////////////////////////////////////////////////
// Company:
// Engineer:
//
// Create Date: 12:38:44 09/10/2012
// Design Name: Top
// Module Name: C:/root/Work/Gauss/Final/Hardware/XUM_Singlecore/MIPS32-Pipelined-Hw/src/Simulation/Top_Tester.v
// Project Name: MIPS32-Pipelined-Hw
// Target Device:
// Tool versions:
// Description:
//
// Verilog Test Fixture created by ISE for module: Top
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
////////////////////////////////////////////////////////////////////////////////
module Top_Tester;
// 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;
// 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)
);
integer i;
initial begin
// Initialize Inputs
clock_100MHz = 0;
reset_n = 0;
Switch = 0;
UART_Rx = 0;
// Wait 100 ns for global reset to finish
#100;
// Add stimulus here
for (i=0; i<900000; i=i+1) begin
reset_n = (i < 28) ? 0 : 1;
clock_100MHz = ~clock_100MHz;
if (i > 4000) Switch <= 8'h00;
if (i > 100000) i = i - 1;
#5;
end
end
endmodule
@@ -0,0 +1,609 @@
<?xml version="1.0" encoding="UTF-8"?>
<wave_config>
<wave_state>
</wave_state>
<db_ref_list>
<db_ref path="C:/root/Work/Gauss/XUM/MIPS32-Pipelined-Hw/Top_Tester_isim_beh.wdb" id="1" type="auto">
<top_modules>
<top_module name="Top_Tester" />
<top_module name="glbl" />
</top_modules>
</db_ref>
</db_ref_list>
<WVObjectSize size="33" />
<wvobject fp_name="/Top_Tester/uut/clock" type="logic" db_ref_id="1">
<obj_property name="ElementShortName">clock</obj_property>
<obj_property name="ObjectShortName">clock</obj_property>
</wvobject>
<wvobject fp_name="/Top_Tester/uut/reset" type="logic" db_ref_id="1">
<obj_property name="ElementShortName">reset</obj_property>
<obj_property name="ObjectShortName">reset</obj_property>
</wvobject>
<wvobject fp_name="/Top_Tester/uut/MIPS32/IFID/ID_Instruction" type="array" db_ref_id="1">
<obj_property name="ElementShortName">ID_Instruction[31:0]</obj_property>
<obj_property name="ObjectShortName">ID_Instruction[31:0]</obj_property>
<obj_property name="Radix">HEXRADIX</obj_property>
</wvobject>
<wvobject fp_name="/Top_Tester/uut/MIPS32/ID_RestartPC" type="array" db_ref_id="1">
<obj_property name="ElementShortName">ID_RestartPC[31:0]</obj_property>
<obj_property name="ObjectShortName">ID_RestartPC[31:0]</obj_property>
<obj_property name="Radix">HEXRADIX</obj_property>
</wvobject>
<wvobject fp_name="group89" type="group">
<obj_property name="label">Stages</obj_property>
<obj_property name="DisplayName">label</obj_property>
<wvobject fp_name="/Top_Tester/uut/MIPS32/IDEX/EX_RestartPC" type="array" db_ref_id="1">
<obj_property name="ElementShortName">EX_RestartPC[31:0]</obj_property>
<obj_property name="ObjectShortName">EX_RestartPC[31:0]</obj_property>
<obj_property name="Radix">HEXRADIX</obj_property>
</wvobject>
<wvobject fp_name="/Top_Tester/uut/MIPS32/EXMEM/M_RestartPC" type="array" db_ref_id="1">
<obj_property name="ElementShortName">M_RestartPC[31:0]</obj_property>
<obj_property name="ObjectShortName">M_RestartPC[31:0]</obj_property>
<obj_property name="Radix">HEXRADIX</obj_property>
</wvobject>
</wvobject>
<wvobject fp_name="group92" type="group">
<obj_property name="label">Forwards</obj_property>
<obj_property name="DisplayName">label</obj_property>
<wvobject fp_name="/Top_Tester/uut/MIPS32/ID_RsFwdSel" type="array" db_ref_id="1">
<obj_property name="ElementShortName">ID_RsFwdSel[1:0]</obj_property>
<obj_property name="ObjectShortName">ID_RsFwdSel[1:0]</obj_property>
</wvobject>
<wvobject fp_name="/Top_Tester/uut/MIPS32/ID_RtFwdSel" type="array" db_ref_id="1">
<obj_property name="ElementShortName">ID_RtFwdSel[1:0]</obj_property>
<obj_property name="ObjectShortName">ID_RtFwdSel[1:0]</obj_property>
</wvobject>
<wvobject fp_name="/Top_Tester/uut/MIPS32/EX_RsFwdSel" type="array" db_ref_id="1">
<obj_property name="ElementShortName">EX_RsFwdSel[1:0]</obj_property>
<obj_property name="ObjectShortName">EX_RsFwdSel[1:0]</obj_property>
</wvobject>
<wvobject fp_name="/Top_Tester/uut/MIPS32/EX_RtFwdSel" type="array" db_ref_id="1">
<obj_property name="ElementShortName">EX_RtFwdSel[1:0]</obj_property>
<obj_property name="ObjectShortName">EX_RtFwdSel[1:0]</obj_property>
</wvobject>
<wvobject fp_name="/Top_Tester/uut/MIPS32/M_WriteDataFwdSel" type="logic" db_ref_id="1">
<obj_property name="ElementShortName">M_WriteDataFwdSel</obj_property>
<obj_property name="ObjectShortName">M_WriteDataFwdSel</obj_property>
</wvobject>
</wvobject>
<wvobject fp_name="group38" type="group">
<obj_property name="label">Stalls</obj_property>
<obj_property name="DisplayName">label</obj_property>
<wvobject fp_name="/Top_Tester/uut/MIPS32/HazardControl/WB_Stall" type="logic" db_ref_id="1">
<obj_property name="ElementShortName">WB_Stall</obj_property>
<obj_property name="ObjectShortName">WB_Stall</obj_property>
</wvobject>
<wvobject fp_name="/Top_Tester/uut/MIPS32/M_Stall" type="logic" db_ref_id="1">
<obj_property name="ElementShortName">M_Stall</obj_property>
<obj_property name="ObjectShortName">M_Stall</obj_property>
</wvobject>
<wvobject fp_name="/Top_Tester/uut/MIPS32/DataMem_Controller/M_Stall" type="logic" db_ref_id="1">
<obj_property name="DisplayName">label</obj_property>
<obj_property name="ElementShortName">M_Stall</obj_property>
<obj_property name="ObjectShortName">M_Stall</obj_property>
<obj_property name="label">M_Stall_Controller</obj_property>
</wvobject>
<wvobject fp_name="/Top_Tester/uut/MIPS32/HazardControl/EX_Stall" type="logic" db_ref_id="1">
<obj_property name="ElementShortName">EX_Stall</obj_property>
<obj_property name="ObjectShortName">EX_Stall</obj_property>
</wvobject>
<wvobject fp_name="/Top_Tester/uut/MIPS32/HazardControl/ID_Stall" type="logic" db_ref_id="1">
<obj_property name="ElementShortName">ID_Stall</obj_property>
<obj_property name="ObjectShortName">ID_Stall</obj_property>
</wvobject>
<wvobject fp_name="/Top_Tester/uut/MIPS32/HazardControl/IF_Stall" type="logic" db_ref_id="1">
<obj_property name="ElementShortName">IF_Stall</obj_property>
<obj_property name="ObjectShortName">IF_Stall</obj_property>
</wvobject>
</wvobject>
<wvobject fp_name="/Top_Tester/uut/MIPS32/InstMem_Read" type="logic" db_ref_id="1">
<obj_property name="ElementShortName">InstMem_Read</obj_property>
<obj_property name="ObjectShortName">InstMem_Read</obj_property>
</wvobject>
<wvobject fp_name="/Top_Tester/uut/MIPS32/InstMem_Ready" type="logic" db_ref_id="1">
<obj_property name="ElementShortName">InstMem_Ready</obj_property>
<obj_property name="ObjectShortName">InstMem_Ready</obj_property>
</wvobject>
<wvobject fp_name="/Top_Tester/uut/MIPS32_InstMem_In" type="array" db_ref_id="1">
<obj_property name="ElementShortName">MIPS32_InstMem_In[31:0]</obj_property>
<obj_property name="ObjectShortName">MIPS32_InstMem_In[31:0]</obj_property>
<obj_property name="Radix">HEXRADIX</obj_property>
</wvobject>
<wvobject fp_name="/Top_Tester/uut/MIPS32/IF_PCIn" type="array" db_ref_id="1">
<obj_property name="ElementShortName">IF_PCIn[31:0]</obj_property>
<obj_property name="ObjectShortName">IF_PCIn[31:0]</obj_property>
<obj_property name="Radix">HEXRADIX</obj_property>
</wvobject>
<wvobject fp_name="/Top_Tester/uut/MIPS32/IF_PCOut" type="array" db_ref_id="1">
<obj_property name="ElementShortName">IF_PCOut[31:0]</obj_property>
<obj_property name="ObjectShortName">IF_PCOut[31:0]</obj_property>
<obj_property name="Radix">HEXRADIX</obj_property>
</wvobject>
<wvobject fp_name="/Top_Tester/uut/MIPS32/PC/enable" type="logic" db_ref_id="1">
<obj_property name="DisplayName">label</obj_property>
<obj_property name="ElementShortName">enable</obj_property>
<obj_property name="ObjectShortName">enable</obj_property>
<obj_property name="label">PC_Enable</obj_property>
</wvobject>
<wvobject fp_name="/Top_Tester/uut/MIPS32/ID_PCSrc" type="array" db_ref_id="1">
<obj_property name="ElementShortName">ID_PCSrc[1:0]</obj_property>
<obj_property name="ObjectShortName">ID_PCSrc[1:0]</obj_property>
</wvobject>
<wvobject fp_name="/Top_Tester/uut/MIPS32/ID_PCSrc_Exc" type="logic" db_ref_id="1">
<obj_property name="ElementShortName">ID_PCSrc_Exc</obj_property>
<obj_property name="ObjectShortName">ID_PCSrc_Exc</obj_property>
</wvobject>
<wvobject fp_name="/Top_Tester/uut/MIPS32/EXMEM/M_RegWrite" type="logic" db_ref_id="1">
<obj_property name="ElementShortName">M_RegWrite</obj_property>
<obj_property name="ObjectShortName">M_RegWrite</obj_property>
</wvobject>
<wvobject fp_name="/Top_Tester/uut/MIPS32/DataMem_Controller/LLSC_Atomic" type="logic" db_ref_id="1">
<obj_property name="ElementShortName">LLSC_Atomic</obj_property>
<obj_property name="ObjectShortName">LLSC_Atomic</obj_property>
</wvobject>
<wvobject fp_name="group118" type="group">
<obj_property name="label">WB STAGE</obj_property>
<obj_property name="DisplayName">label</obj_property>
<wvobject fp_name="/Top_Tester/uut/MIPS32/MEMWB/M_Flush" type="logic" db_ref_id="1">
<obj_property name="ElementShortName">M_Flush</obj_property>
<obj_property name="ObjectShortName">M_Flush</obj_property>
</wvobject>
<wvobject fp_name="/Top_Tester/uut/MIPS32/MEMWB/M_Stall" type="logic" db_ref_id="1">
<obj_property name="ElementShortName">M_Stall</obj_property>
<obj_property name="ObjectShortName">M_Stall</obj_property>
</wvobject>
<wvobject fp_name="/Top_Tester/uut/MIPS32/MEMWB/WB_Stall" type="logic" db_ref_id="1">
<obj_property name="ElementShortName">WB_Stall</obj_property>
<obj_property name="ObjectShortName">WB_Stall</obj_property>
</wvobject>
<wvobject fp_name="/Top_Tester/uut/MIPS32/MEMWB/M_RtRd" type="array" db_ref_id="1">
<obj_property name="ElementShortName">M_RtRd[4:0]</obj_property>
<obj_property name="ObjectShortName">M_RtRd[4:0]</obj_property>
<obj_property name="Radix">UNSIGNEDDECRADIX</obj_property>
</wvobject>
<wvobject fp_name="/Top_Tester/uut/MIPS32/MEMWB/WB_RegWrite" type="logic" db_ref_id="1">
<obj_property name="ElementShortName">WB_RegWrite</obj_property>
<obj_property name="ObjectShortName">WB_RegWrite</obj_property>
</wvobject>
<wvobject fp_name="/Top_Tester/uut/MIPS32/MEMWB/WB_MemtoReg" type="logic" db_ref_id="1">
<obj_property name="ElementShortName">WB_MemtoReg</obj_property>
<obj_property name="ObjectShortName">WB_MemtoReg</obj_property>
</wvobject>
<wvobject fp_name="/Top_Tester/uut/MIPS32/MEMWB/M_ReadData" type="array" db_ref_id="1">
<obj_property name="ElementShortName">M_ReadData[31:0]</obj_property>
<obj_property name="ObjectShortName">M_ReadData[31:0]</obj_property>
<obj_property name="Radix">HEXRADIX</obj_property>
</wvobject>
<wvobject fp_name="/Top_Tester/uut/MIPS32/MEMWB/WB_ReadData" type="array" db_ref_id="1">
<obj_property name="ElementShortName">WB_ReadData[31:0]</obj_property>
<obj_property name="ObjectShortName">WB_ReadData[31:0]</obj_property>
<obj_property name="Radix">HEXRADIX</obj_property>
</wvobject>
<wvobject fp_name="/Top_Tester/uut/MIPS32/MEMWB/WB_ALU_Result" type="array" db_ref_id="1">
<obj_property name="ElementShortName">WB_ALU_Result[31:0]</obj_property>
<obj_property name="ObjectShortName">WB_ALU_Result[31:0]</obj_property>
<obj_property name="Radix">HEXRADIX</obj_property>
</wvobject>
<wvobject fp_name="/Top_Tester/uut/MIPS32/WB_WriteData" type="array" db_ref_id="1">
<obj_property name="ElementShortName">WB_WriteData[31:0]</obj_property>
<obj_property name="ObjectShortName">WB_WriteData[31:0]</obj_property>
<obj_property name="Radix">HEXRADIX</obj_property>
</wvobject>
</wvobject>
<wvobject fp_name="/Top_Tester/uut/MIPS32/DataMem_Controller/Address" type="array" db_ref_id="1">
<obj_property name="ElementShortName">Address[31:0]</obj_property>
<obj_property name="ObjectShortName">Address[31:0]</obj_property>
<obj_property name="Radix">HEXRADIX</obj_property>
</wvobject>
<wvobject fp_name="/Top_Tester/uut/MIPS32/DataMem_Address" type="array" db_ref_id="1">
<obj_property name="ElementShortName">DataMem_Address[29:0]</obj_property>
<obj_property name="ObjectShortName">DataMem_Address[29:0]</obj_property>
<obj_property name="Radix">HEXRADIX</obj_property>
</wvobject>
<wvobject fp_name="/Top_Tester/uut/MIPS32/DataMem_Out" type="array" db_ref_id="1">
<obj_property name="ElementShortName">DataMem_Out[31:0]</obj_property>
<obj_property name="ObjectShortName">DataMem_Out[31:0]</obj_property>
<obj_property name="Radix">HEXRADIX</obj_property>
</wvobject>
<wvobject fp_name="/Top_Tester/uut/MIPS32/DataMem_In" type="array" db_ref_id="1">
<obj_property name="ElementShortName">DataMem_In[31:0]</obj_property>
<obj_property name="ObjectShortName">DataMem_In[31:0]</obj_property>
<obj_property name="Radix">HEXRADIX</obj_property>
</wvobject>
<wvobject fp_name="/Top_Tester/uut/MIPS32/DataMem_Write" type="array" db_ref_id="1">
<obj_property name="ElementShortName">DataMem_Write[3:0]</obj_property>
<obj_property name="ObjectShortName">DataMem_Write[3:0]</obj_property>
</wvobject>
<wvobject fp_name="/Top_Tester/uut/MIPS32/DataMem_Read" type="logic" db_ref_id="1">
<obj_property name="ElementShortName">DataMem_Read</obj_property>
<obj_property name="ObjectShortName">DataMem_Read</obj_property>
</wvobject>
<wvobject fp_name="/Top_Tester/uut/MIPS32/DataMem_Ready" type="logic" db_ref_id="1">
<obj_property name="ElementShortName">DataMem_Ready</obj_property>
<obj_property name="ObjectShortName">DataMem_Ready</obj_property>
</wvobject>
<wvobject fp_name="/Top_Tester/uut/MIPS32/M_MemRead" type="logic" db_ref_id="1">
<obj_property name="ElementShortName">M_MemRead</obj_property>
<obj_property name="ObjectShortName">M_MemRead</obj_property>
</wvobject>
<wvobject fp_name="/Top_Tester/uut/MIPS32/M_MemWrite" type="logic" db_ref_id="1">
<obj_property name="ElementShortName">M_MemWrite</obj_property>
<obj_property name="ObjectShortName">M_MemWrite</obj_property>
</wvobject>
<wvobject fp_name="/Top_Tester/uut/MIPS32/DataMem_Controller/WriteCondition" type="logic" db_ref_id="1">
<obj_property name="ElementShortName">WriteCondition</obj_property>
<obj_property name="ObjectShortName">WriteCondition</obj_property>
</wvobject>
<wvobject fp_name="/Top_Tester/uut/Memory/web" type="array" db_ref_id="1">
<obj_property name="ElementShortName">web[3:0]</obj_property>
<obj_property name="ObjectShortName">web[3:0]</obj_property>
</wvobject>
<wvobject fp_name="group19" type="group">
<obj_property name="label">Exceptions</obj_property>
<obj_property name="DisplayName">label</obj_property>
<wvobject fp_name="/Top_Tester/uut/MIPS32/CP0/EXC_AdIF" type="logic" db_ref_id="1">
<obj_property name="ElementShortName">EXC_AdIF</obj_property>
<obj_property name="ObjectShortName">EXC_AdIF</obj_property>
</wvobject>
<wvobject fp_name="/Top_Tester/uut/MIPS32/CP0/EXC_AdEL" type="logic" db_ref_id="1">
<obj_property name="ElementShortName">EXC_AdEL</obj_property>
<obj_property name="ObjectShortName">EXC_AdEL</obj_property>
</wvobject>
<wvobject fp_name="/Top_Tester/uut/MIPS32/CP0/EXC_AdES" type="logic" db_ref_id="1">
<obj_property name="ElementShortName">EXC_AdES</obj_property>
<obj_property name="ObjectShortName">EXC_AdES</obj_property>
</wvobject>
<wvobject fp_name="/Top_Tester/uut/MIPS32/CP0/EXC_Ov" type="logic" db_ref_id="1">
<obj_property name="ElementShortName">EXC_Ov</obj_property>
<obj_property name="ObjectShortName">EXC_Ov</obj_property>
</wvobject>
<wvobject fp_name="/Top_Tester/uut/MIPS32/CP0/EXC_Tr" type="logic" db_ref_id="1">
<obj_property name="ElementShortName">EXC_Tr</obj_property>
<obj_property name="ObjectShortName">EXC_Tr</obj_property>
</wvobject>
<wvobject fp_name="/Top_Tester/uut/MIPS32/CP0/EXC_Sys" type="logic" db_ref_id="1">
<obj_property name="ElementShortName">EXC_Sys</obj_property>
<obj_property name="ObjectShortName">EXC_Sys</obj_property>
</wvobject>
<wvobject fp_name="/Top_Tester/uut/MIPS32/CP0/EXC_Bp" type="logic" db_ref_id="1">
<obj_property name="ElementShortName">EXC_Bp</obj_property>
<obj_property name="ObjectShortName">EXC_Bp</obj_property>
</wvobject>
<wvobject fp_name="/Top_Tester/uut/MIPS32/CP0/EXC_RI" type="logic" db_ref_id="1">
<obj_property name="ElementShortName">EXC_RI</obj_property>
<obj_property name="ObjectShortName">EXC_RI</obj_property>
</wvobject>
<wvobject fp_name="/Top_Tester/uut/MIPS32/CP0/EXC_CpU" type="logic" db_ref_id="1">
<obj_property name="ElementShortName">EXC_CpU</obj_property>
<obj_property name="ObjectShortName">EXC_CpU</obj_property>
</wvobject>
<wvobject fp_name="/Top_Tester/uut/MIPS32/CP0/EXC_Int" type="logic" db_ref_id="1">
<obj_property name="ElementShortName">EXC_Int</obj_property>
<obj_property name="ObjectShortName">EXC_Int</obj_property>
</wvobject>
</wvobject>
<wvobject fp_name="group78" type="group">
<obj_property name="label">CP0</obj_property>
<obj_property name="DisplayName">label</obj_property>
<wvobject fp_name="/Top_Tester/uut/MIPS32/CP0/ID_Exception_Stall" type="logic" db_ref_id="1">
<obj_property name="ElementShortName">ID_Exception_Stall</obj_property>
<obj_property name="ObjectShortName">ID_Exception_Stall</obj_property>
</wvobject>
<wvobject fp_name="group100" type="group">
<obj_property name="label">Flushes</obj_property>
<obj_property name="DisplayName">label</obj_property>
<wvobject fp_name="/Top_Tester/uut/MIPS32/CP0/IF_Exception_Flush" type="logic" db_ref_id="1">
<obj_property name="ElementShortName">IF_Exception_Flush</obj_property>
<obj_property name="ObjectShortName">IF_Exception_Flush</obj_property>
</wvobject>
<wvobject fp_name="/Top_Tester/uut/MIPS32/CP0/ID_Exception_Flush" type="logic" db_ref_id="1">
<obj_property name="ElementShortName">ID_Exception_Flush</obj_property>
<obj_property name="ObjectShortName">ID_Exception_Flush</obj_property>
</wvobject>
<wvobject fp_name="/Top_Tester/uut/MIPS32/CP0/EX_Exception_Flush" type="logic" db_ref_id="1">
<obj_property name="ElementShortName">EX_Exception_Flush</obj_property>
<obj_property name="ObjectShortName">EX_Exception_Flush</obj_property>
</wvobject>
<wvobject fp_name="/Top_Tester/uut/MIPS32/CP0/M_Exception_Flush" type="logic" db_ref_id="1">
<obj_property name="ElementShortName">M_Exception_Flush</obj_property>
<obj_property name="ObjectShortName">M_Exception_Flush</obj_property>
</wvobject>
</wvobject>
<wvobject fp_name="/Top_Tester/uut/MIPS32/CP0/ID_Exception_Ready" type="logic" db_ref_id="1">
<obj_property name="ElementShortName">ID_Exception_Ready</obj_property>
<obj_property name="ObjectShortName">ID_Exception_Ready</obj_property>
</wvobject>
<wvobject fp_name="/Top_Tester/uut/MIPS32/CP0/EX_Exception_Ready" type="logic" db_ref_id="1">
<obj_property name="ElementShortName">EX_Exception_Ready</obj_property>
<obj_property name="ObjectShortName">EX_Exception_Ready</obj_property>
</wvobject>
<wvobject fp_name="/Top_Tester/uut/MIPS32/CP0/M_Exception_Ready" type="logic" db_ref_id="1">
<obj_property name="ElementShortName">M_Exception_Ready</obj_property>
<obj_property name="ObjectShortName">M_Exception_Ready</obj_property>
</wvobject>
<wvobject fp_name="/Top_Tester/uut/MIPS32/TrapDetect/EXC_Tr" type="logic" db_ref_id="1">
<obj_property name="DisplayName">label</obj_property>
<obj_property name="ElementShortName">EXC_Tr</obj_property>
<obj_property name="ObjectShortName">EXC_Tr</obj_property>
<obj_property name="label">M_EXC_Tr</obj_property>
</wvobject>
<wvobject fp_name="/Top_Tester/uut/MIPS32/CP0/ErrorEPC" type="array" db_ref_id="1">
<obj_property name="ElementShortName">ErrorEPC[31:0]</obj_property>
<obj_property name="ObjectShortName">ErrorEPC[31:0]</obj_property>
<obj_property name="Radix">HEXRADIX</obj_property>
</wvobject>
<wvobject fp_name="/Top_Tester/uut/MIPS32/CP0/EPC" type="array" db_ref_id="1">
<obj_property name="ElementShortName">EPC[31:0]</obj_property>
<obj_property name="ObjectShortName">EPC[31:0]</obj_property>
<obj_property name="Radix">HEXRADIX</obj_property>
</wvobject>
<wvobject fp_name="/Top_Tester/uut/MIPS32/CP0/Exc_PC_Out" type="array" db_ref_id="1">
<obj_property name="ElementShortName">Exc_PC_Out[31:0]</obj_property>
<obj_property name="ObjectShortName">Exc_PC_Out[31:0]</obj_property>
<obj_property name="Radix">HEXRADIX</obj_property>
</wvobject>
<wvobject fp_name="/Top_Tester/uut/MIPS32/CP0/Status_ERL" type="logic" db_ref_id="1">
<obj_property name="ElementShortName">Status_ERL</obj_property>
<obj_property name="ObjectShortName">Status_ERL</obj_property>
</wvobject>
<wvobject fp_name="/Top_Tester/uut/MIPS32/CP0/Status_EXL" type="logic" db_ref_id="1">
<obj_property name="ElementShortName">Status_EXL</obj_property>
<obj_property name="ObjectShortName">Status_EXL</obj_property>
</wvobject>
<wvobject fp_name="/Top_Tester/uut/MIPS32/CP0/Status" type="array" db_ref_id="1">
<obj_property name="ElementShortName">Status[31:0]</obj_property>
<obj_property name="ObjectShortName">Status[31:0]</obj_property>
<obj_property name="Radix">HEXRADIX</obj_property>
</wvobject>
<wvobject fp_name="/Top_Tester/uut/MIPS32/CP0/Cause" type="array" db_ref_id="1">
<obj_property name="ElementShortName">Cause[31:0]</obj_property>
<obj_property name="ObjectShortName">Cause[31:0]</obj_property>
<obj_property name="Radix">HEXRADIX</obj_property>
</wvobject>
<wvobject fp_name="/Top_Tester/uut/MIPS32/CP0/Mtc0" type="logic" db_ref_id="1">
<obj_property name="ElementShortName">Mtc0</obj_property>
<obj_property name="ObjectShortName">Mtc0</obj_property>
</wvobject>
<wvobject fp_name="/Top_Tester/uut/MIPS32/CP0/CP0_WriteCond" type="logic" db_ref_id="1">
<obj_property name="ElementShortName">CP0_WriteCond</obj_property>
<obj_property name="ObjectShortName">CP0_WriteCond</obj_property>
</wvobject>
<wvobject fp_name="/Top_Tester/uut/MIPS32/CP0/ERET" type="logic" db_ref_id="1">
<obj_property name="ElementShortName">ERET</obj_property>
<obj_property name="ObjectShortName">ERET</obj_property>
</wvobject>
<wvobject fp_name="/Top_Tester/uut/MIPS32/Interrupts" type="array" db_ref_id="1">
<obj_property name="ElementShortName">Interrupts[4:0]</obj_property>
<obj_property name="ObjectShortName">Interrupts[4:0]</obj_property>
<obj_property name="Radix">BINARYRADIX</obj_property>
</wvobject>
</wvobject>
<wvobject fp_name="group39" type="group">
<obj_property name="label">Registers</obj_property>
<obj_property name="DisplayName">label</obj_property>
<wvobject fp_name="/Top_Tester/uut/MIPS32/RegisterFile/registers[1]" type="array" db_ref_id="1">
<obj_property name="DisplayName">label</obj_property>
<obj_property name="ElementShortName">[1,31:0]</obj_property>
<obj_property name="ObjectShortName">registers[1,31:0]</obj_property>
<obj_property name="Radix">HEXRADIX</obj_property>
<obj_property name="label">at (1)</obj_property>
</wvobject>
<wvobject fp_name="/Top_Tester/uut/MIPS32/RegisterFile/registers[2]" type="array" db_ref_id="1">
<obj_property name="DisplayName">label</obj_property>
<obj_property name="ElementShortName">[2,31:0]</obj_property>
<obj_property name="ObjectShortName">registers[2,31:0]</obj_property>
<obj_property name="Radix">HEXRADIX</obj_property>
<obj_property name="label">v0 (2)</obj_property>
</wvobject>
<wvobject fp_name="/Top_Tester/uut/MIPS32/RegisterFile/registers[3]" type="array" db_ref_id="1">
<obj_property name="DisplayName">label</obj_property>
<obj_property name="ElementShortName">[3,31:0]</obj_property>
<obj_property name="ObjectShortName">registers[3,31:0]</obj_property>
<obj_property name="Radix">HEXRADIX</obj_property>
<obj_property name="label">v1 (3)</obj_property>
</wvobject>
<wvobject fp_name="/Top_Tester/uut/MIPS32/RegisterFile/registers[4]" type="array" db_ref_id="1">
<obj_property name="DisplayName">label</obj_property>
<obj_property name="ElementShortName">[4,31:0]</obj_property>
<obj_property name="ObjectShortName">registers[4,31:0]</obj_property>
<obj_property name="Radix">HEXRADIX</obj_property>
<obj_property name="label">a0 (4)</obj_property>
</wvobject>
<wvobject fp_name="/Top_Tester/uut/MIPS32/RegisterFile/registers[5]" type="array" db_ref_id="1">
<obj_property name="DisplayName">label</obj_property>
<obj_property name="ElementShortName">[5,31:0]</obj_property>
<obj_property name="ObjectShortName">registers[5,31:0]</obj_property>
<obj_property name="Radix">ASCIIRADIX</obj_property>
<obj_property name="label">a1 (5)</obj_property>
</wvobject>
<wvobject fp_name="/Top_Tester/uut/MIPS32/RegisterFile/registers[6]" type="array" db_ref_id="1">
<obj_property name="DisplayName">label</obj_property>
<obj_property name="ElementShortName">[6,31:0]</obj_property>
<obj_property name="ObjectShortName">registers[6,31:0]</obj_property>
<obj_property name="Radix">HEXRADIX</obj_property>
<obj_property name="label">a2 (6)</obj_property>
</wvobject>
<wvobject fp_name="/Top_Tester/uut/MIPS32/RegisterFile/registers[7]" type="array" db_ref_id="1">
<obj_property name="DisplayName">label</obj_property>
<obj_property name="ElementShortName">[7,31:0]</obj_property>
<obj_property name="ObjectShortName">registers[7,31:0]</obj_property>
<obj_property name="Radix">HEXRADIX</obj_property>
<obj_property name="label">a3 (7)</obj_property>
</wvobject>
<wvobject fp_name="/Top_Tester/uut/MIPS32/RegisterFile/registers[8]" type="array" db_ref_id="1">
<obj_property name="DisplayName">label</obj_property>
<obj_property name="ElementShortName">[8,31:0]</obj_property>
<obj_property name="ObjectShortName">registers[8,31:0]</obj_property>
<obj_property name="Radix">UNSIGNEDDECRADIX</obj_property>
<obj_property name="label">t0 (8)</obj_property>
</wvobject>
<wvobject fp_name="/Top_Tester/uut/MIPS32/RegisterFile/registers[9]" type="array" db_ref_id="1">
<obj_property name="DisplayName">label</obj_property>
<obj_property name="ElementShortName">[9,31:0]</obj_property>
<obj_property name="ObjectShortName">registers[9,31:0]</obj_property>
<obj_property name="Radix">UNSIGNEDDECRADIX</obj_property>
<obj_property name="label">t1 (9)</obj_property>
</wvobject>
<wvobject fp_name="/Top_Tester/uut/MIPS32/RegisterFile/registers[10]" type="array" db_ref_id="1">
<obj_property name="DisplayName">label</obj_property>
<obj_property name="ElementShortName">[10,31:0]</obj_property>
<obj_property name="ObjectShortName">registers[10,31:0]</obj_property>
<obj_property name="Radix">HEXRADIX</obj_property>
<obj_property name="label">t2 (10)</obj_property>
</wvobject>
<wvobject fp_name="/Top_Tester/uut/MIPS32/RegisterFile/registers[11]" type="array" db_ref_id="1">
<obj_property name="DisplayName">label</obj_property>
<obj_property name="ElementShortName">[11,31:0]</obj_property>
<obj_property name="ObjectShortName">registers[11,31:0]</obj_property>
<obj_property name="Radix">HEXRADIX</obj_property>
<obj_property name="label">t3 (11)</obj_property>
</wvobject>
<wvobject fp_name="/Top_Tester/uut/MIPS32/RegisterFile/registers[12]" type="array" db_ref_id="1">
<obj_property name="DisplayName">label</obj_property>
<obj_property name="ElementShortName">[12,31:0]</obj_property>
<obj_property name="ObjectShortName">registers[12,31:0]</obj_property>
<obj_property name="Radix">HEXRADIX</obj_property>
<obj_property name="label">t4 (12)</obj_property>
</wvobject>
<wvobject fp_name="/Top_Tester/uut/MIPS32/RegisterFile/registers[13]" type="array" db_ref_id="1">
<obj_property name="DisplayName">label</obj_property>
<obj_property name="ElementShortName">[13,31:0]</obj_property>
<obj_property name="ObjectShortName">registers[13,31:0]</obj_property>
<obj_property name="Radix">HEXRADIX</obj_property>
<obj_property name="label">t5 (13)</obj_property>
</wvobject>
<wvobject fp_name="/Top_Tester/uut/MIPS32/RegisterFile/registers[14]" type="array" db_ref_id="1">
<obj_property name="DisplayName">label</obj_property>
<obj_property name="ElementShortName">[14,31:0]</obj_property>
<obj_property name="ObjectShortName">registers[14,31:0]</obj_property>
<obj_property name="Radix">HEXRADIX</obj_property>
<obj_property name="label">t6 (14)</obj_property>
</wvobject>
<wvobject fp_name="/Top_Tester/uut/MIPS32/RegisterFile/registers[15]" type="array" db_ref_id="1">
<obj_property name="DisplayName">label</obj_property>
<obj_property name="ElementShortName">[15,31:0]</obj_property>
<obj_property name="ObjectShortName">registers[15,31:0]</obj_property>
<obj_property name="Radix">HEXRADIX</obj_property>
<obj_property name="label">t7 (15)</obj_property>
</wvobject>
<wvobject fp_name="/Top_Tester/uut/MIPS32/RegisterFile/registers[16]" type="array" db_ref_id="1">
<obj_property name="DisplayName">label</obj_property>
<obj_property name="ElementShortName">[16,31:0]</obj_property>
<obj_property name="ObjectShortName">registers[16,31:0]</obj_property>
<obj_property name="Radix">HEXRADIX</obj_property>
<obj_property name="label">s0 (16)</obj_property>
</wvobject>
<wvobject fp_name="/Top_Tester/uut/MIPS32/RegisterFile/registers[17]" type="array" db_ref_id="1">
<obj_property name="ElementShortName">[17,31:0]</obj_property>
<obj_property name="ObjectShortName">registers[17,31:0]</obj_property>
<obj_property name="Radix">HEXRADIX</obj_property>
</wvobject>
<wvobject fp_name="/Top_Tester/uut/MIPS32/RegisterFile/registers[18]" type="array" db_ref_id="1">
<obj_property name="ElementShortName">[18,31:0]</obj_property>
<obj_property name="ObjectShortName">registers[18,31:0]</obj_property>
<obj_property name="Radix">HEXRADIX</obj_property>
</wvobject>
<wvobject fp_name="/Top_Tester/uut/MIPS32/RegisterFile/registers[19]" type="array" db_ref_id="1">
<obj_property name="ElementShortName">[19,31:0]</obj_property>
<obj_property name="ObjectShortName">registers[19,31:0]</obj_property>
<obj_property name="Radix">HEXRADIX</obj_property>
</wvobject>
<wvobject fp_name="/Top_Tester/uut/MIPS32/RegisterFile/registers[20]" type="array" db_ref_id="1">
<obj_property name="ElementShortName">[20,31:0]</obj_property>
<obj_property name="ObjectShortName">registers[20,31:0]</obj_property>
<obj_property name="Radix">HEXRADIX</obj_property>
</wvobject>
<wvobject fp_name="/Top_Tester/uut/MIPS32/RegisterFile/registers[21]" type="array" db_ref_id="1">
<obj_property name="ElementShortName">[21,31:0]</obj_property>
<obj_property name="ObjectShortName">registers[21,31:0]</obj_property>
<obj_property name="Radix">HEXRADIX</obj_property>
</wvobject>
<wvobject fp_name="/Top_Tester/uut/MIPS32/RegisterFile/registers[22]" type="array" db_ref_id="1">
<obj_property name="ElementShortName">[22,31:0]</obj_property>
<obj_property name="ObjectShortName">registers[22,31:0]</obj_property>
<obj_property name="Radix">HEXRADIX</obj_property>
</wvobject>
<wvobject fp_name="/Top_Tester/uut/MIPS32/RegisterFile/registers[23]" type="array" db_ref_id="1">
<obj_property name="DisplayName">label</obj_property>
<obj_property name="ElementShortName">[23,31:0]</obj_property>
<obj_property name="ObjectShortName">registers[23,31:0]</obj_property>
<obj_property name="Radix">HEXRADIX</obj_property>
<obj_property name="label">s7 (23)</obj_property>
</wvobject>
<wvobject fp_name="/Top_Tester/uut/MIPS32/RegisterFile/registers[24]" type="array" db_ref_id="1">
<obj_property name="ElementShortName">[24,31:0]</obj_property>
<obj_property name="ObjectShortName">registers[24,31:0]</obj_property>
<obj_property name="Radix">HEXRADIX</obj_property>
</wvobject>
<wvobject fp_name="/Top_Tester/uut/MIPS32/RegisterFile/registers[25]" type="array" db_ref_id="1">
<obj_property name="ElementShortName">[25,31:0]</obj_property>
<obj_property name="ObjectShortName">registers[25,31:0]</obj_property>
<obj_property name="Radix">HEXRADIX</obj_property>
</wvobject>
<wvobject fp_name="/Top_Tester/uut/MIPS32/RegisterFile/registers[26]" type="array" db_ref_id="1">
<obj_property name="ElementShortName">[26,31:0]</obj_property>
<obj_property name="ObjectShortName">registers[26,31:0]</obj_property>
<obj_property name="Radix">HEXRADIX</obj_property>
</wvobject>
<wvobject fp_name="/Top_Tester/uut/MIPS32/RegisterFile/registers[27]" type="array" db_ref_id="1">
<obj_property name="ElementShortName">[27,31:0]</obj_property>
<obj_property name="ObjectShortName">registers[27,31:0]</obj_property>
<obj_property name="Radix">HEXRADIX</obj_property>
</wvobject>
<wvobject fp_name="/Top_Tester/uut/MIPS32/RegisterFile/registers[28]" type="array" db_ref_id="1">
<obj_property name="ElementShortName">[28,31:0]</obj_property>
<obj_property name="ObjectShortName">registers[28,31:0]</obj_property>
<obj_property name="Radix">HEXRADIX</obj_property>
</wvobject>
<wvobject fp_name="/Top_Tester/uut/MIPS32/RegisterFile/registers[29]" type="array" db_ref_id="1">
<obj_property name="ElementShortName">[29,31:0]</obj_property>
<obj_property name="ObjectShortName">registers[29,31:0]</obj_property>
<obj_property name="Radix">HEXRADIX</obj_property>
</wvobject>
<wvobject fp_name="/Top_Tester/uut/MIPS32/RegisterFile/registers[30]" type="array" db_ref_id="1">
<obj_property name="ElementShortName">[30,31:0]</obj_property>
<obj_property name="ObjectShortName">registers[30,31:0]</obj_property>
<obj_property name="Radix">HEXRADIX</obj_property>
</wvobject>
<wvobject fp_name="/Top_Tester/uut/MIPS32/RegisterFile/registers[31]" type="array" db_ref_id="1">
<obj_property name="ElementShortName">[31,31:0]</obj_property>
<obj_property name="ObjectShortName">registers[31,31:0]</obj_property>
<obj_property name="Radix">HEXRADIX</obj_property>
</wvobject>
</wvobject>
<wvobject fp_name="group105" type="group">
<obj_property name="label">I2C</obj_property>
<obj_property name="DisplayName">label</obj_property>
<wvobject fp_name="/Top_Tester/uut/I2C/PHY/scl" type="logic" db_ref_id="1">
<obj_property name="ElementShortName">scl</obj_property>
<obj_property name="ObjectShortName">scl</obj_property>
</wvobject>
<wvobject fp_name="/Top_Tester/uut/I2C/i2c_sda" type="logic" db_ref_id="1">
<obj_property name="ElementShortName">i2c_sda</obj_property>
<obj_property name="ObjectShortName">i2c_sda</obj_property>
</wvobject>
<wvobject fp_name="/Top_Tester/uut/I2C/PHY/scl_tick_90" type="logic" db_ref_id="1">
<obj_property name="ElementShortName">scl_tick_90</obj_property>
<obj_property name="ObjectShortName">scl_tick_90</obj_property>
</wvobject>
<wvobject fp_name="/Top_Tester/uut/I2C/PHY/state" type="array" db_ref_id="1">
<obj_property name="ElementShortName">state[5:0]</obj_property>
<obj_property name="ObjectShortName">state[5:0]</obj_property>
<obj_property name="Radix">UNSIGNEDDECRADIX</obj_property>
</wvobject>
<wvobject fp_name="/Top_Tester/uut/I2C/PHY/Write" type="logic" db_ref_id="1">
<obj_property name="ElementShortName">Write</obj_property>
<obj_property name="ObjectShortName">Write</obj_property>
</wvobject>
<wvobject fp_name="/Top_Tester/uut/I2C/I2C_Nack" type="logic" db_ref_id="1">
<obj_property name="ElementShortName">I2C_Nack</obj_property>
<obj_property name="ObjectShortName">I2C_Nack</obj_property>
</wvobject>
<wvobject fp_name="/Top_Tester/uut/I2C/PHY/FIFO/count" type="array" db_ref_id="1">
<obj_property name="ElementShortName">count[8:0]</obj_property>
<obj_property name="ObjectShortName">count[8:0]</obj_property>
<obj_property name="Radix">UNSIGNEDDECRADIX</obj_property>
</wvobject>
</wvobject>
</wave_config>
@@ -0,0 +1,76 @@
`timescale 1ns / 1ps
/*
* File : Switch_Filter.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 18-Jun-2012 GEA Initial design.
*
* Standards/Formatting:
* Verilog 2001, 4 soft tab, wide column.
*
* Description:
* A debouncer for 8 switches.
*/
module Switch_Filter(
input clock,
input reset,
input [7:0] switch_in,
output reg [7:0] switch_out
);
reg [5:0] c7, c6, c5, c4, c3, c2, c1, c0;
always @(posedge clock) begin
c0 <= (reset) ? 6'h20 : ((switch_in[0] & (c0 != 6'h3F)) ? c0 + 1 : ((~switch_in[0] & (c0 != 6'h00)) ? c0 - 1 : c0));
c1 <= (reset) ? 6'h20 : ((switch_in[1] & (c1 != 6'h3F)) ? c1 + 1 : ((~switch_in[1] & (c1 != 6'h00)) ? c1 - 1 : c1));
c2 <= (reset) ? 6'h20 : ((switch_in[2] & (c2 != 6'h3F)) ? c2 + 1 : ((~switch_in[2] & (c2 != 6'h00)) ? c2 - 1 : c2));
c3 <= (reset) ? 6'h20 : ((switch_in[3] & (c3 != 6'h3F)) ? c3 + 1 : ((~switch_in[3] & (c3 != 6'h00)) ? c3 - 1 : c3));
c4 <= (reset) ? 6'h20 : ((switch_in[4] & (c4 != 6'h3F)) ? c4 + 1 : ((~switch_in[4] & (c4 != 6'h00)) ? c4 - 1 : c4));
c5 <= (reset) ? 6'h20 : ((switch_in[5] & (c5 != 6'h3F)) ? c5 + 1 : ((~switch_in[5] & (c5 != 6'h00)) ? c5 - 1 : c5));
c6 <= (reset) ? 6'h20 : ((switch_in[6] & (c6 != 6'h3F)) ? c6 + 1 : ((~switch_in[6] & (c6 != 6'h00)) ? c6 - 1 : c6));
c7 <= (reset) ? 6'h20 : ((switch_in[7] & (c7 != 6'h3F)) ? c7 + 1 : ((~switch_in[7] & (c7 != 6'h00)) ? c7 - 1 : c7));
end
always @(posedge clock) begin
switch_out[0] <= (reset) ? 0 : ((c0 == 6'h00) ? 0 : ((c0 == 6'h3F) ? 1 : switch_out[0]));
switch_out[1] <= (reset) ? 0 : ((c1 == 6'h00) ? 0 : ((c1 == 6'h3F) ? 1 : switch_out[1]));
switch_out[2] <= (reset) ? 0 : ((c2 == 6'h00) ? 0 : ((c2 == 6'h3F) ? 1 : switch_out[2]));
switch_out[3] <= (reset) ? 0 : ((c3 == 6'h00) ? 0 : ((c3 == 6'h3F) ? 1 : switch_out[3]));
switch_out[4] <= (reset) ? 0 : ((c4 == 6'h00) ? 0 : ((c4 == 6'h3F) ? 1 : switch_out[4]));
switch_out[5] <= (reset) ? 0 : ((c5 == 6'h00) ? 0 : ((c5 == 6'h3F) ? 1 : switch_out[5]));
switch_out[6] <= (reset) ? 0 : ((c6 == 6'h00) ? 0 : ((c6 == 6'h3F) ? 1 : switch_out[6]));
switch_out[7] <= (reset) ? 0 : ((c7 == 6'h00) ? 0 : ((c7 == 6'h3F) ? 1 : switch_out[7]));
end
/*
reg [19:0] c7, c6, c5, c4, c3, c2, c1, c0;
always @(posedge clock) begin
c0 <= (reset) ? 20'h80000 : ((switch_in[0] & (c0 != 20'hFFFFF)) ? c0 + 1 : ((~switch_in[0] & (c0 != 20'h00000)) ? c0 - 1 : c0));
c1 <= (reset) ? 20'h80000 : ((switch_in[1] & (c1 != 20'hFFFFF)) ? c1 + 1 : ((~switch_in[1] & (c1 != 20'h00000)) ? c1 - 1 : c1));
c2 <= (reset) ? 20'h80000 : ((switch_in[2] & (c2 != 20'hFFFFF)) ? c2 + 1 : ((~switch_in[2] & (c2 != 20'h00000)) ? c2 - 1 : c2));
c3 <= (reset) ? 20'h80000 : ((switch_in[3] & (c3 != 20'hFFFFF)) ? c3 + 1 : ((~switch_in[3] & (c3 != 20'h00000)) ? c3 - 1 : c3));
c4 <= (reset) ? 20'h80000 : ((switch_in[4] & (c4 != 20'hFFFFF)) ? c4 + 1 : ((~switch_in[4] & (c4 != 20'h00000)) ? c4 - 1 : c4));
c5 <= (reset) ? 20'h80000 : ((switch_in[5] & (c5 != 20'hFFFFF)) ? c5 + 1 : ((~switch_in[5] & (c5 != 20'h00000)) ? c5 - 1 : c5));
c6 <= (reset) ? 20'h80000 : ((switch_in[6] & (c6 != 20'hFFFFF)) ? c6 + 1 : ((~switch_in[6] & (c6 != 20'h00000)) ? c6 - 1 : c6));
c7 <= (reset) ? 20'h80000 : ((switch_in[7] & (c7 != 20'hFFFFF)) ? c7 + 1 : ((~switch_in[7] & (c7 != 20'h00000)) ? c7 - 1 : c7));
end
always @(posedge clock) begin
switch_out[0] <= (reset) ? 0 : ((c0 == 20'h00000) ? 0 : ((c0 == 20'hFFFFF) ? 1 : switch_out[0]));
switch_out[1] <= (reset) ? 0 : ((c1 == 20'h00000) ? 0 : ((c1 == 20'hFFFFF) ? 1 : switch_out[1]));
switch_out[2] <= (reset) ? 0 : ((c2 == 20'h00000) ? 0 : ((c2 == 20'hFFFFF) ? 1 : switch_out[2]));
switch_out[3] <= (reset) ? 0 : ((c3 == 20'h00000) ? 0 : ((c3 == 20'hFFFFF) ? 1 : switch_out[3]));
switch_out[4] <= (reset) ? 0 : ((c4 == 20'h00000) ? 0 : ((c4 == 20'hFFFFF) ? 1 : switch_out[4]));
switch_out[5] <= (reset) ? 0 : ((c5 == 20'h00000) ? 0 : ((c5 == 20'hFFFFF) ? 1 : switch_out[5]));
switch_out[6] <= (reset) ? 0 : ((c6 == 20'h00000) ? 0 : ((c6 == 20'hFFFFF) ? 1 : switch_out[6]));
switch_out[7] <= (reset) ? 0 : ((c7 == 20'h00000) ? 0 : ((c7 == 20'hFFFFF) ? 1 : switch_out[7]));
end
*/
endmodule
@@ -0,0 +1,41 @@
`timescale 1ns / 1ps
/*
* File : Switches.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 17-Jul-2012 GEA Initial design.
*
* Standards/Formatting:
* Verilog 2001, 4 soft tab, wide column.
*
* Description:
* A read interface between a 4-way handshaking data bus and
* 8 physical switches, which are debounced.
*/
module Switches(
input clock,
input reset,
input Read,
input Write,
input [7:0] Switch_in, // Direct from physical switches
output reg Ack,
output [7:0] Switch_out
);
always @(posedge clock) begin
Ack <= (reset) ? 0 : (Read | Write);
end
// Low-level switch debounce filter
Switch_Filter Switch_Filter (
.clock (clock),
.reset (reset),
.switch_in (Switch_in),
.switch_out (Switch_out)
);
endmodule
@@ -0,0 +1,53 @@
# 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
NET "UART_Rx" LOC = AG15 | IOSTANDARD = LVCMOS33;
NET "UART_Tx" LOC = AG20 | IOSTANDARD = LVCMOS33;
# 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
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
@@ -0,0 +1,307 @@
`timescale 1ns / 1ps
/*
* File : Top.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 8-Jul-2011 GEA Initial design.
*
* Standards/Formatting:
* Verilog 2001, 4 soft tab, wide column.
*
* Description:
* The top-level file for the FPGA. Also known as the 'motherboard,' this
* 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,
// I/O
input [7:0] Switch,
output [14:0] LED,
output [6:0] LCD,
input UART_Rx,
output UART_Tx,
inout i2c_scl,
inout i2c_sda,
output Piezo
);
// Clock signals
wire clock, clock2x;
wire PLL_Locked;
reg reset;
always @(posedge clock) begin
reset <= ~reset_n | ~PLL_Locked;
end
// MIPS Processor Signals
reg [31:0] MIPS32_DataMem_In;
wire [31:0] MIPS32_DataMem_Out, MIPS32_InstMem_In;
wire [29:0] MIPS32_DataMem_Address, MIPS32_InstMem_Address;
wire [3:0] MIPS32_DataMem_WE;
wire MIPS32_DataMem_Read, MIPS32_InstMem_Read;
reg MIPS32_DataMem_Ready;
wire [4:0] MIPS32_Interrupts;
wire MIPS32_NMI;
wire [7:0] MIPS32_IP;
wire MIPS32_IO_WE;
// BRAM Memory Signals
reg [3:0] BRAM_WEA;
reg BRAM_REA;
reg [17:0] BRAM_AddrA;
reg [31:0] BRAM_DINA;
wire BRAM_ReadyA;
wire BRAM_REB;
wire [3:0] BRAM_WEB;
wire [31:0] BRAM_DOUTB;
wire BRAM_ReadyB;
// LCD Signals
wire [3:0] LCD_WE;
wire LCD_Ready;
// UART Bootloader Signals
wire UART_RE;
wire UART_WE;
wire [16:0] UART_DOUT;
wire UART_Ack;
wire UART_Interrupt;
wire UART_BootResetCPU;
wire [17:0] UART_BootAddress;
wire [31:0] UART_BootData;
wire UART_BootWriteMem_pre;
wire [3:0] UART_BootWriteMem = (UART_BootWriteMem_pre) ? 4'hF : 4'h0;
// I2C Signals
wire I2C_Ready;
wire [10:0] I2C_DOUT;
wire I2C_RE, I2C_WE;
// Piezo Transducer Signals
wire Piezo_WE;
wire Piezo_Ready;
// LED Signals
wire LED_WE;
wire LED_RE;
wire [13:0] LED_DOUT;
wire LED_Ready;
wire [13:0] LED_Sw_LEDs;
// Filtered Switch Input Signals
wire Switches_RE;
wire Switches_WE;
wire Switches_Ready;
wire [7:0] Switches_DOUT;
// Clock Generation
PLL_100MHz_to_33MHz_66MHz Clock_Generator (
.CLKIN1_IN (clock_100MHz),
.RST_IN (1'b0),
.CLKOUT0_OUT (clock),
.CLKOUT1_OUT (clock2x),
.LOCKED_OUT (PLL_Locked)
);
// 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),
.IP (MIPS32_IP)
);
// On-Chip Block RAM
BRAM_592KB_Wrapper Memory (
.clock (clock2x),
.reset (reset),
.rea (BRAM_REA),
.wea (BRAM_WEA),
.addra (BRAM_AddrA),
.dina (BRAM_DINA),
.douta (MIPS32_InstMem_In),
.dreadya (BRAM_ReadyA),
.reb (BRAM_REB),
.web (BRAM_WEB),
.addrb (MIPS32_DataMem_Address[17:0]),
.dinb (MIPS32_DataMem_Out),
.doutb (BRAM_DOUTB),
.dreadyb (BRAM_ReadyB)
);
// 16x2 LCD Display Screen
LCD LCD_Screen (
.clock_100MHz (clock2x),
.clock_Mem (clock2x),
.reset (reset),
.address (MIPS32_DataMem_Address[2:0]),
.data (MIPS32_DataMem_Out),
.writeEnable (LCD_WE),
.ack (LCD_Ready),
.LCD (LCD)
);
// UART + Boot Loader (v2)
uart_bootloader UART (
.clock (clock2x),
.reset (reset),
.Read (UART_RE),
.Write (UART_WE),
.DataIn (MIPS32_DataMem_Out[8:0]),
.DataOut (UART_DOUT),
.Ack (UART_Ack),
.DataReady (UART_Interrupt),
.BootResetCPU (UART_BootResetCPU),
.BootWriteMem (UART_BootWriteMem_pre),
.BootAddr (UART_BootAddress),
.BootData (UART_BootData),
.RxD (UART_Rx),
.TxD (UART_Tx)
);
// I2C Module
I2C_Controller I2C (
.clock (clock2x),
.reset (reset),
.Read (I2C_RE),
.Write (I2C_WE),
.DataIn (MIPS32_DataMem_Out[12:0]),
.DataOut (I2C_DOUT),
.Ack (I2C_Ready),
.i2c_scl (i2c_scl),
.i2c_sda (i2c_sda)
);
// Piezo-electric Transducer
Piezo_Driver Piezo_Driver (
.clock (clock2x),
.reset (reset),
.data (MIPS32_DataMem_Out[24:0]),
.Write (Piezo_WE),
.Ack (Piezo_Ready),
.Piezo (Piezo)
);
// LEDs
LED LEDs (
.clock (clock2x),
.reset (reset),
.dataIn (MIPS32_DataMem_Out[14:0]),
.IP (MIPS32_IP),
.Write (LED_WE),
.Read (LED_RE),
.dataOut (LED_DOUT),
.Ack (LED_Ready),
.LED (LED_Sw_LEDs)
);
// Filtered Input Switches
Switches Switches (
.clock (clock2x),
.reset (reset),
.Read (Switches_RE),
.Write (Switches_WE),
.Switch_in (Switch),
.Ack (Switches_Ready),
.Switch_out (Switches_DOUT)
);
assign MIPS32_IO_WE = (MIPS32_DataMem_WE == 4'hF) ? 1 : 0;
assign MIPS32_Interrupts[4:1] = Switches_DOUT[7:4];
assign MIPS32_Interrupts[0] = UART_Interrupt;
assign MIPS32_NMI = Switches_DOUT[3];
assign LED = {UART_BootResetCPU, LED_Sw_LEDs[13:0]};
// Allow writes to Instruction Memory Port when bootloading
always @(*) begin
BRAM_REA <= (UART_BootResetCPU) ? 0 : MIPS32_InstMem_Read;
BRAM_WEA <= (UART_BootResetCPU) ? UART_BootWriteMem : 4'h0;
BRAM_AddrA <= (UART_BootResetCPU) ? UART_BootAddress : MIPS32_InstMem_Address;
BRAM_DINA <= (UART_BootResetCPU) ? UART_BootData : 32'h0000_0000;
end
always @(*) begin
case (MIPS32_DataMem_Address[29])
0 : begin
MIPS32_DataMem_In <= BRAM_DOUTB;
MIPS32_DataMem_Ready <= BRAM_ReadyB;
end
1 : begin
// Memory-mapped I/O
case (MIPS32_DataMem_Address[28:26])
// LCD
3'b000 : begin
MIPS32_DataMem_In <= 32'h0000_0000;
MIPS32_DataMem_Ready <= LCD_Ready;
end
// I2C
3'b001 : begin
MIPS32_DataMem_In <= {21'h000000, I2C_DOUT[10:0]};
MIPS32_DataMem_Ready <= I2C_Ready;
end
// Piezo
3'b010 : begin
MIPS32_DataMem_In <= 32'h0000_0000;
MIPS32_DataMem_Ready <= Piezo_Ready;
end
// UART
3'b011 : begin
MIPS32_DataMem_In <= {15'h0000, UART_DOUT[16:0]};
MIPS32_DataMem_Ready <= UART_Ack;
end
// LED
3'b100 : begin
MIPS32_DataMem_In <= {18'h00000, LED_DOUT[13:0]};
MIPS32_DataMem_Ready <= LED_Ready;
end
// Switches
3'b101 : begin
MIPS32_DataMem_In <= {24'h000000, Switches_DOUT[7:0]};
MIPS32_DataMem_Ready <= Switches_Ready;
end
default: begin
MIPS32_DataMem_In <= 32'h0000_0000;
MIPS32_DataMem_Ready <= 0;
end
endcase
end
endcase
end
// Memory
assign BRAM_REB = (MIPS32_DataMem_Address[29]) ? 0 : MIPS32_DataMem_Read;
assign BRAM_WEB = (MIPS32_DataMem_Address[29]) ? 4'h0 : MIPS32_DataMem_WE;
// I/O
assign LCD_WE = (MIPS32_DataMem_Address[29:26] == 4'b1000) ? MIPS32_DataMem_WE : 4'h0;
assign Piezo_WE = (MIPS32_DataMem_Address[29:26] == 4'b1010) ? MIPS32_IO_WE : 0;
assign I2C_WE = (MIPS32_DataMem_Address[29:26] == 4'b1001) ? MIPS32_IO_WE : 0;
assign I2C_RE = (MIPS32_DataMem_Address[29:26] == 4'b1001) ? MIPS32_DataMem_Read : 0;
assign UART_WE = (MIPS32_DataMem_Address[29:26] == 4'b1011) ? MIPS32_IO_WE : 0;
assign UART_RE = (MIPS32_DataMem_Address[29:26] == 4'b1011) ? MIPS32_DataMem_Read : 0;
assign LED_WE = (MIPS32_DataMem_Address[29:26] == 4'b1100) ? MIPS32_IO_WE : 0;
assign LED_RE = (MIPS32_DataMem_Address[29:26] == 4'b1100) ? MIPS32_DataMem_Read : 0;
assign Switches_WE = (MIPS32_DataMem_Address[29:26] == 4'b1101) ? MIPS32_IO_WE : 0;
assign Switches_RE = (MIPS32_DataMem_Address[29:26] == 4'b1101) ? MIPS32_DataMem_Read : 0;
endmodule
@@ -0,0 +1,129 @@
`timescale 1ns / 1ps
/*
* File : uart-min.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:
* 115200 baud 8-N-1 serial port, using only Tx and Rx.
* (8 data bits, no parity, 1 stop bit, no flow control.)
* Configurable baud rate determined by clocking module, 16x oversampling
* for Rx data, Rx filtering, and configurable FIFO buffers for receiving
* and transmitting.
*
* Described as '_min' due to lack of overflow and other status signals
* as well as the use of only Tx and Rx signals.
*/
module uart_min(
input clock,
input reset,
input write,
input [7:0] data_in, // tx going into uart, out of serial port
input read,
output [7:0] data_out, // rx coming in from serial port, out of uart
output data_ready,
output [8:0] rx_count,
/*------------------------*/
input RxD,
output TxD
);
localparam DATA_WIDTH = 8; // Bit-width of FIFO data (should be 8)
localparam ADDR_WIDTH = 8; // 2^ADDR_WIDTH words of FIFO space
/* Clocking Signals */
wire uart_tick, uart_tick_16x;
/* Receive Signals */
wire [7:0] rx_data; // Raw bytes coming in from uart
wire rx_data_ready; // Synchronous pulse indicating this (^)
wire rx_fifo_empty;
/* Send Signals */
reg tx_fifo_deQ = 0;
reg tx_start = 0;
wire tx_free;
wire tx_fifo_empty;
wire [7:0] tx_fifo_data_out;
assign data_ready = ~rx_fifo_empty;
always @(posedge clock) begin
if (reset) begin
tx_fifo_deQ <= 0;
tx_start <= 0;
end
else begin
if (~tx_fifo_empty & tx_free & uart_tick) begin
tx_fifo_deQ <= 1;
tx_start <= 1;
end
else begin
tx_fifo_deQ <= 0;
tx_start <= 0;
end
end
end
uart_clock clocks (
.clock (clock),
.uart_tick (uart_tick),
.uart_tick_16x (uart_tick_16x)
);
uart_tx tx (
.clock (clock),
.reset (reset),
.uart_tick (uart_tick),
.TxD_data (tx_fifo_data_out),
.TxD_start (tx_start),
.ready (tx_free),
.TxD (TxD)
);
uart_rx rx (
.clock (clock),
.reset (reset),
.RxD (RxD),
.uart_tick_16x (uart_tick_16x),
.RxD_data (rx_data),
.data_ready (rx_data_ready)
);
FIFO_NoFull_Count #(
.DATA_WIDTH (DATA_WIDTH),
.ADDR_WIDTH (ADDR_WIDTH))
tx_buffer (
.clock (clock),
.reset (reset),
.enQ (write),
.deQ (tx_fifo_deQ),
.data_in (data_in),
.data_out (tx_fifo_data_out),
.empty (tx_fifo_empty),
.count ()
);
FIFO_NoFull_Count #(
.DATA_WIDTH (DATA_WIDTH),
.ADDR_WIDTH (ADDR_WIDTH))
rx_buffer (
.clock (clock),
.reset (reset),
.enQ (rx_data_ready),
.deQ (read),
.data_in (rx_data),
.data_out (data_out),
.empty (rx_fifo_empty),
.count (rx_count)
);
endmodule
@@ -0,0 +1,183 @@
`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company:
// Engineer: Grant Ayers (ayers@cs.utah.edu)
//
// Create Date: 09:59:05 05/24/2010
// Design Name:
// Module Name: uart_bootloader
// Project Name:
// Target Devices:
// Tool versions:
// Description:
// Implements the XUM bootloader protocol over a serial port (115200 8N1).
// The protocol is as follows:
//
// 1. Programmer sends 'XUM' ascii bytes
// 2. Programmer sends a number indicating how many 32-bit data words it
// has to send, minus 1. (For example, if it has one 32-bit data word,
// this number will be 0.) The size of this number is 18 bits.
// This means the minimum transmission size is 1 word (32 bits), and
// the maximum transmission size is 262144 words (exactly 1MB).
// This 18-bit number is sent in three bytes, and the six most
// significant bits of the first byte must be 0.
// 3. The FPGA sends back the third size byte from the programmer, allowing
// the programmer to determine if the FPGA is listening and conforming
// to the XUM boot protocol.
// 4. The programmer sends another 18-bit number indicating the starting
// offset in memory where the data should be placed. Normally this will
// be 0. This number is also sent in three bytes, and the six most
// significant bits of the first byte are ignored.
// 5. The programmer sends the data. A copy of each byte that it sends will
// be sent back to the programmer from the FPGA, allowing the programmer
// to determine if all of the data was transmitted successfully.
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//////////////////////////////////////////////////////////////////////////////////
module uart_bootloader(
input clock, // 100Mhz
input reset, // System-wide global reset
input RxD, // UART data from computer
output TxD, // UART data to computer
output resetCPU, // Reset CPUs' PCs to start execution at 0x0
output reg writeMem = 0, // Write command to instruction memory
output reg [17:0] addrMem = 0, // address to instruction memory
output reg [31:0] dataMem = 0 // 32-bit data words of instruction memory
);
localparam [3:0] HEAD_1=0, HEAD_2=1, HEAD_3=2, SIZE_1=3, SIZE_2=4, SIZE_3=5, OFST_1=6, OFST_2=7,
OFST_3=8, ADDRSET=9, DATA_1=10, DATA_2=11, DATA_3=12, DATA_4=13, ADDRINC=14;
/* UART Signals */
reg uart_write = 0;
reg uart_read = 0;
wire [7:0] uart_rx_data;
wire [7:0] uart_tx_data = uart_rx_data;
wire uart_rx_data_ready;
reg [17:0] size = 0; // Number of 32-bit words to expect
reg [17:0] offset = 0; // Starting address to store words
reg [17:0] rx_count = 0; // Number of 32-bit words received so far
reg [3:0] state = HEAD_1;
// The CPU(s) is continuously reset while memory is being replaced.
assign resetCPU = ((state!=HEAD_1) && (state!=HEAD_2) && (state!=HEAD_3) && (state!=SIZE_1));
always @(posedge clock) begin
if (reset) begin
state <= HEAD_1;
uart_read <= 0;
uart_write <= 0;
writeMem <= 0;
rx_count <= 0;
end
else begin
uart_read <= uart_rx_data_ready & ((state!=ADDRSET) && (state!=ADDRINC));
uart_write <= uart_rx_data_ready & ((state==SIZE_3) || (state==DATA_1) || (state==DATA_2) || (state==DATA_3) || (state==DATA_4));
writeMem <= uart_rx_data_ready & (state == DATA_4);
rx_count <= (state == HEAD_1) ? 0 : ((state == ADDRINC) ? rx_count + 1 : rx_count);
case (state)
HEAD_1: begin
if (uart_rx_data_ready) begin
state <= (uart_rx_data == 8'h58) ? HEAD_2 : HEAD_1; // 'X'
end
else begin
state <= HEAD_1;
end
end
HEAD_2: begin
if (uart_rx_data_ready) begin
state <= (uart_rx_data == 8'h55) ? HEAD_3 : HEAD_1; // 'U'
end
else begin
state <= HEAD_2;
end
end
HEAD_3: begin
if (uart_rx_data_ready) begin
state <= (uart_rx_data == 8'h4D) ? SIZE_1 : HEAD_1; // 'M'
end
else begin
state <= HEAD_3;
end
end
SIZE_1: begin
if (uart_rx_data_ready) begin
state <= (uart_rx_data[7:2] == 6'b000000) ? SIZE_2 : HEAD_1; // 6 leading 0s
size[17:16] <= uart_rx_data[1:0];
end
else begin
state <= SIZE_1;
end
end
SIZE_2: begin
state <= (uart_rx_data_ready) ? SIZE_3 : SIZE_2;
size[15:8] <= (uart_rx_data_ready) ? uart_rx_data : size[15:8];
end
SIZE_3: begin
state <= (uart_rx_data_ready) ? OFST_1 : SIZE_3;
size[7:0] <= (uart_rx_data_ready) ? uart_rx_data : size[7:0];
end
OFST_1: begin
state <= (uart_rx_data_ready) ? OFST_2 : OFST_1;
offset[17:16] <= (uart_rx_data_ready) ? uart_rx_data[1:0] : offset[17:16];
end
OFST_2: begin
state <= (uart_rx_data_ready) ? OFST_3 : OFST_2;
offset[15:8] <= (uart_rx_data_ready) ? uart_rx_data : offset[15:8];
end
OFST_3: begin
state <= (uart_rx_data_ready) ? ADDRSET : OFST_3;
offset[7:0] <= (uart_rx_data_ready) ? uart_rx_data : offset[7:0];
end
ADDRSET: begin
state <= DATA_1;
addrMem <= offset;
end
DATA_1: begin
state <= (uart_rx_data_ready) ? DATA_2 : DATA_1;
dataMem[31:24] <= (uart_rx_data_ready) ? uart_rx_data : dataMem[31:24];
end
DATA_2: begin
state <= (uart_rx_data_ready) ? DATA_3 : DATA_2;
dataMem[23:16] <= (uart_rx_data_ready) ? uart_rx_data : dataMem[23:16];
end
DATA_3: begin
state <= (uart_rx_data_ready) ? DATA_4 : DATA_3;
dataMem[15:8] <= (uart_rx_data_ready) ? uart_rx_data : dataMem[15:8];
end
DATA_4: begin
state <= (uart_rx_data_ready) ? ADDRINC : DATA_4;
dataMem[7:0] <= (uart_rx_data_ready) ? uart_rx_data : dataMem[7:0];
end
ADDRINC: begin
addrMem <= addrMem + 1;
state <= (rx_count == size) ? HEAD_1 : DATA_1;
end
default: state <= HEAD_1;
endcase
end
end
uart_min uart (
.clock (clock),
.reset (reset),
.write (uart_write),
.data_in (uart_tx_data),
.read (uart_read),
.data_out (uart_rx_data),
.data_ready (uart_rx_data_ready),
.RxD (RxD),
.TxD (TxD)
);
endmodule
@@ -0,0 +1,221 @@
`timescale 1ns / 1ps
/*
* File : uart_bootloader_v2.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 of standalone bootloader
* 2.0 7-Jul-2012 GEA Added data memory bus to allow for general-purpose use.
*
* Standards/Formatting:
* Verilog 2001, 4 soft tab, wide column.
*
* Description:
* An RS-232 compatible UART coupled with the XUM bootloader.
*
* The UART is general-purpose and capable of sending and receiving at a
* pre-determined BAUD rate (determined by the clocking module)
* with 8 data bits, 1 stop bit, and no parity. In other words it
* is 8N1 with only RxD and TxD signals. It uses two 256-byte FIFO
* buffers, one for receiving and the other for transmitting.
*
* The XUM bootloader protocol is as follows:
*
* 1. Programmer sends 'XUM' ASCII bytes.
* 2. Programmer sends a number indicating how many 32-bit data words
* it has to send, minus 1. (For example, if it has one 32-bit data word,
* this number would be 0.) The size of this number is 18 bits.
* This means the minimum transmission size is 1 word (32 bits), and
* the maximum transmission size is 262144 words, or exactly 1 MB.
* This 18-bit number is sent MSB first, in three bytes, with the six
* most-significant bits set to 0.
* 3. The FPGA sends back the third size byte from the programmer, allowing
* the programmer to determine if the FPGA is listening and conforming
* to the XUM boot protocol.
* 4. The programmer sends another 18-bit number indicating the starting
* offset in memory where the data should be placed. Normally this will
* be 0. This number is also sent in three bytes, and the six most-significant
* bits of the first byte are ignored.
* 5. The programmer sends the data. A copy of each byte that it sends will be
* sent back to the programmer from the FPGA, allowing the programmer
* to determine if all of the data was transmitted successfully.
*
* On reset, the bootloader is enabled by default. When the bootloader is enabled,
* the data memory bus will not see any incoming data. To configure the UART for
* general-purpose use, software must issue a write command to the UART
* over the data memory bus with bit 8 set. This disables the boot protocol until
* the UART is reset again and allows normal use. Note however that there is
* a 5-second guard time after reset during which the boot loader is
* enabled regardless of any software commands to disable it. After the 5 second
* time has lapsed after reset, the software state determines the operating mode
* of the UART.
*/
module uart_bootloader(
input clock,
input reset,
input Read, // MMIO
input Write, // MMIO
input [8:0] DataIn, // MMIO
output reg [16:0] DataOut, // MMIO
output Ack, // MMIO
output DataReady, // Can be used as an interrupt
output BootResetCPU, // XUM Boot Protocol: Reset CPU
output BootWriteMem, // XUM Boot Protocol: Write to CPU memory
output reg [17:0] BootAddr, // XUM Boot Protocol
output reg [31:0] BootData, // XUM Boot Protocol
input RxD, // UART Rx Signal
output TxD // UART Tx Signal
);
localparam [4:0] IDLE=0, WRITE=1, READ=2, BUSW=3, XHEAD1=4, XHEAD2=5, XHEAD3=6, XSIZE1=7, XSIZE2=8, XSIZE3=9,
XOFST1=10, XOFST2=11, XOFST3=12, XDATA1=13, XDATA2=14, XDATA3=15, XDATA4=16, XADDRI=17;
// UART module signals
wire uart_write;
reg uart_read;
wire uart_data_ready;
wire [7:0] uart_data_in;
wire [7:0] uart_data_out;
wire [8:0] uart_rx_count;
reg [8:0] DataIn_r; // Latch for incoming data to improve timing
wire DisableBoot = DataIn_r[8]; // Software boot disable command is bit 8
reg [28:0] BootTimedEnable; // Hardware override enabler for boot loader after reset
reg BootSwEnabled; // Software enabled/disabled state of bootloader
wire BootProtoEnabled; // Master bootloader enabled signal
reg [17:0] rx_count; // Number of 32-bit words received (boot loader)
reg [17:0] rx_size; // Number of 32-bit words to expect (boot loader)
reg [4:0] state;
always @(posedge clock) begin
if (reset) begin
state <= IDLE;
end
else begin
case (state)
IDLE: begin
if (Write) state <= WRITE;
else if (Read) state <= READ;
else if (BootProtoEnabled & uart_data_ready) state <= XHEAD1;
else state <= IDLE;
end
WRITE: state <= BUSW;
READ: state <= BUSW;
BUSW: state <= ~(Read | Write) ? IDLE : BUSW;
XHEAD1: state <= (uart_data_out == 8'h58) ? XHEAD2 : IDLE; // 'X'
XHEAD2: state <= (uart_data_ready) ? ((uart_data_out == 8'h55) ? XHEAD3 : IDLE) : XHEAD2; // 'U'
XHEAD3: state <= (uart_data_ready) ? ((uart_data_out == 8'h4D) ? XSIZE1 : IDLE) : XHEAD3; // 'M'
XSIZE1: state <= (uart_data_ready) ? ((uart_data_out[7:2] == 6'b000000) ? XSIZE2 : IDLE) : XSIZE1;
XSIZE2: state <= (uart_data_ready) ? XSIZE3 : XSIZE2;
XSIZE3: state <= (uart_data_ready) ? XOFST1 : XSIZE3;
XOFST1: state <= (uart_data_ready) ? XOFST2 : XOFST1;
XOFST2: state <= (uart_data_ready) ? XOFST3 : XOFST2;
XOFST3: state <= (uart_data_ready) ? XDATA1 : XOFST3;
XDATA1: state <= (uart_data_ready) ? XDATA2 : XDATA1;
XDATA2: state <= (uart_data_ready) ? XDATA3 : XDATA2;
XDATA3: state <= (uart_data_ready) ? XDATA4 : XDATA3;
XDATA4: state <= (uart_data_ready) ? XADDRI : XDATA4;
XADDRI: state <= (rx_count == rx_size) ? IDLE : XDATA1;
default: state <= IDLE;
endcase
end
end
always @(*) begin
case (state)
IDLE: uart_read <= 0;
WRITE: uart_read <= 0;
READ: uart_read <= 1;
BUSW: uart_read <= 0;
XHEAD1: uart_read <= uart_data_ready;
XHEAD2: uart_read <= uart_data_ready;
XHEAD3: uart_read <= uart_data_ready;
XSIZE1: uart_read <= uart_data_ready;
XSIZE2: uart_read <= uart_data_ready;
XSIZE3: uart_read <= uart_data_ready;
XOFST1: uart_read <= uart_data_ready;
XOFST2: uart_read <= uart_data_ready;
XOFST3: uart_read <= uart_data_ready;
XDATA1: uart_read <= uart_data_ready;
XDATA2: uart_read <= uart_data_ready;
XDATA3: uart_read <= uart_data_ready;
XDATA4: uart_read <= uart_data_ready;
XADDRI: uart_read <= 0;
default: uart_read <= 0;
endcase
end
always @(posedge clock) begin
DataIn_r <= ((state == IDLE) & Write) ? DataIn : DataIn_r;
end
always @(posedge clock) begin
DataOut <= (reset) ? 17'h00000 : ((state == READ) ? {uart_rx_count[8:0], uart_data_out[7:0]} : DataOut);
end
always @(posedge clock) begin
BootTimedEnable <= (reset) ? 29'h00000000 : (BootTimedEnable != 29'h1dcd6500) ? BootTimedEnable + 1 : BootTimedEnable; // 5 sec @ 100 MHz
BootSwEnabled <= (reset) ? 1 : ((state == WRITE) ? ~DisableBoot : BootSwEnabled);
end
assign BootResetCPU = (state != IDLE) && (state != WRITE) && (state != READ) && (state != BUSW) &&
(state != XHEAD1) && (state != XHEAD2) && (state != XHEAD3) && (state != XSIZE1);
assign BootWriteMem = (state == XADDRI);
assign uart_write = ((state == WRITE) & ~DisableBoot) |
(uart_data_ready & ((state == XSIZE3) | (state == XDATA1) | (state == XDATA2) | (state == XDATA3) | (state == XDATA4)));
assign uart_data_in = (state == WRITE) ? DataIn_r[7:0] : uart_data_out;
assign Ack = (state == BUSW);
assign DataReady = uart_data_ready;
assign BootProtoEnabled = BootSwEnabled | (BootTimedEnable != 29'h1dcd6500);
// XUM Boot Protocol Logic
always @(posedge clock) begin
BootData[31:24] <= (reset) ? 8'h00 : (((state == XDATA1) & uart_data_ready) ? uart_data_out : BootData[31:24]);
BootData[23:16] <= (reset) ? 8'h00 : (((state == XDATA2) & uart_data_ready) ? uart_data_out : BootData[23:16]);
BootData[15:8] <= (reset) ? 8'h00 : (((state == XDATA3) & uart_data_ready) ? uart_data_out : BootData[15:8]);
BootData[7:0] <= (reset) ? 8'h00 : (((state == XDATA4) & uart_data_ready) ? uart_data_out : BootData[7:0]);
end
always @(posedge clock) begin
if (reset) begin
BootAddr <= 18'h00000;
end
else if (state == XADDRI) begin
BootAddr <= BootAddr + 1;
end
else begin
BootAddr[17:16] <= ((state == XOFST1) & uart_data_ready) ? uart_data_out[1:0] : BootAddr[17:16];
BootAddr[15:8] <= ((state == XOFST2) & uart_data_ready) ? uart_data_out[7:0] : BootAddr[15:8];
BootAddr[7:0] <= ((state == XOFST3) & uart_data_ready) ? uart_data_out[7:0] : BootAddr[7:0];
end
end
always @(posedge clock) begin
rx_count <= (state == IDLE) ? 18'h00000 : ((state == XADDRI) ? rx_count + 1 : rx_count);
end
always @(posedge clock) begin
rx_size[17:16] <= (reset) ? 2'b00 : (((state == XSIZE1) & uart_data_ready) ? uart_data_out[1:0] : rx_size[17:16]);
rx_size[15:8] <= (reset) ? 8'h00 : (((state == XSIZE2) & uart_data_ready) ? uart_data_out[7:0] : rx_size[15:8]);
rx_size[7:0] <= (reset) ? 8'h00 : (((state == XSIZE3) & uart_data_ready) ? uart_data_out[7:0] : rx_size[7:0]);
end
// UART Driver
uart_min UART (
.clock (clock),
.reset (reset),
.write (uart_write),
.data_in (uart_data_in),
.read (uart_read),
.data_out (uart_data_out),
.data_ready (uart_data_ready),
.rx_count (uart_rx_count),
.RxD (RxD),
.TxD (TxD)
);
endmodule
@@ -0,0 +1,56 @@
`timescale 1ns / 1ps
/*
* File : uart_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 24-May-2010 GEA Initial design.
*
* Standards/Formatting:
* Verilog 2001, 4 soft tab, wide column.
*
* Description:
* Takes a 100 MHz clock and generates synchronous pulses for 115200 baud
* and 16x 115200 baud (synchronized).
*
* This timing can be adjusted to allow for other baud rates.
*/
module uart_clock(
input clock,
output uart_tick,
output uart_tick_16x
);
// 100MHz / (2^13 / 151) == 16 * 115203.857 Hz
// 100MHz / (2^17 / 151) == 115203.857 Hz
// 66MHz / (2^14 / 453) == 16 * 115203.857 Hz
// 66MHz / (2^18 / 453) == 115203.857 Hz
// 66 MHz version
reg [14:0] accumulator = 15'h0000;
always @(posedge clock) begin
accumulator <= accumulator[13:0] + 453;
end
assign uart_tick_16x = accumulator[14];
/*
// 100 MHz version
reg [13:0] accumulator = 14'h0000;
always @(posedge clock) begin
accumulator <= accumulator[12:0] + 151;
end
assign uart_tick_16x = accumulator[13];
*/
//------------------------------
reg [3:0] uart_16x_count = 4'h0;
always @(posedge clock) begin
uart_16x_count <= (uart_tick_16x) ? uart_16x_count + 1 : uart_16x_count;
end
assign uart_tick = (uart_tick_16x==1'b1 && (uart_16x_count == 4'b1111));
endmodule
@@ -0,0 +1,96 @@
`timescale 1ns / 1ps
/*
* File : uart_rx.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-2010 GEA Initial design.
*
* Standards/Formatting:
* Verilog 2001, 4 soft tab, wide column.
*
* Description:
* Recovers received data from the serial port with 16x clock over-sampling.
* 'data_ready' is a synchronous pulse indicator. 8N1.
*/
module uart_rx(
input clock,
input reset,
input RxD,
input uart_tick_16x,
output reg [7:0] RxD_data = 0,
output data_ready
);
/* Synchronize incoming RxD */
reg [1:0] RxD_sync = 2'b11; //0;
always @(posedge clock) RxD_sync <= (uart_tick_16x) ? {RxD_sync[0], RxD} : RxD_sync;
/* Filter Input */
reg [1:0] RxD_cnt = 0;
reg RxD_bit = 1; //0;
always @(posedge clock) begin
if (uart_tick_16x) begin
case (RxD_sync[1])
0: RxD_cnt <= (RxD_cnt == 2'b11) ? RxD_cnt : RxD_cnt + 1;
1: RxD_cnt <= (RxD_cnt == 2'b00) ? RxD_cnt : RxD_cnt - 1;
endcase
RxD_bit <= (RxD_cnt == 2'b11) ? 0 : ((RxD_cnt == 2'b00) ? 1 : RxD_bit);
end
else begin
RxD_cnt <= RxD_cnt;
RxD_bit <= RxD_bit;
end
end
/* State Definitions */
localparam [3:0] IDLE=0, BIT_0=1, BIT_1=2, BIT_2=3, BIT_3=4, BIT_4=5, BIT_5=6,
BIT_6=7, BIT_7=8, STOP=9;
reg [3:0] state = IDLE;
/* Next-bit spacing and clock locking */
reg clock_lock = 0;
reg [3:0] bit_spacing = 4'b1110; // Enable quick jumping from IDLE to BIT_0 when line was idle.
always @(posedge clock) begin
if (uart_tick_16x) begin
if (~clock_lock) clock_lock <= ~RxD_bit; // We lock on when we detect a filtered 0 from idle
else clock_lock <= ((state == IDLE) && (RxD_bit == 1'b1)) ? 0 : clock_lock;
bit_spacing <= (clock_lock) ? bit_spacing + 1 : 4'b1110;
end
else begin
clock_lock <= clock_lock;
bit_spacing <= bit_spacing;
end
end
wire next_bit = (bit_spacing == 4'b1111);
/* State Machine */
always @(posedge clock) begin
if (reset) state <= IDLE;
else if (uart_tick_16x) begin
case (state)
IDLE: state <= (next_bit & (RxD_bit == 1'b0)) ? BIT_0 : IDLE; // Start bit is 0
BIT_0: state <= (next_bit) ? BIT_1 : BIT_0;
BIT_1: state <= (next_bit) ? BIT_2 : BIT_1;
BIT_2: state <= (next_bit) ? BIT_3 : BIT_2;
BIT_3: state <= (next_bit) ? BIT_4 : BIT_3;
BIT_4: state <= (next_bit) ? BIT_5 : BIT_4;
BIT_5: state <= (next_bit) ? BIT_6 : BIT_5;
BIT_6: state <= (next_bit) ? BIT_7 : BIT_6;
BIT_7: state <= (next_bit) ? STOP : BIT_7;
STOP: state <= (next_bit) ? IDLE : STOP;
default: state <= 4'bxxxx;
endcase
end
else state <= state;
end
/* Shift Register to Collect Rx bits as they come */
wire capture = (uart_tick_16x & next_bit & (state!=IDLE) & (state!=STOP));
always @(posedge clock) RxD_data <= (capture) ? {RxD_bit, RxD_data[7:1]} : RxD_data[7:0];
assign data_ready = (uart_tick_16x & next_bit & (state==STOP));
endmodule
@@ -0,0 +1,79 @@
`timescale 1ns / 1ps
/*
* File : uart_tx.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 25-Mar-2010 GEA Initial design.
*
* Standards/Formatting:
* Verilog 2001, 4 soft tab, wide column.
*
* Description:
* Transmits bytes of data from the serial port. Capable of back-to-back
* transmission of data for maximum bandwidth utilization.
* 'TxD_start' must only pulse with a 'uart_tick' pulse. 8N1.
*/
module uart_tx (
input clock,
input reset,
input uart_tick,
input [7:0] TxD_data,
input TxD_start, // Must happen with a uart_tick
output ready,
output reg TxD
);
localparam [3:0] IDLE=0, START=1, BIT_0=2, BIT_1=3, BIT_2=4, BIT_3=5,
BIT_4=6, BIT_5=7, BIT_6=8, BIT_7=9, STOP=10;
reg [3:0] tx_state = IDLE;
reg [7:0] TxD_data_r = 8'h00; // Registered input data so it doesn't need to be held
assign ready = (tx_state == IDLE) || (tx_state == STOP);
always @(posedge clock) begin
TxD_data_r <= (ready & TxD_start) ? TxD_data : TxD_data_r;
end
always @(posedge clock) begin
if (reset) tx_state <= IDLE;
else begin
case (tx_state)
IDLE: if (TxD_start) tx_state <= START;
START: if (uart_tick) tx_state <= BIT_0;
BIT_0: if (uart_tick) tx_state <= BIT_1;
BIT_1: if (uart_tick) tx_state <= BIT_2;
BIT_2: if (uart_tick) tx_state <= BIT_3;
BIT_3: if (uart_tick) tx_state <= BIT_4;
BIT_4: if (uart_tick) tx_state <= BIT_5;
BIT_5: if (uart_tick) tx_state <= BIT_6;
BIT_6: if (uart_tick) tx_state <= BIT_7;
BIT_7: if (uart_tick) tx_state <= STOP;
STOP: if (uart_tick) tx_state <= (TxD_start) ? START : IDLE;
default: tx_state <= 4'bxxxx;
endcase
end
end
always @(tx_state, TxD_data_r) begin
case (tx_state)
IDLE: TxD <= 1;
START: TxD <= 0;
BIT_0: TxD <= TxD_data_r[0];
BIT_1: TxD <= TxD_data_r[1];
BIT_2: TxD <= TxD_data_r[2];
BIT_3: TxD <= TxD_data_r[3];
BIT_4: TxD <= TxD_data_r[4];
BIT_5: TxD <= TxD_data_r[5];
BIT_6: TxD <= TxD_data_r[6];
BIT_7: TxD <= TxD_data_r[7];
STOP: TxD <= 1;
default: TxD <= 1'bx;
endcase
end
endmodule