Line 1... |
Line 1... |
/* $Id: aeMB2_idmx.v,v 1.4 2007-12-13 21:25:41 sybreon Exp $
|
/* $Id: aeMB2_idmx.v,v 1.5 2007-12-16 03:25:02 sybreon Exp $
|
**
|
**
|
** AEMB2 INSTRUCTION DECODE MUX
|
** AEMB2 INSTRUCTION DECODE MUX
|
**
|
**
|
** Copyright (C) 2004-2007 Shawn Tan Ser Ngiap <shawn.tan@aeste.net>
|
** Copyright (C) 2004-2007 Shawn Tan Ser Ngiap <shawn.tan@aeste.net>
|
**
|
**
|
Line 114... |
Line 114... |
|
|
wire fSKIP = (rBRA == 2'o2) | // non-delay branch
|
wire fSKIP = (rBRA == 2'o2) | // non-delay branch
|
!(TXE | pha_i) |
|
!(TXE | pha_i) |
|
fOPBHZD | fOPAHZD; // hazards
|
fOPBHZD | fOPAHZD; // hazards
|
|
|
|
/*
|
|
PARTIAL IMMI
|
|
|
|
Replicated from OPMX and used for checking atomicity for
|
|
interrupts. */
|
|
|
|
reg rFIM0, rFIM1, rFIML[0:1];
|
|
wire rFIM = (pha_i) ? rFIM0 : rFIM1;
|
|
wire fSKP = rBRA == 2'b10;
|
|
wire fINT = !rFIM & !rBRA[1] & rINT & pha_i;
|
|
|
|
always @(posedge clk_i)
|
|
if (rst_i) begin
|
|
/*AUTORESET*/
|
|
// Beginning of autoreset for uninitialized flops
|
|
rFIM0 <= 1'h0;
|
|
rFIM1 <= 1'h0;
|
|
// End of automatics
|
|
end else if (ena_i) begin
|
|
if (pha_i)
|
|
rFIM0 <= #1 fIMM & !fSKP;
|
|
else
|
|
rFIM1 <= #1 fIMM & !fSKP;
|
|
end
|
|
|
|
|
|
|
/* ALU Selector */
|
/* ALU Selector */
|
|
|
always @(posedge clk_i)
|
always @(posedge clk_i)
|
if (rst_i) begin
|
if (rst_i) begin
|
/*AUTORESET*/
|
/*AUTORESET*/
|
Line 134... |
Line 161... |
(fMUL) ? 3'o4 :
|
(fMUL) ? 3'o4 :
|
(fBSF) ? 3'o5 :
|
(fBSF) ? 3'o5 :
|
3'o0;
|
3'o0;
|
*/
|
*/
|
rALU_OF <= #1
|
rALU_OF <= #1
|
(fSKIP) ? 3'o1 : // NOP
|
(fSKIP) ? 3'o2 : // NOP
|
(fBRA | fMOV) ? 3'o1 :
|
(fBRA | fMOV) ? 3'o2 :
|
(fSFT) ? 3'o1 :
|
(fSFT) ? 3'o2 :
|
(fLOG) ? 3'o1 :
|
(fLOG) ? 3'o2 :
|
(fBSF) ? 3'o2 :
|
(fBSF) ? 3'o1 :
|
3'o0;
|
3'o0;
|
end
|
end // if (ena_i)
|
|
|
/* WB Selector */
|
/* WB Selector */
|
|
|
reg [2:0] rOPD_OF;
|
reg [2:0] rOPD_OF;
|
|
|
Line 167... |
Line 194... |
(fMUL) ? 3'o3 : // MUL
|
(fMUL) ? 3'o3 : // MUL
|
(|rRD_IF) ? 3'o0 : // ALU
|
(|rRD_IF) ? 3'o0 : // ALU
|
3'o7; // NOP
|
3'o7; // NOP
|
end // if (ena_i)
|
end // if (ena_i)
|
|
|
/* Passthrough */
|
|
|
|
|
// The only non atomic instruction is IMMI. All other instructions
|
|
// are atomic. No interception allowed for branching.
|
|
|
|
/*
|
|
INTERCEPTION
|
|
|
|
Instructions are either pass-thru or intercepted here. */
|
|
|
always @(posedge clk_i)
|
always @(posedge clk_i)
|
if (rst_i) begin
|
if (rst_i) begin
|
/*AUTORESET*/
|
/*AUTORESET*/
|
// Beginning of autoreset for uninitialized flops
|
// Beginning of autoreset for uninitialized flops
|
Line 185... |
Line 220... |
end else if (ena_i) begin // if (rst_i)
|
end else if (ena_i) begin // if (rst_i)
|
rRD_MA <= #1 rRD_EX;
|
rRD_MA <= #1 rRD_EX;
|
rRD_EX <= #1 rRD_OF;
|
rRD_EX <= #1 rRD_OF;
|
|
|
// TODO: Interrrupt
|
// TODO: Interrrupt
|
case (fSKIP)
|
case ({fINT, fSKIP})
|
2'o0: {rOPC_OF, rRD_OF, rRA_OF, rIMM_OF} <= #1 {rOPC_IF, rRD_IF, rRA_IF, rIMM_IF};
|
2'o0: {rOPC_OF, rRD_OF, rRA_OF, rIMM_OF} <= #1 {rOPC_IF, rRD_IF, rRA_IF, rIMM_IF};
|
2'o1: {rOPC_OF, rRD_OF, rRA_OF, rIMM_OF} <= #1 wNOPOP; // delay/stall
|
2'o1: {rOPC_OF, rRD_OF, rRA_OF, rIMM_OF} <= #1 wNOPOP; // delay/stall
|
|
2'o3,
|
|
2'o2: {rOPC_OF, rRD_OF, rRA_OF, rIMM_OF} <= #1 wINTOP; // interrupt
|
default: {rOPC_OF, rRD_OF, rRA_OF} <= #1 16'hX;
|
default: {rOPC_OF, rRD_OF, rRA_OF} <= #1 16'hX;
|
endcase // case (fSKIP)
|
endcase // case (fSKIP)
|
|
|
end // if (ena_i)
|
end // if (ena_i)
|
|
|
endmodule // aeMB2_idmx
|
endmodule // aeMB2_idmx
|
|
|
/* $Log: not supported by cvs2svn $
|
/* $Log: not supported by cvs2svn $
|
|
/* Revision 1.4 2007/12/13 21:25:41 sybreon
|
|
/* Further optimisations (speed + size).
|
|
/*
|
/* Revision 1.3 2007/12/13 20:12:11 sybreon
|
/* Revision 1.3 2007/12/13 20:12:11 sybreon
|
/* Code cleanup + minor speed regression.
|
/* Code cleanup + minor speed regression.
|
/*
|
/*
|
/* Revision 1.2 2007/12/12 19:16:59 sybreon
|
/* Revision 1.2 2007/12/12 19:16:59 sybreon
|
/* Minor optimisations (~10% faster)
|
/* Minor optimisations (~10% faster)
|