commit-gnuradio
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Commit-gnuradio] r7343 - usrp2/trunk/fpga/opencores/aemb/rtl/verilog


From: matt
Subject: [Commit-gnuradio] r7343 - usrp2/trunk/fpga/opencores/aemb/rtl/verilog
Date: Fri, 4 Jan 2008 13:32:39 -0700 (MST)

Author: matt
Date: 2008-01-04 13:32:38 -0700 (Fri, 04 Jan 2008)
New Revision: 7343

Added:
   usrp2/trunk/fpga/opencores/aemb/rtl/verilog/aeMB2_aslu.v
   usrp2/trunk/fpga/opencores/aemb/rtl/verilog/aeMB2_bpcu.v
   usrp2/trunk/fpga/opencores/aemb/rtl/verilog/aeMB2_edk32.v
   usrp2/trunk/fpga/opencores/aemb/rtl/verilog/aeMB2_idmx.v
   usrp2/trunk/fpga/opencores/aemb/rtl/verilog/aeMB2_ofid.v
   usrp2/trunk/fpga/opencores/aemb/rtl/verilog/aeMB2_opmx.v
   usrp2/trunk/fpga/opencores/aemb/rtl/verilog/aeMB2_regf.v
   usrp2/trunk/fpga/opencores/aemb/rtl/verilog/aeMB2_sim.v
   usrp2/trunk/fpga/opencores/aemb/rtl/verilog/aeMB2_sysc.v
Log:
new version of core.  We aren't using this for now, but may eventually


Added: usrp2/trunk/fpga/opencores/aemb/rtl/verilog/aeMB2_aslu.v
===================================================================
--- usrp2/trunk/fpga/opencores/aemb/rtl/verilog/aeMB2_aslu.v                    
        (rev 0)
+++ usrp2/trunk/fpga/opencores/aemb/rtl/verilog/aeMB2_aslu.v    2008-01-04 
20:32:38 UTC (rev 7343)
@@ -0,0 +1,586 @@
+/* $Id: aeMB2_aslu.v,v 1.7 2007/12/17 12:53:27 sybreon Exp $
+**
+** AEMB2 INTEGER ARITHMETIC SHIFT LOGIC UNIT
+** 
+** Copyright (C) 2004-2007 Shawn Tan Ser Ngiap <address@hidden>
+**  
+** This file is part of AEMB.
+**
+** AEMB is free software: you can redistribute it and/or modify it
+** under the terms of the GNU Lesser General Public License as
+** published by the Free Software Foundation, either version 3 of the
+** License, or (at your option) any later version.
+**
+** AEMB is distributed in the hope that it will be useful, but WITHOUT
+** ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+** or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General
+** Public License for more details.
+**
+** You should have received a copy of the GNU Lesser General Public
+** License along with AEMB. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+module aeMB2_aslu (/*AUTOARG*/
+   // Outputs
+   dwb_adr_o, dwb_sel_o, rSEL_MA, cwb_adr_o, cwb_tga_o, cwb_sel_o,
+   iwb_tga_o, dwb_tga_o, rMUL_MA, rRES_MA, rRES_EX, rMSR_IE, rMSR_BE,
+   rMSR_BIP,
+   // Inputs
+   rIMM_OF, rALU_OF, rOPC_OF, rOPC_IF, rRA_OF, rRD_OF, rOPA_OF,
+   rOPB_OF, pha_i, clk_i, rst_i, ena_i
+   );
+
+   parameter DWB = 32;
+   parameter TXE = 1;
+   
+   parameter MUL = 0;
+   parameter BSF = 1;
+   parameter FSL = 1;   
+   
+   // DWB
+   output [DWB-1:2] dwb_adr_o;
+   output [3:0]     dwb_sel_o;
+   output [3:0]     rSEL_MA;
+
+   // FSL
+   output [6:2]     cwb_adr_o;
+   output [1:0]     cwb_tga_o;
+   output [3:0]     cwb_sel_o;   
+
+   // CACHE ENABLE
+   output          iwb_tga_o,
+                   dwb_tga_o;  
+   
+   // PIPELINE
+   output [31:0]    rMUL_MA;   
+   output [31:0]    rRES_MA,
+                   rRES_EX;   
+   
+   output          rMSR_IE,
+                   rMSR_BE,
+                   //rMSR_TXE,
+                   //rMSR_DCE,
+                   //rMSR_ICE,             
+                   rMSR_BIP;
+   
+   input [15:0]     rIMM_OF;   
+   input [2:0]             rALU_OF;   
+   input [5:0]             rOPC_OF,
+                   rOPC_IF;
+   
+   input [4:0]             rRA_OF,
+                   rRD_OF;
+   
+   input [31:0]     rOPA_OF, // RA, PC
+                   rOPB_OF; // RB, IMM
+   
+   // SYSTEM
+   input           pha_i,
+                   clk_i,
+                   rst_i,
+                   ena_i;
+
+   /*AUTOREG*/
+   // Beginning of automatic regs (for this module's undeclared outputs)
+   reg [6:2]           cwb_adr_o;
+   reg [3:0]           cwb_sel_o;
+   reg [1:0]           cwb_tga_o;
+   reg [DWB-1:2]       dwb_adr_o;
+   reg [3:0]           dwb_sel_o;
+   reg                 dwb_tga_o;
+   reg                 iwb_tga_o;
+   reg                 rMSR_BE;
+   reg                 rMSR_BIP;
+   reg                 rMSR_IE;
+   reg [31:0]          rMUL_MA;
+   reg [31:0]          rRES_EX;
+   reg [31:0]          rRES_MA;
+   reg [3:0]           rSEL_MA;
+   // End of automatics
+
+   reg                         rMSR_C0, 
+                       rMSR_C1, 
+                       rMSR_C,
+                       rMSR_CC,
+                       rMSR_CL[0:1];
+   
+   
+   wire [4:0]          rRD = rRD_OF;   
+   wire [31:0]                 rOPA = rOPA_OF;
+   wire [31:0]                 rOPB = rOPB_OF;   
+   wire [5:0]          rOPC = rOPC_OF;
+   wire [4:0]          rRA = rRA_OF;   
+   wire [15:0]                 rIMM = rIMM_OF;
+   wire [10:0]                 rALT = rIMM_OF[10:0];
+
+   /*
+    MSR REGISTER
+    
+    We should keep common configuration bits in the lower 16-bits of
+    the MSR in order to avoid using the IMMI instruction.
+    
+    MSR bits
+    31 - CC (carry copy)
+    
+    10 - HTE (hardware thread enabled)
+     9 - PHA (current phase)
+     8 - TXE (enable threads)
+    
+     7 - DCE (data cache enable)   
+     5 - ICE (instruction cache enable)
+     4 - FSL (FSL available)
+    
+     3 - BIP (break in progress)
+     2 - C (carry flag)
+     1 - IE (interrupt enable)
+     0 - BE (bus-lock enable)    
+    
+    */
+
+   wire [31:0]                 wMSR = {rMSR_C, // MSR_CC
+                               
+                               20'd0, // Reserved
+                               
+                               TXE[0], // (PVR)
+                               pha_i, // (EIP)
+                               TXE[0], // (EE)
+                               
+                               dwb_tga_o, // MSR_DCE
+                               1'b0, // reserved for DZ
+                               iwb_tga_o, // MSR_ICE
+                               FSL[0], // GET/PUT available
+                               
+                               rMSR_BIP, // MSR_BIP
+                               rMSR_C, // MSR_C
+                               rMSR_IE, // MSR_IE
+                               rMSR_BE}; // MSR_BE
+   
+   
+   /*
+    C SELECTOR 
+
+    Preselects the C to speed things up.  */
+
+   // TODO: Optimise
+   
+   wire                wMSR_CX, wMSR_C;   
+   assign              wMSR_CX = (pha_i) ? rMSR_C0 : rMSR_C1;
+   
+   assign              wMSR_C = (rOPC_IF == 6'o44) & wMSR_CX | // SRX
+                                (rOPC_IF[5:4] == 2'o0) & rOPC_IF[1] & wMSR_CX 
| // ADDC/RSUBC
+                                (rOPC_IF[5:4] == 2'o0) & (rOPC_IF[1:0] == 
2'o1); // RSUB
+   /* 
+   assign              wMSR_C = ((rOPC_IF[5:4] == 2'o0) & (rOPC_OF[1:0] == 
2'o1)) ? 1'b1 : // RSUB = 1
+                                ((rOPC_IF[5:4] == 2'o0) & (rOPC_OF[1:0] == 
2'o0)) ? 1'b0 : // ADD = 0
+                                wMSR_CX;   
+   */
+     
+   always @(posedge clk_i)
+     if (rst_i) begin
+       /*AUTORESET*/
+       // Beginning of autoreset for uninitialized flops
+       rMSR_C <= 1'h0;
+       rMSR_CC <= 1'h0;
+       // End of automatics
+     end else if (ena_i) begin
+       rMSR_C <= #1 wMSR_CX;
+       rMSR_CC <= #1 wMSR_C;   
+     end
+   
+   /* 
+    ADD/SUB SELECTOR
+    
+    Current implementation is a clutz. It needs to be
+    re-implemented. It is also in the critical path.  */
+   
+   // FIXME: Redesign
+   // TODO: Verify signed compare   
+   
+   wire                wADDC, wSUBC, wRES_AC, wCMPC, wOPC;
+   wire [31:0]                 wADD, wSUB, wRES_A, wCMP, wOPX;
+
+   wire                wCMPU = (rOPA > rOPB);         
+   wire                wCMPF = (rIMM[1]) ? wCMPU :
+                       ((wCMPU & ~(rOPB[31] ^ rOPA[31])) | (rOPB[31] & 
~rOPA[31]));
+   
+   assign              {wCMPC,wCMP} = {wSUBC,wCMPF,wSUB[30:0]};  
+   assign              wOPX = (rOPC[0] & !rOPC[5]) ? ~rOPA : rOPA ;
+   //assign            wOPC = ((rMSR_C & rOPC[1]) | (rOPC[0] & !rOPC[1])) & 
(!rOPC[5] & ~&rOPC[5:4]);
+   assign              wOPC = rMSR_CC;   
+   
+   assign              {wSUBC,wSUB} = {wADDC,wADD}; 
+   assign              {wADDC,wADD} = (rOPB + wOPX) + wOPC; 
+   
+   reg                         rRES_ADDC;
+   reg [31:0]          rRES_ADD;
+   always @(rIMM or rOPC or wADD or wADDC or wCMP
+           or wCMPC or wSUB or wSUBC)
+     case ({rOPC[3],rOPC[0],rIMM[0]})
+       4'h2, 4'h6, 4'h7: {rRES_ADDC,rRES_ADD} <= #1 {wSUBC,wSUB}; // SUB
+       4'h3: {rRES_ADDC,rRES_ADD} <= #1 {wCMPC,wCMP}; // CMP
+       default: {rRES_ADDC,rRES_ADD} <= #1 {wADDC,wADD};       
+     endcase // case ({rOPC[3],rOPC[0],rIMM[0]})
+
+   /* 
+    LOGIC
+    
+    This can be combined with the shifter below.
+    */
+
+   reg [31:0]          rRES_LOG;
+   always @(/*AUTOSENSE*/rOPA or rOPB or rOPC)
+     case (rOPC[2:0])
+       2'o0: rRES_LOG <= #1 rOPA | rOPB;
+       2'o1: rRES_LOG <= #1 rOPA & rOPB;
+       2'o2: rRES_LOG <= #1 rOPA ^ rOPB;
+       2'o3: rRES_LOG <= #1 rOPA & ~rOPB;
+     endcase // case (rOPC[2:0])
+   
+   /* 
+    SIMPLE SHIFTER
+        
+    Implemented as wiring and registers.
+    */
+   
+   reg [31:0]          rRES_SFT;
+   reg                         rRES_SFTC;
+   
+   always @(/*AUTOSENSE*/rIMM or rMSR_C or rOPA)
+     case (rIMM[6:5])
+       2'o0: rRES_SFT <= {rOPA[31],rOPA[31:1]}; // SRA
+       2'o1: rRES_SFT <= {rMSR_C,rOPA[31:1]}; // SRC
+       2'o2: rRES_SFT <= {1'b0,rOPA[31:1]}; // SRL
+       2'o3: rRES_SFT <= (rIMM[0]) ? 
+                        {{(16){rOPA[15]}}, rOPA[15:0]} : // SEXT16
+                        {{(24){rOPA[7]}}, rOPA[7:0]}; // SEXT8
+     endcase // case (rIMM[6:5])
+
+   always @(/*AUTOSENSE*/rIMM or rMSR_C or rOPA)
+     rRES_SFTC <= (&rIMM[6:5]) ? rMSR_C : rOPA[0];
+
+   /*
+    MOVER
+    */
+   
+   wire                fMFSR = (rOPC == 6'o45) & !rIMM[14] & rIMM[0];
+   wire                fMFPC = (rOPC == 6'o45) & !rIMM[14] & !rIMM[0];
+   reg [31:0]          rRES_MOV;
+   
+   always @(/*AUTOSENSE*/fMFSR or rOPA or rOPB or rRA or wMSR)
+     case ({fMFSR, rRA[3]})
+       2'o0: rRES_MOV <= rOPA; // MFS rpc
+       2'o1: rRES_MOV <= rOPB; // BRA       
+       2'o2: rRES_MOV <= wMSR; // MFS rmsr
+       default: rRES_MOV <= 32'hX;       
+     endcase // case ({fMFSR, rRA[3]})
+
+
+   /*
+    COMBINED SHIFT/LOGIC/MOVE
+    
+    */
+   
+   reg [31:0]          rRES_SLM;
+
+   always @(/*AUTOSENSE*/fMFSR or rIMM or rMSR_C or rOPA or rOPB
+           or rOPC or rRA or wMSR)
+     case (rOPC[2:0])
+       3'o0: rRES_SLM <= #1 rOPA | rOPB;
+       3'o1: rRES_SLM <= #1 rOPA & rOPB;
+       3'o2: rRES_SLM <= #1 rOPA ^ rOPB;
+       3'o3: rRES_SLM <= #1 rOPA & ~rOPB;
+       3'o4: case (rIMM[6:5])
+              2'o0: rRES_SLM <= #1 {rOPA[31],rOPA[31:1]}; // SRA
+              2'o1: rRES_SLM <= #1 {rMSR_C,rOPA[31:1]}; // SRC
+              2'o2: rRES_SLM <= #1 {1'b0,rOPA[31:1]}; // SRL
+              2'o3: rRES_SLM <= #1 (rIMM[0]) ? 
+                                {{(16){rOPA[15]}}, rOPA[15:0]} : // SEXT16
+                                {{(24){rOPA[7]}}, rOPA[7:0]}; // SEXT8
+            endcase // case (rIMM[6:5])
+       3'o5: case ({fMFSR, rRA[3]})
+              2'o0: rRES_SLM <= #1 rOPA; // MFS rpc
+              2'o1: rRES_SLM <= #1 rOPB; // BRA       
+              2'o2: rRES_SLM <= #1 wMSR; // MFS rmsr
+              default: rRES_MOV <= #1 32'hX;       
+            endcase // case ({fMFSR, rRA[3]})
+       3'o6: rRES_SLM <= #1 rOPB;
+       default: rRES_SLM <= #1 32'hX;       
+     endcase // case (rOPC[2:0])
+   
+   
+   /* 
+    MULTIPLIER
+    
+    Implemented as a 2-stage multiplier in order to increase clock
+    speed. */
+   
+   reg [31:0]      rRES_MUL;
+   always @(posedge clk_i) begin
+      rMUL_MA <= #1 rRES_MUL;      
+      rRES_MUL <= #1 (rOPA * rOPB);
+   end
+
+   /* 
+    BARREL SHIFTER
+    
+    This can be potentially made 2-stage if it is a
+    bottleneck. Doesn't seem necessary at the moment as the critical
+    path runs through the adder. */
+   
+   reg [31:0]   rRES_BSF;
+   reg [31:0]   xBSRL, xBSRA, xBSLL;
+   
+   /* logical left barrel shifter */
+   always @(/*AUTOSENSE*/rOPA or rOPB)
+     xBSLL <= rOPA << rOPB[4:0];
+   
+   /* logical right barrel shifter */
+   always @(/*AUTOSENSE*/rOPA or rOPB)
+     xBSRL <= rOPA >> rOPB[4:0];
+
+   /* arithmetic right barrel shifter */
+   always @(/*AUTOSENSE*/rOPA or rOPB)
+     case (rOPB[4:0])
+       5'd00: xBSRA <= rOPA;
+       5'd01: xBSRA <= {{(1){rOPA[31]}}, rOPA[31:1]};
+       5'd02: xBSRA <= {{(2){rOPA[31]}}, rOPA[31:2]};
+       5'd03: xBSRA <= {{(3){rOPA[31]}}, rOPA[31:3]};
+       5'd04: xBSRA <= {{(4){rOPA[31]}}, rOPA[31:4]};
+       5'd05: xBSRA <= {{(5){rOPA[31]}}, rOPA[31:5]};
+       5'd06: xBSRA <= {{(6){rOPA[31]}}, rOPA[31:6]};
+       5'd07: xBSRA <= {{(7){rOPA[31]}}, rOPA[31:7]};
+       5'd08: xBSRA <= {{(8){rOPA[31]}}, rOPA[31:8]};
+       5'd09: xBSRA <= {{(9){rOPA[31]}}, rOPA[31:9]};
+       5'd10: xBSRA <= {{(10){rOPA[31]}}, rOPA[31:10]};
+       5'd11: xBSRA <= {{(11){rOPA[31]}}, rOPA[31:11]};
+       5'd12: xBSRA <= {{(12){rOPA[31]}}, rOPA[31:12]};
+       5'd13: xBSRA <= {{(13){rOPA[31]}}, rOPA[31:13]};
+       5'd14: xBSRA <= {{(14){rOPA[31]}}, rOPA[31:14]};
+       5'd15: xBSRA <= {{(15){rOPA[31]}}, rOPA[31:15]};
+       5'd16: xBSRA <= {{(16){rOPA[31]}}, rOPA[31:16]};
+       5'd17: xBSRA <= {{(17){rOPA[31]}}, rOPA[31:17]};
+       5'd18: xBSRA <= {{(18){rOPA[31]}}, rOPA[31:18]};
+       5'd19: xBSRA <= {{(19){rOPA[31]}}, rOPA[31:19]};
+       5'd20: xBSRA <= {{(20){rOPA[31]}}, rOPA[31:20]};
+       5'd21: xBSRA <= {{(21){rOPA[31]}}, rOPA[31:21]};
+       5'd22: xBSRA <= {{(22){rOPA[31]}}, rOPA[31:22]};
+       5'd23: xBSRA <= {{(23){rOPA[31]}}, rOPA[31:23]};
+       5'd24: xBSRA <= {{(24){rOPA[31]}}, rOPA[31:24]};
+       5'd25: xBSRA <= {{(25){rOPA[31]}}, rOPA[31:25]};
+       5'd26: xBSRA <= {{(26){rOPA[31]}}, rOPA[31:26]};
+       5'd27: xBSRA <= {{(27){rOPA[31]}}, rOPA[31:27]};
+       5'd28: xBSRA <= {{(28){rOPA[31]}}, rOPA[31:28]};
+       5'd29: xBSRA <= {{(29){rOPA[31]}}, rOPA[31:29]};
+       5'd30: xBSRA <= {{(30){rOPA[31]}}, rOPA[31:30]};
+       5'd31: xBSRA <= {{(31){rOPA[31]}}, rOPA[31]};
+     endcase // case (rOPB[4:0])
+
+   /* select the shift result (2nd stage) */
+   always @(/*AUTOSENSE*/rALT or xBSLL or xBSRA or xBSRL)
+     case (rALT[10:9])
+       2'd0: rRES_BSF <= xBSRL;
+       2'd1: rRES_BSF <= xBSRA;       
+       2'd2: rRES_BSF <= xBSLL;
+       default: rRES_BSF <= 32'hX;       
+     endcase // case (rALT[10:9])
+
+
+   /*
+    RESULTS
+    */
+   
+   // RESULT   
+   always @(posedge clk_i)
+     if (rst_i) begin
+       /*AUTORESET*/
+       // Beginning of autoreset for uninitialized flops
+       rRES_EX <= 32'h0;
+       rRES_MA <= 32'h0;
+       // End of automatics
+     end else if (ena_i) begin
+       rRES_MA <= #1 rRES_EX;
+       /*
+       case (rALU_OF)
+         3'o0: rRES_EX <= #1 rRES_ADD;
+         3'o1: rRES_EX <= #1 rRES_LOG;
+         3'o2: rRES_EX <= #1 rRES_SFT;
+         3'o3: rRES_EX <= #1 rRES_MOV;
+         3'o5: rRES_EX <= #1 (BSF) ? rRES_BSF : 32'hX;  
+         default: rRES_EX <= #1 32'hX;   
+       endcase // case (rALU_OF)
+        */
+       case (rALU_OF[1:0])
+       //case (rOPC[5:4])
+         2'o0: rRES_EX <= #1 rRES_ADD;
+         2'o2: rRES_EX <= #1 rRES_SLM;
+         2'o1: rRES_EX <= #1 (BSF) ? rRES_BSF : 32'hX;   
+         default: rRES_EX <= #1 32'hX;   
+       endcase // case (rALU_OF[1:0])
+       
+     end // if (ena_i)
+   
+   
+   /*
+    MSR REGISTER
+   
+    Move data to the MSR or change due to break/returns. */
+   
+   reg                  xMSR_C;
+   
+   // C
+   wire         fMTS = (rOPC == 6'o45) & rIMM[14];
+   wire         fADDC = ({rOPC[5:4], rOPC[2]} == 3'o0);
+   
+   always @(/*AUTOSENSE*/fADDC or rALU_OF or rIMM or rMSR_C or rOPC
+           or rRES_ADDC or rRES_SFTC)
+     case (rALU_OF[1:0])
+     //case (rOPC[5:4])
+       3'o0: xMSR_C <= (fADDC) ? rRES_ADDC : rMSR_C; // ADD/SUB
+       3'o2: case (rOPC[2:0])
+              3'o5: xMSR_C <= (rIMM[14]) ? rOPA[2] : rMSR_C; // MTS
+              3'o4: xMSR_C <= (&rIMM[6:5]) ? rMSR_C : rRES_SFTC; // SRX
+              default: xMSR_C <= rMSR_C;
+            endcase // case (rOPC[2:0])
+       default: xMSR_C <= rMSR_C;       
+     endcase // case (rOPC[5:4])
+   
+     /*
+     case (rALU_OF)
+       3'o0: xMSR_C <= (fADDC) ? rRES_ADDC : rMSR_C;    
+       3'o1: xMSR_C <= rMSR_C; // LOGIC       
+       3'o2: xMSR_C <= rRES_SFTC; // SHIFT
+       3'o3: xMSR_C <= (fMTS) ? rOPA[2] : rMSR_C;
+       3'o4: xMSR_C <= rMSR_C;  
+       3'o5: xMSR_C <= rMSR_C;  
+       default: xMSR_C <= 1'hX;       
+     endcase // case (rALU_OF)
+      */
+     
+   always @(posedge clk_i)
+     if (rst_i) begin
+       /*AUTORESET*/
+       // Beginning of autoreset for uninitialized flops
+       rMSR_C0 <= 1'h0;
+       rMSR_C1 <= 1'h0;
+       // End of automatics
+     end else if (ena_i) begin
+       if (pha_i)
+         rMSR_C1 <= #1 xMSR_C;
+       else
+         rMSR_C0 <= #1 xMSR_C; 
+     end
+   
+   // IE/BIP/BE
+   wire            fRTID = (rOPC == 6'o55) & rRD[0];   
+   wire            fRTBD = (rOPC == 6'o55) & rRD[1];
+   wire            fBRK = ((rOPC == 6'o56) | (rOPC == 6'o66)) & (rRA == 5'hC);
+   wire            fINT = ((rOPC == 6'o56) | (rOPC == 6'o66)) & (rRA == 5'hE);
+
+   always @(posedge clk_i)
+     if (rst_i) begin
+       /*AUTORESET*/
+       // Beginning of autoreset for uninitialized flops
+       dwb_tga_o <= 1'h0;
+       iwb_tga_o <= 1'h0;
+       rMSR_BE <= 1'h0;
+       rMSR_BIP <= 1'h0;
+       rMSR_IE <= 1'h0;
+       // End of automatics
+     end else if (ena_i) begin
+       
+       // Interrupt enable (compatible)
+       rMSR_IE <= #1
+                  (fINT) ? 1'b0 :
+                  (fRTID) ? 1'b1 : 
+                  (fMTS) ? rOPA[1] :
+                  rMSR_IE;
+
+       // Break in progress (compatible)
+       rMSR_BIP <= #1
+                   (fBRK) ? 1'b1 :
+                   (fRTBD) ? 1'b0 : 
+                   (fMTS) ? rOPA[3] :
+                   rMSR_BIP;
+
+       // Forcibly assert dwb_cyc_o signal     
+       rMSR_BE <= #1
+                  (fMTS) ? rOPA[0] : rMSR_BE;
+
+       // Enable the thread extension
+       //rMSR_TXE <= #1 TXE[0];        
+
+       // Enable the caches
+       dwb_tga_o <= #1 (fMTS) ? 
+                    rOPA[7] : 
+                    dwb_tga_o;
+       iwb_tga_o <= #1 (fMTS) ? 
+                    rOPA[5] : 
+                    iwb_tga_o; 
+       
+     end // if (ena_i)
+
+   /*
+    DATA/FSL WISHBONE
+    
+    Asserts the data address as calculated by the adder and the
+    appropriate byte select lanes depending on the byte offset of the
+    address. It does not check for mis-aligned addresses.  */
+
+   // TODO: Check for mis-alignment
+
+   always @(posedge clk_i)
+     if (rst_i) begin
+       /*AUTORESET*/
+       // Beginning of autoreset for uninitialized flops
+       cwb_adr_o <= 5'h0;
+       cwb_sel_o <= 4'h0;
+       cwb_tga_o <= 2'h0;
+       dwb_adr_o <= {(1+(DWB-1)-(2)){1'b0}};
+       dwb_sel_o <= 4'h0;
+       rSEL_MA <= 4'h0;
+       // End of automatics
+     end else if (ena_i) begin // if (rst_i)
+       rSEL_MA <= #1 dwb_sel_o;        
+       
+       dwb_adr_o <= #1 wADD[DWB-1:2];  
+       case (rOPC[1:0])
+         2'o0: case (wADD[1:0]) // 8'bit
+                 2'o0: dwb_sel_o <= #1 4'h8;          
+                 2'o1: dwb_sel_o <= #1 4'h4;          
+                 2'o2: dwb_sel_o <= #1 4'h2;          
+                 2'o3: dwb_sel_o <= #1 4'h1;          
+               endcase // case (wADD[1:0])
+         2'o1: dwb_sel_o <= #1 (wADD[1]) ? 4'h3 : 4'hC; // 16'bit
+         2'o2: dwb_sel_o <= #1 4'hF; // 32'bit
+         2'o3: dwb_sel_o <= #1 4'h0; // FSL
+       endcase // case (rOPC[1:0])
+
+       {cwb_adr_o, cwb_tga_o} <= #1 {rIMM_OF[4:0], rIMM_OF[15:14]};
+       cwb_sel_o <= #1 {(4){ &rOPC[1:0]}};     
+       
+     end // if (ena_i)
+   
+endmodule // aeMB2_aslu
+
+/* $Log: aeMB2_aslu.v,v $
+/* Revision 1.7  2007/12/17 12:53:27  sybreon
+/* Fixed Carry bit bug.
+/*
+/* Revision 1.6  2007/12/16 20:38:06  sybreon
+/* Minor optimisations.
+/*
+/* Revision 1.5  2007/12/16 03:25:37  sybreon
+/* Some optimisations.
+/*
+/* Revision 1.4  2007/12/13 21:25:41  sybreon
+/* Further optimisations (speed + size).
+/*
+/* Revision 1.3  2007/12/13 20:12:11  sybreon
+/* Code cleanup + minor speed regression.
+/*
+/* Revision 1.2  2007/12/12 19:16:59  sybreon
+/* Minor optimisations (~10% faster)
+/*
+/* Revision 1.1  2007/12/11 00:43:17  sybreon
+/* initial import
+/* */
\ No newline at end of file

Added: usrp2/trunk/fpga/opencores/aemb/rtl/verilog/aeMB2_bpcu.v
===================================================================
--- usrp2/trunk/fpga/opencores/aemb/rtl/verilog/aeMB2_bpcu.v                    
        (rev 0)
+++ usrp2/trunk/fpga/opencores/aemb/rtl/verilog/aeMB2_bpcu.v    2008-01-04 
20:32:38 UTC (rev 7343)
@@ -0,0 +1,260 @@
+/* $Id: aeMB2_bpcu.v,v 1.5 2007/12/21 22:39:38 sybreon Exp $
+**
+** AEMB2 BRANCH/PROGRAMME COUNTER
+** 
+** Copyright (C) 2004-2007 Shawn Tan Ser Ngiap <address@hidden>
+**  
+** This file is part of AEMB.
+**
+** AEMB is free software: you can redistribute it and/or modify it
+** under the terms of the GNU Lesser General Public License as
+** published by the Free Software Foundation, either version 3 of the
+** License, or (at your option) any later version.
+**
+** AEMB is distributed in the hope that it will be useful, but WITHOUT
+** ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+** or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General
+** Public License for more details.
+**
+** You should have received a copy of the GNU Lesser General Public
+** License along with AEMB. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+module aeMB2_bpcu (/*AUTOARG*/
+   // Outputs
+   iwb_adr_o, rPC_MA, rPC_IF, rIMM_IF, rALT_IF, rOPC_IF, rRD_IF,
+   rRA_IF, rRB_IF, rBRA,
+   // Inputs
+   iwb_dat_i, iwb_ack_i, rOPX_OF, rOPC_OF, rRA_OF, rRD_OF, rRES_EX,
+   rRD_EX, rOPD_EX, clk_i, rst_i, ena_i, pha_i
+   );
+   parameter IWB = 32;
+   parameter TXE = 1;   
+   
+   // IWB
+   output [IWB-1:2] iwb_adr_o;
+   input [31:0]     iwb_dat_i;
+   input           iwb_ack_i;
+   
+   // PIPELINE
+   output [31:2]    //rPC_OF,
+                   rPC_MA,
+                   rPC_IF;    
+   output [15:0]    rIMM_IF;
+   output [10:0]    rALT_IF;
+   output [5:0]     rOPC_IF;
+   output [4:0]     rRD_IF,
+                   rRA_IF,
+                   rRB_IF;
+
+   // BRANCH DETECTION
+   output [1:0]     rBRA; // {branch, delay}
+   input [31:0]     rOPX_OF; // BCC op test   
+   input [5:0]             rOPC_OF;
+   input [4:0]             rRA_OF,
+                   rRD_OF;   
+   input [31:0]     rRES_EX;  
+
+   // MEMORY HAZARD DETECTION
+   input [4:0]             rRD_EX; ///< RD
+   input [2:0]             rOPD_EX; ///< data register source (ALU, MEM/FSL, 
PC)
+   
+   // SYSTEM
+   input           clk_i, 
+                   rst_i, 
+                   ena_i, 
+                   pha_i;
+   
+   /*AUTOREG*/
+   // Beginning of automatic regs (for this module's undeclared outputs)
+   reg [1:0]           rBRA;
+   reg [15:0]          rIMM_IF;
+   reg [5:0]           rOPC_IF;
+   reg [31:2]          rPC_IF;
+   reg [31:2]          rPC_MA;
+   reg [4:0]           rRA_IF;
+   reg [4:0]           rRD_IF;
+   // End of automatics
+
+   /* Partial decoding */
+   wire [5:0]          rOPC = rOPC_IF;
+   wire [4:0]          rRA = rRA_IF;
+   wire [4:0]          rRB = rRB_IF;   
+   wire                fSFT = (rOPC == 6'o44);
+   wire                fLOG = ({rOPC[5:4],rOPC[2]} == 3'o4);      
+   wire                fMUL = (rOPC == 6'o20) | (rOPC == 6'o30);
+   wire                fBSF = (rOPC == 6'o21) | (rOPC == 6'o31);
+   wire                fDIV = (rOPC == 6'o22);   
+   wire                fRTD = (rOPC == 6'o55);
+   wire                fBCC = (rOPC == 6'o47) | (rOPC == 6'o57);
+   wire                fBRU = (rOPC == 6'o46) | (rOPC == 6'o56);
+   wire                fBRA = fBRU & rRA[3];      
+   wire                fIMM = (rOPC == 6'o54);
+   wire                fMOV = (rOPC == 6'o45);      
+   wire                fLOD = ({rOPC[5:4],rOPC[2]} == 3'o6);
+   wire                fSTR = ({rOPC[5:4],rOPC[2]} == 3'o7);
+   wire                fLDST = (rOPC[5:4] == 2'o3);      
+   wire                fPUT = (rOPC == 6'o33) & rRB[4];
+   wire                fGET = (rOPC == 6'o33) & !rRB[4];
+   
+   /* Select the PC. */
+   
+   reg [31:2]          rPC, // PC
+                       rPC0, rPC1,// register based 
+                       rPCL[0:1]; // LUT based
+
+   wire [31:2]                 wPCNXT = (pha_i | !TXE) ? rPC0 : rPC1; 
+   wire [31:2]                 wPCINC = (rPC + 1);
+   
+   /* Check for RW data hazard */
+   // TODO: Optimise
+
+   wire                fLOAD = (rOPD_EX == 3'o2);
+   wire                fMULT = (rOPD_EX == 3'o3);
+   wire                fWRE = |rRD_EX;
+   wire                fOPBHZD = (rRB_IF == rRD_EX) & (fLOAD | fMULT) & !fMOV 
& !rOPC_IF[3] & fWRE;
+   wire                fOPAHZD = (rRA_IF == rRD_EX) & (fLOAD | fMULT) & !fBRU 
& fWRE;      
+   wire                fOPDHZD = (rRD_IF == rRD_EX) & (fLOAD | fMULT) & fSTR & 
fWRE;   
+   wire                fHZD = (fOPBHZD | fOPAHZD | fOPDHZD) & !rBRA[1];
+
+   /* 
+    IWB PC OUTPUT
+    
+    This is part of the address generation stage. It pre-selects the
+    next PC to fetch depending on whether it's a branch, retry or
+    normal. A retry happens during a special hazard */
+   
+   wire [1:0]          wIPCMX = {fHZD, rBRA[1]};
+   assign              iwb_adr_o = rPC[IWB-1:2];
+   
+   always @ (posedge clk_i) 
+     if (rst_i) begin
+       rPC <= {(30){1'b1}};
+       /*AUTORESET*/
+     end else if (ena_i) begin
+       case (wIPCMX)
+         2'o0 : rPC <= #1 wPCNXT[IWB-1:2]; // normal
+         2'o1 : rPC <= #1 rRES_EX[IWB-1:2]; // branch/return/break
+         2'o2 : rPC <= #1 rPC_IF[IWB-1:2]; // retry/stall
+         default: rPC <= {(IWB-2){1'bX}}; // undefined
+       endcase // case (wIPCMX)
+     end
+
+   /* 
+    PC INCREMENT
+    
+    This will store the next PC in a holding register until it is
+    needed during the next AG stage. */
+   
+   always @(posedge clk_i)
+     if (rst_i) begin
+       /*AUTORESET*/
+       // Beginning of autoreset for uninitialized flops
+       rPC0 <= 30'h0;
+       rPC1 <= 30'h0;
+       // End of automatics
+     end else if (ena_i) begin
+       if (pha_i) 
+         rPC1 <= #1 wPCINC;
+       else
+         rPC0 <= #1 wPCINC;    
+     end
+   
+   /* 
+    INSTRUCTION LATCH
+    
+    This latches onto the instruction. It may not work correctly if
+    there is a pipeline stall. */
+   
+   reg [31:2]          rPC_OF, rPC_EX;
+   assign              {rRB_IF, rALT_IF} = rIMM_IF;
+   
+   always @(posedge clk_i)
+     if (rst_i) begin
+       /*AUTORESET*/
+       // Beginning of autoreset for uninitialized flops
+       rIMM_IF <= 16'h0;
+       rOPC_IF <= 6'h0;
+       rRA_IF <= 5'h0;
+       rRD_IF <= 5'h0;
+       // End of automatics
+     end else if (ena_i & iwb_ack_i) begin
+       {rOPC_IF, rRD_IF, rRA_IF, rIMM_IF} <= #1 iwb_dat_i;
+     end
+
+   /*
+    PC PIPELINE
+    
+    This merely passes the PC down so that it is available during
+    branch instructions. This may be modified to use a shift register.
+    */
+
+   always @(posedge clk_i) if (rst_i) begin
+       /*AUTORESET*/
+       // Beginning of autoreset for uninitialized flops
+       rPC_EX <= 30'h0;
+       rPC_IF <= 30'h0;
+       rPC_MA <= 30'h0;
+       rPC_OF <= 30'h0;
+       // End of automatics
+   end else if (ena_i) begin
+       // TODO: Stuff inside a small LUT FIFO
+       {rPC_MA, rPC_EX, rPC_OF, rPC_IF} <= #1 {rPC_EX, rPC_OF, rPC_IF, rPC};   
+   end
+
+   /* Branch Control */
+   
+   wire                wRTD = (rOPC_OF == 6'o55);
+   wire                wBCC = (rOPC_OF == 6'o47) | (rOPC_OF == 6'o57);
+   wire                wBRU = (rOPC_OF == 6'o46) | (rOPC_OF == 6'o56);
+   
+   wire                wBEQ = (rOPX_OF == 32'd0);
+   wire                wBNE = ~wBEQ;
+   wire                wBLT = rOPX_OF[31];
+   wire                wBLE = wBLT | wBEQ;   
+   wire                wBGE = ~wBLT;
+   wire                wBGT = ~wBLE;   
+
+   reg                         xXCC;
+   
+   always @(/*AUTOSENSE*/rRD_OF or wBEQ or wBGE or wBGT or wBLE
+           or wBLT or wBNE)
+     case (rRD_OF[2:0])
+       3'o0: xXCC <= wBEQ;
+       3'o1: xXCC <= wBNE;
+       3'o2: xXCC <= wBLT;
+       3'o3: xXCC <= wBLE;
+       3'o4: xXCC <= wBGT;
+       3'o5: xXCC <= wBGE;
+       default: xXCC <= 1'bX;
+     endcase // case (rRD_OF[2:0])
+   
+   always @(posedge clk_i)
+     if (rst_i) begin
+       /*AUTORESET*/
+       // Beginning of autoreset for uninitialized flops
+       rBRA <= 2'h0;
+       // End of automatics
+     end else if(ena_i) begin
+       rBRA[1] <= #1 wRTD | wBRU | (wBCC & xXCC);      
+       rBRA[0] <= #1 (wBRU & rRA_OF[4]) | (wBCC & rRD_OF[4]) | wRTD;           
+     end
+   
+endmodule // aeMB2_bpcu
+
+/* $Log: aeMB2_bpcu.v,v $
+/* Revision 1.5  2007/12/21 22:39:38  sybreon
+/* Prevent fHZD & rBRA[1]
+/*
+/* Revision 1.4  2007/12/17 12:53:43  sybreon
+/* Made idle thread PC track main PC.
+/*
+/* Revision 1.3  2007/12/13 20:12:11  sybreon
+/* Code cleanup + minor speed regression.
+/*
+/* Revision 1.2  2007/12/12 19:16:59  sybreon
+/* Minor optimisations (~10% faster)
+/*
+/* Revision 1.1  2007/12/11 00:43:17  sybreon
+/* initial import
+/* */
\ No newline at end of file

Added: usrp2/trunk/fpga/opencores/aemb/rtl/verilog/aeMB2_edk32.v
===================================================================
--- usrp2/trunk/fpga/opencores/aemb/rtl/verilog/aeMB2_edk32.v                   
        (rev 0)
+++ usrp2/trunk/fpga/opencores/aemb/rtl/verilog/aeMB2_edk32.v   2008-01-04 
20:32:38 UTC (rev 7343)
@@ -0,0 +1,341 @@
+/* $Id: aeMB2_edk32.v,v 1.8 2007/12/18 18:54:36 sybreon Exp $
+**
+** AEMB2 HI-PERFORMANCE CPU
+** 
+** Copyright (C) 2004-2007 Shawn Tan Ser Ngiap <address@hidden>
+**  
+** This file is part of AEMB.
+**
+** AEMB is free software: you can redistribute it and/or modify it
+** under the terms of the GNU Lesser General Public License as
+** published by the Free Software Foundation, either version 3 of the
+** License, or (at your option) any later version.
+**
+** AEMB is distributed in the hope that it will be useful, but WITHOUT
+** ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+** or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General
+** Public License for more details.
+**
+** You should have received a copy of the GNU Lesser General Public
+** License along with AEMB. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+module aeMB2_edk32 (/*AUTOARG*/
+   // Outputs
+   iwb_wre_o, iwb_tga_o, iwb_stb_o, iwb_adr_o, dwb_wre_o, dwb_tga_o,
+   dwb_stb_o, dwb_sel_o, dwb_dat_o, dwb_cyc_o, dwb_adr_o, cwb_wre_o,
+   cwb_tga_o, cwb_stb_o, cwb_sel_o, cwb_dat_o, cwb_adr_o,
+   // Inputs
+   sys_rst_i, sys_int_i, sys_clk_i, iwb_dat_i, iwb_ack_i, dwb_dat_i,
+   dwb_ack_i, cwb_dat_i, cwb_ack_i
+   );
+   parameter IWB = 32; // instruction wishbone address space
+   parameter DWB = 32; // data wishbone address space
+
+   parameter TXE = 1; // thread execution extension
+   
+   parameter MUL = 1; // enable multiply instruction
+   parameter BSF = 1; // enable barrel shift instructions
+   parameter FSL = 1; // enable get/put instructions
+   
+   /*AUTOOUTPUT*/
+   // Beginning of automatic outputs (from unused autoinst outputs)
+   output [6:2]                cwb_adr_o;              // From aslu of 
aeMB2_aslu.v
+   output [31:0]       cwb_dat_o;              // From regf of aeMB2_regf.v
+   output [3:0]                cwb_sel_o;              // From aslu of 
aeMB2_aslu.v
+   output              cwb_stb_o;              // From sysc of aeMB2_sysc.v
+   output [1:0]                cwb_tga_o;              // From aslu of 
aeMB2_aslu.v
+   output              cwb_wre_o;              // From sysc of aeMB2_sysc.v
+   output [DWB-1:2]    dwb_adr_o;              // From aslu of aeMB2_aslu.v
+   output              dwb_cyc_o;              // From sysc of aeMB2_sysc.v
+   output [31:0]       dwb_dat_o;              // From regf of aeMB2_regf.v
+   output [3:0]                dwb_sel_o;              // From aslu of 
aeMB2_aslu.v
+   output              dwb_stb_o;              // From sysc of aeMB2_sysc.v
+   output              dwb_tga_o;              // From aslu of aeMB2_aslu.v
+   output              dwb_wre_o;              // From sysc of aeMB2_sysc.v
+   output [IWB-1:2]    iwb_adr_o;              // From bpcu of aeMB2_bpcu.v
+   output              iwb_stb_o;              // From sysc of aeMB2_sysc.v
+   output              iwb_tga_o;              // From aslu of aeMB2_aslu.v
+   output              iwb_wre_o;              // From sysc of aeMB2_sysc.v
+   // End of automatics
+   /*AUTOINPUT*/
+   // Beginning of automatic inputs (from unused autoinst inputs)
+   input               cwb_ack_i;              // To sysc of aeMB2_sysc.v, ...
+   input [31:0]                cwb_dat_i;              // To regf of 
aeMB2_regf.v
+   input               dwb_ack_i;              // To sysc of aeMB2_sysc.v, ...
+   input [31:0]                dwb_dat_i;              // To regf of 
aeMB2_regf.v
+   input               iwb_ack_i;              // To sysc of aeMB2_sysc.v, ...
+   input [31:0]                iwb_dat_i;              // To bpcu of 
aeMB2_bpcu.v
+   input               sys_clk_i;              // To sysc of aeMB2_sysc.v
+   input               sys_int_i;              // To sysc of aeMB2_sysc.v
+   input               sys_rst_i;              // To sysc of aeMB2_sysc.v
+   // End of automatics
+   /*AUTOWIRE*/
+   // Beginning of automatic wires (for undeclared instantiated-module outputs)
+   wire                        clk_i;                  // From sysc of 
aeMB2_sysc.v
+   wire                        ena_i;                  // From sysc of 
aeMB2_sysc.v
+   wire                        pha_i;                  // From sysc of 
aeMB2_sysc.v
+   wire [10:0]         rALT_IF;                // From bpcu of aeMB2_bpcu.v
+   wire [2:0]          rALU_OF;                // From ofid of aeMB2_ofid.v
+   wire [1:0]          rBRA;                   // From bpcu of aeMB2_bpcu.v
+   wire [15:0]         rIMM_IF;                // From bpcu of aeMB2_bpcu.v
+   wire [15:0]         rIMM_OF;                // From ofid of aeMB2_ofid.v
+   wire                        rINT;                   // From sysc of 
aeMB2_sysc.v
+   wire                        rMSR_BE;                // From aslu of 
aeMB2_aslu.v
+   wire                        rMSR_BIP;               // From aslu of 
aeMB2_aslu.v
+   wire                        rMSR_IE;                // From aslu of 
aeMB2_aslu.v
+   wire [31:0]         rMUL_MA;                // From aslu of aeMB2_aslu.v
+   wire [31:0]         rOPA_OF;                // From ofid of aeMB2_ofid.v
+   wire [31:0]         rOPB_OF;                // From ofid of aeMB2_ofid.v
+   wire [5:0]          rOPC_IF;                // From bpcu of aeMB2_bpcu.v
+   wire [5:0]          rOPC_OF;                // From ofid of aeMB2_ofid.v
+   wire [2:0]          rOPD_EX;                // From ofid of aeMB2_ofid.v
+   wire [2:0]          rOPD_MA;                // From ofid of aeMB2_ofid.v
+   wire [31:0]         rOPM_OF;                // From ofid of aeMB2_ofid.v
+   wire [31:0]         rOPX_OF;                // From ofid of aeMB2_ofid.v
+   wire [31:2]         rPC_IF;                 // From bpcu of aeMB2_bpcu.v
+   wire [31:2]         rPC_MA;                 // From bpcu of aeMB2_bpcu.v
+   wire [4:0]          rRA_IF;                 // From bpcu of aeMB2_bpcu.v
+   wire [4:0]          rRA_OF;                 // From ofid of aeMB2_ofid.v
+   wire [4:0]          rRB_IF;                 // From bpcu of aeMB2_bpcu.v
+   wire [4:0]          rRD_EX;                 // From ofid of aeMB2_ofid.v
+   wire [4:0]          rRD_IF;                 // From bpcu of aeMB2_bpcu.v
+   wire [4:0]          rRD_MA;                 // From ofid of aeMB2_ofid.v
+   wire [4:0]          rRD_OF;                 // From ofid of aeMB2_ofid.v
+   wire [31:0]         rREGA_OF;               // From regf of aeMB2_regf.v
+   wire [31:0]         rREGB_OF;               // From regf of aeMB2_regf.v
+   wire [31:0]         rREGD_OF;               // From regf of aeMB2_regf.v
+   wire [31:0]         rRES_EX;                // From aslu of aeMB2_aslu.v
+   wire [31:0]         rRES_MA;                // From aslu of aeMB2_aslu.v
+   wire [3:0]          rSEL_MA;                // From aslu of aeMB2_aslu.v
+   wire                        rXCE;                   // From sysc of 
aeMB2_sysc.v
+   wire                        rst_i;                  // From sysc of 
aeMB2_sysc.v
+   // End of automatics
+
+   /* aeMB2_sysc AUTO_TEMPLATE (
+    .clk_o(clk_i),
+    .rst_o(rst_i),
+    .ena_o(ena_i),
+    .pha_o(pha_i),
+    )*/
+
+   /* System/Interrupt Control */
+   
+   aeMB2_sysc 
+     #(/*AUTOINSTPARAM*/
+       // Parameters
+       .TXE                            (TXE),
+       .FSL                            (FSL))
+   sysc (/*AUTOINST*/
+        // Outputs
+        .rINT                          (rINT),
+        .rXCE                          (rXCE),
+        .pha_o                         (pha_i),                 // Templated
+        .clk_o                         (clk_i),                 // Templated
+        .rst_o                         (rst_i),                 // Templated
+        .ena_o                         (ena_i),                 // Templated
+        .iwb_stb_o                     (iwb_stb_o),
+        .iwb_wre_o                     (iwb_wre_o),
+        .dwb_cyc_o                     (dwb_cyc_o),
+        .dwb_stb_o                     (dwb_stb_o),
+        .dwb_wre_o                     (dwb_wre_o),
+        .cwb_stb_o                     (cwb_stb_o),
+        .cwb_wre_o                     (cwb_wre_o),
+        // Inputs
+        .rIMM_OF                       (rIMM_OF[15:0]),
+        .rOPC_OF                       (rOPC_OF[5:0]),
+        .rRA_OF                        (rRA_OF[4:0]),
+        .rMSR_BE                       (rMSR_BE),
+        .rMSR_BIP                      (rMSR_BIP),
+        .rMSR_IE                       (rMSR_IE),
+        .rOPC_IF                       (rOPC_IF[5:0]),
+        .iwb_ack_i                     (iwb_ack_i),
+        .dwb_ack_i                     (dwb_ack_i),
+        .cwb_ack_i                     (cwb_ack_i),
+        .sys_int_i                     (sys_int_i),
+        .sys_clk_i                     (sys_clk_i),
+        .sys_rst_i                     (sys_rst_i));
+
+   /* Register file */
+
+   aeMB2_regf 
+     #(/*AUTOINSTPARAM*/
+       // Parameters
+       .TXE                            (TXE),
+       .MUL                            (MUL))
+   regf (/*AUTOINST*/
+        // Outputs
+        .dwb_dat_o                     (dwb_dat_o[31:0]),
+        .cwb_dat_o                     (cwb_dat_o[31:0]),
+        .rREGD_OF                      (rREGD_OF[31:0]),
+        .rREGA_OF                      (rREGA_OF[31:0]),
+        .rREGB_OF                      (rREGB_OF[31:0]),
+        // Inputs
+        .dwb_dat_i                     (dwb_dat_i[31:0]),
+        .dwb_ack_i                     (dwb_ack_i),
+        .cwb_dat_i                     (cwb_dat_i[31:0]),
+        .cwb_ack_i                     (cwb_ack_i),
+        .rRA_IF                        (rRA_IF[4:0]),
+        .rRB_IF                        (rRB_IF[4:0]),
+        .rRD_IF                        (rRD_IF[4:0]),
+        .rRD_MA                        (rRD_MA[4:0]),
+        .rOPM_OF                       (rOPM_OF[31:0]),
+        .rOPA_OF                       (rOPA_OF[31:0]),
+        .rOPC_OF                       (rOPC_OF[5:0]),
+        .rPC_MA                        (rPC_MA[31:2]),
+        .rMUL_MA                       (rMUL_MA[31:0]),
+        .rRES_MA                       (rRES_MA[31:0]),
+        .rOPD_MA                       (rOPD_MA[2:0]),
+        .rSEL_MA                       (rSEL_MA[3:0]),
+        .clk_i                         (clk_i),
+        .rst_i                         (rst_i),
+        .ena_i                         (ena_i),
+        .pha_i                         (pha_i));
+
+   /* Branch/Programme Counter Unit */
+   
+   aeMB2_bpcu
+     #(/*AUTOINSTPARAM*/
+       // Parameters
+       .IWB                            (IWB),
+       .TXE                            (TXE))     
+   bpcu (/*AUTOINST*/
+        // Outputs
+        .iwb_adr_o                     (iwb_adr_o[IWB-1:2]),
+        .rPC_MA                        (rPC_MA[31:2]),
+        .rPC_IF                        (rPC_IF[31:2]),
+        .rIMM_IF                       (rIMM_IF[15:0]),
+        .rALT_IF                       (rALT_IF[10:0]),
+        .rOPC_IF                       (rOPC_IF[5:0]),
+        .rRD_IF                        (rRD_IF[4:0]),
+        .rRA_IF                        (rRA_IF[4:0]),
+        .rRB_IF                        (rRB_IF[4:0]),
+        .rBRA                          (rBRA[1:0]),
+        // Inputs
+        .iwb_dat_i                     (iwb_dat_i[31:0]),
+        .iwb_ack_i                     (iwb_ack_i),
+        .rOPX_OF                       (rOPX_OF[31:0]),
+        .rOPC_OF                       (rOPC_OF[5:0]),
+        .rRA_OF                        (rRA_OF[4:0]),
+        .rRD_OF                        (rRD_OF[4:0]),
+        .rRES_EX                       (rRES_EX[31:0]),
+        .rRD_EX                        (rRD_EX[4:0]),
+        .rOPD_EX                       (rOPD_EX[2:0]),
+        .clk_i                         (clk_i),
+        .rst_i                         (rst_i),
+        .ena_i                         (ena_i),
+        .pha_i                         (pha_i));
+
+   /* Operand Fetch Mux */
+   
+   aeMB2_ofid
+     #(/*AUTOINSTPARAM*/
+       // Parameters
+       .TXE                            (TXE),
+       .MUL                            (MUL),
+       .BSF                            (BSF),
+       .FSL                            (FSL))
+   ofid (/*AUTOINST*/
+        // Outputs
+        .rOPM_OF                       (rOPM_OF[31:0]),
+        .rOPX_OF                       (rOPX_OF[31:0]),
+        .rOPA_OF                       (rOPA_OF[31:0]),
+        .rOPB_OF                       (rOPB_OF[31:0]),
+        .rIMM_OF                       (rIMM_OF[15:0]),
+        .rOPC_OF                       (rOPC_OF[5:0]),
+        .rRA_OF                        (rRA_OF[4:0]),
+        .rRD_OF                        (rRD_OF[4:0]),
+        .rRD_EX                        (rRD_EX[4:0]),
+        .rRD_MA                        (rRD_MA[4:0]),
+        .rOPD_EX                       (rOPD_EX[2:0]),
+        .rOPD_MA                       (rOPD_MA[2:0]),
+        .rALU_OF                       (rALU_OF[2:0]),
+        // Inputs
+        .rRES_EX                       (rRES_EX[31:0]),
+        .rREGD_OF                      (rREGD_OF[31:0]),
+        .rREGA_OF                      (rREGA_OF[31:0]),
+        .rREGB_OF                      (rREGB_OF[31:0]),
+        .rBRA                          (rBRA[1:0]),
+        .rXCE                          (rXCE),
+        .rINT                          (rINT),
+        .rPC_IF                        (rPC_IF[31:2]),
+        .rIMM_IF                       (rIMM_IF[15:0]),
+        .rALT_IF                       (rALT_IF[10:0]),
+        .rOPC_IF                       (rOPC_IF[5:0]),
+        .rRA_IF                        (rRA_IF[4:0]),
+        .rRB_IF                        (rRB_IF[4:0]),
+        .rRD_IF                        (rRD_IF[4:0]),
+        .pha_i                         (pha_i),
+        .clk_i                         (clk_i),
+        .rst_i                         (rst_i),
+        .ena_i                         (ena_i));   
+   
+   
+   /* Arithmetic Shift Logic Unit */
+
+   aeMB2_aslu
+     #(/*AUTOINSTPARAM*/
+       // Parameters
+       .DWB                            (DWB),
+       .TXE                            (TXE),
+       .MUL                            (MUL),
+       .BSF                            (BSF),
+       .FSL                            (FSL))     
+   aslu (/*AUTOINST*/
+        // Outputs
+        .dwb_adr_o                     (dwb_adr_o[DWB-1:2]),
+        .dwb_sel_o                     (dwb_sel_o[3:0]),
+        .rSEL_MA                       (rSEL_MA[3:0]),
+        .cwb_adr_o                     (cwb_adr_o[6:2]),
+        .cwb_tga_o                     (cwb_tga_o[1:0]),
+        .cwb_sel_o                     (cwb_sel_o[3:0]),
+        .iwb_tga_o                     (iwb_tga_o),
+        .dwb_tga_o                     (dwb_tga_o),
+        .rMUL_MA                       (rMUL_MA[31:0]),
+        .rRES_MA                       (rRES_MA[31:0]),
+        .rRES_EX                       (rRES_EX[31:0]),
+        .rMSR_IE                       (rMSR_IE),
+        .rMSR_BE                       (rMSR_BE),
+        .rMSR_BIP                      (rMSR_BIP),
+        // Inputs
+        .rIMM_OF                       (rIMM_OF[15:0]),
+        .rALU_OF                       (rALU_OF[2:0]),
+        .rOPC_OF                       (rOPC_OF[5:0]),
+        .rOPC_IF                       (rOPC_IF[5:0]),
+        .rRA_OF                        (rRA_OF[4:0]),
+        .rRD_OF                        (rRD_OF[4:0]),
+        .rOPA_OF                       (rOPA_OF[31:0]),
+        .rOPB_OF                       (rOPB_OF[31:0]),
+        .pha_i                         (pha_i),
+        .clk_i                         (clk_i),
+        .rst_i                         (rst_i),
+        .ena_i                         (ena_i));
+
+      
+endmodule // aeMB2_edk32
+
+/* $Log: aeMB2_edk32.v,v $
+/* Revision 1.8  2007/12/18 18:54:36  sybreon
+/* Partitioned simulation model.
+/*
+/* Revision 1.7  2007/12/17 12:53:13  sybreon
+/* Changed simulation kernel.
+/*
+/* Revision 1.6  2007/12/16 03:25:22  sybreon
+/* Replaced OF/ID blocks with combined block.
+/*
+/* Revision 1.5  2007/12/13 21:25:41  sybreon
+/* Further optimisations (speed + size).
+/*
+/* Revision 1.4  2007/12/13 20:12:11  sybreon
+/* Code cleanup + minor speed regression.
+/*
+/* Revision 1.3  2007/12/12 19:16:59  sybreon
+/* Minor optimisations (~10% faster)
+/*
+/* Revision 1.2  2007/12/11 00:43:17  sybreon
+/* initial import
+/*
+/* Revision 1.1  2007/12/07 18:58:51  sybreon
+/* initial
+/* */
\ No newline at end of file

Added: usrp2/trunk/fpga/opencores/aemb/rtl/verilog/aeMB2_idmx.v
===================================================================
--- usrp2/trunk/fpga/opencores/aemb/rtl/verilog/aeMB2_idmx.v                    
        (rev 0)
+++ usrp2/trunk/fpga/opencores/aemb/rtl/verilog/aeMB2_idmx.v    2008-01-04 
20:32:38 UTC (rev 7343)
@@ -0,0 +1,252 @@
+/* $Id: aeMB2_idmx.v,v 1.5 2007/12/16 03:25:02 sybreon Exp $
+**
+** AEMB2 INSTRUCTION DECODE MUX
+** 
+** Copyright (C) 2004-2007 Shawn Tan Ser Ngiap <address@hidden>
+**  
+** This file is part of AEMB.
+**
+** AEMB is free software: you can redistribute it and/or modify it
+** under the terms of the GNU Lesser General Public License as
+** published by the Free Software Foundation, either version 3 of the
+** License, or (at your option) any later version.
+**
+** AEMB is distributed in the hope that it will be useful, but WITHOUT
+** ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+** or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General
+** Public License for more details.
+**
+** You should have received a copy of the GNU Lesser General Public
+** License along with AEMB. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+module aeMB2_idmx (/*AUTOARG*/
+   // Outputs
+   rIMM_OF, rOPC_OF, rRA_OF, rRD_OF, rRD_EX, rRD_MA, rOPD_EX, rOPD_MA,
+   rALU_OF,
+   // Inputs
+   rBRA, rXCE, rINT, rIMM_IF, rALT_IF, rOPC_IF, rRA_IF, rRB_IF,
+   rRD_IF, pha_i, clk_i, rst_i, ena_i
+   );
+   parameter TXE = 1;
+   
+   parameter MUL = 1;
+   parameter BSF = 1;
+   parameter FSL = 1;   
+   
+   output [15:0] rIMM_OF;
+   output [5:0]  rOPC_OF;
+   output [4:0]  rRA_OF,
+                rRD_OF;
+   
+   output [4:0]  rRD_EX,  
+                rRD_MA;   
+   output [2:0]  rOPD_EX,
+                rOPD_MA;
+   
+   output [2:0]  rALU_OF; // addsub, logic, bshift, sext, mul, mov, ldst
+
+   
+   input [1:0]          rBRA;
+   input        rXCE,
+                //rMSR_TXE,
+                rINT;
+   
+   input [15:0]  rIMM_IF;
+   input [10:0]  rALT_IF;   
+   input [5:0]          rOPC_IF;
+   input [4:0]          rRA_IF,
+                rRB_IF,
+                rRD_IF;
+   
+   input        pha_i,
+                clk_i,
+                rst_i,
+                ena_i;   
+   
+   /*AUTOREG*/
+   // Beginning of automatic regs (for this module's undeclared outputs)
+   reg [2:0]           rALU_OF;
+   reg [15:0]          rIMM_OF;
+   reg [5:0]           rOPC_OF;
+   reg [2:0]           rOPD_EX;
+   reg [2:0]           rOPD_MA;
+   reg [4:0]           rRA_OF;
+   reg [4:0]           rRD_EX;
+   reg [4:0]           rRD_MA;
+   reg [4:0]           rRD_OF;
+   // End of automatics
+
+   //wire [31:0]               wXCEOP = 32'hBA2D0020; // Vector 0x20
+   wire [31:0]                 wINTOP = 32'hB9CE0010; // Vector 0x10   
+   wire [31:0]                 wNOPOP = 32'h88000000; // branch-no-delay/stall
+   
+   /* Partial decoding */
+   wire [5:0]          rOPC = rOPC_IF;
+   wire [4:0]          rRA = rRA_IF;
+   wire [4:0]          rRB = rRB_IF;   
+   wire                fSFT = (rOPC == 6'o44);
+   wire                fLOG = ({rOPC[5:4],rOPC[2]} == 3'o4);      
+   wire                fMUL = (rOPC == 6'o20) | (rOPC == 6'o30);
+   wire                fBSF = (rOPC == 6'o21) | (rOPC == 6'o31);
+   wire                fDIV = (rOPC == 6'o22);   
+   wire                fRTD = (rOPC == 6'o55);
+   wire                fBCC = (rOPC == 6'o47) | (rOPC == 6'o57);
+   wire                fBRU = (rOPC == 6'o46) | (rOPC == 6'o56);
+   wire                fBRA = fBRU & rRA[3];      
+   wire                fIMM = (rOPC == 6'o54);
+   wire                fMOV = (rOPC == 6'o45);      
+   wire                fLOD = ({rOPC[5:4],rOPC[2]} == 3'o6);
+   wire                fSTR = ({rOPC[5:4],rOPC[2]} == 3'o7);
+   wire                fLDST = (rOPC[5:4] == 2'o3);      
+   wire                fPUT = (rOPC == 6'o33) & rRB[4];
+   wire                fGET = (rOPC == 6'o33) & !rRB[4];
+   
+   /* Hazard detection */
+
+   wire                fLOAD = (rOPD_EX == 3'o2);
+   wire                fMULT = (rOPD_EX == 3'o3);
+   wire                fWRE = |rRD_EX;   
+   wire                fOPBHZD = (rRB_IF == rRD_EX) & (fLOAD | fMULT) & !fMOV 
& !rOPC_IF[3] & fWRE;
+   wire                fOPAHZD = (rRA_IF == rRD_EX) & (fLOAD | fMULT) & !fBRU 
& fWRE;
+   wire                fOPDHZD = (rRD_IF == rRD_EX) & (fLOAD | fMULT) & fSTR & 
fWRE;   
+   wire                fHAZARD = fOPBHZD | fOPAHZD | fOPDHZD;
+   
+   wire                fSKIP = (rBRA == 2'o2) | // non-delay branch
+                       !(TXE | pha_i) |
+                       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 */
+   
+   always @(posedge clk_i)
+     if (rst_i) begin
+       /*AUTORESET*/
+       // Beginning of autoreset for uninitialized flops
+       rALU_OF <= 3'h0;
+       // End of automatics
+     end else if (ena_i) begin
+       /*
+       rALU_OF <= #1
+                  (fSKIP) ? 3'o1 : // NOP
+                  (fBRA | fMOV) ? 3'o3 :
+                  (fSFT) ? 3'o2 :
+                  (fLOG) ? 3'o1 :
+                  (fMUL) ? 3'o4 :
+                  (fBSF) ? 3'o5 :
+                  3'o0;        
+        */
+       rALU_OF <= #1
+                  (fSKIP) ? 3'o2 : // NOP
+                  (fBRA | fMOV) ? 3'o2 :
+                  (fSFT) ? 3'o2 :
+                  (fLOG) ? 3'o2 :
+                  (fBSF) ? 3'o1 :
+                  3'o0;        
+     end // if (ena_i)
+
+   /* WB Selector */
+
+   reg [2:0] rOPD_OF;
+   
+   always @(posedge clk_i)
+     if (rst_i) begin
+       /*AUTORESET*/
+       // Beginning of autoreset for uninitialized flops
+       rOPD_EX <= 3'h0;
+       rOPD_MA <= 3'h0;
+       rOPD_OF <= 3'h0;
+       // End of automatics
+     end else if (ena_i) begin
+       rOPD_MA <= #1 rOPD_EX;  
+       rOPD_EX <= #1 rOPD_OF;  
+       rOPD_OF <= #1
+                  (fSKIP) ? 3'o7: // NOP
+                  (fSTR | fRTD | fBCC) ? 3'o7 : // STR/RTD/BCC            
+                  (fLOD | fGET) ? 3'o2 : // RAM/FSL
+                  (fBRU) ? 3'o1 : // PCLNK
+                  (fMUL) ? 3'o3 : // MUL
+                  (|rRD_IF) ? 3'o0 : // ALU
+                  3'o7; // NOP
+     end // if (ena_i)
+
+
+
+   // 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)
+     if (rst_i) begin
+       /*AUTORESET*/
+       // Beginning of autoreset for uninitialized flops
+       rIMM_OF <= 16'h0;
+       rOPC_OF <= 6'h0;
+       rRA_OF <= 5'h0;
+       rRD_EX <= 5'h0;
+       rRD_MA <= 5'h0;
+       rRD_OF <= 5'h0;
+       // End of automatics
+     end else if (ena_i) begin // if (rst_i)
+       rRD_MA <= #1 rRD_EX;
+       rRD_EX <= #1 rRD_OF;    
+       
+       // TODO: Interrrupt
+       case ({fINT, fSKIP})
+         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'o3,
+         2'o2: {rOPC_OF, rRD_OF, rRA_OF, rIMM_OF} <= #1 wINTOP; // interrupt
+         default: {rOPC_OF, rRD_OF, rRA_OF} <= #1 16'hX;         
+       endcase // case (fSKIP)
+       
+     end // if (ena_i)
+   
+endmodule // aeMB2_idmx
+
+/* $Log: aeMB2_idmx.v,v $
+/* Revision 1.5  2007/12/16 03:25:02  sybreon
+/* Added interrupt support.
+/*
+/* Revision 1.4  2007/12/13 21:25:41  sybreon
+/* Further optimisations (speed + size).
+/*
+/* Revision 1.3  2007/12/13 20:12:11  sybreon
+/* Code cleanup + minor speed regression.
+/*
+/* Revision 1.2  2007/12/12 19:16:59  sybreon
+/* Minor optimisations (~10% faster)
+/*
+/* Revision 1.1  2007/12/11 00:43:17  sybreon
+/* initial import
+/* */
\ No newline at end of file

Added: usrp2/trunk/fpga/opencores/aemb/rtl/verilog/aeMB2_ofid.v
===================================================================
--- usrp2/trunk/fpga/opencores/aemb/rtl/verilog/aeMB2_ofid.v                    
        (rev 0)
+++ usrp2/trunk/fpga/opencores/aemb/rtl/verilog/aeMB2_ofid.v    2008-01-04 
20:32:38 UTC (rev 7343)
@@ -0,0 +1,337 @@
+/* $Id: aeMB2_ofid.v,v 1.2 2007/12/16 20:38:06 sybreon Exp $
+**
+** AEMB2 COMBINED OPERAND FETCH & INSTRUCTION DECODE
+** 
+** Copyright (C) 2004-2007 Shawn Tan Ser Ngiap <address@hidden>
+**  
+** This file is part of AEMB.
+**
+** AEMB is free software: you can redistribute it and/or modify it
+** under the terms of the GNU Lesser General Public License as
+** published by the Free Software Foundation, either version 3 of the
+** License, or (at your option) any later version.
+**
+** AEMB is distributed in the hope that it will be useful, but WITHOUT
+** ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+** or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General
+** Public License for more details.
+**
+** You should have received a copy of the GNU Lesser General Public
+** License along with AEMB. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+module aeMB2_ofid (/*AUTOARG*/
+   // Outputs
+   rOPM_OF, rOPX_OF, rOPA_OF, rOPB_OF, rIMM_OF, rOPC_OF, rRA_OF,
+   rRD_OF, rRD_EX, rRD_MA, rOPD_EX, rOPD_MA, rALU_OF,
+   // Inputs
+   rRES_EX, rREGD_OF, rREGA_OF, rREGB_OF, rBRA, rXCE, rINT, rPC_IF,
+   rIMM_IF, rALT_IF, rOPC_IF, rRA_IF, rRB_IF, rRD_IF, pha_i, clk_i,
+   rst_i, ena_i
+   );
+   parameter TXE = 1;
+   
+   parameter MUL = 1;
+   parameter BSF = 1;
+   parameter FSL = 1;   
+
+   output [31:0] rOPM_OF, // used for store
+                rOPX_OF, // used for BCC checking
+                rOPA_OF, // OPA as per ISA
+                rOPB_OF; // OPB as per ISA
+   
+   output [15:0] rIMM_OF;
+   output [5:0]  rOPC_OF;
+   output [4:0]  rRA_OF,
+                rRD_OF;
+   
+   output [4:0]  rRD_EX,  
+                rRD_MA;   
+   output [2:0]  rOPD_EX,
+                rOPD_MA;
+   
+   output [2:0]  rALU_OF; // addsub, logic, bshift, sext, mul, mov, ldst
+
+
+   input [31:0]  rRES_EX;
+
+   
+   input [31:0]  rREGD_OF,
+                rREGA_OF,
+                rREGB_OF;
+   
+   input [1:0]          rBRA;
+   input        rXCE,
+                rINT;
+   
+   input [31:2]  rPC_IF;   
+   input [15:0]  rIMM_IF;
+   input [10:0]  rALT_IF;   
+   input [5:0]          rOPC_IF;
+   input [4:0]          rRA_IF,
+                rRB_IF,
+                rRD_IF;
+   
+   input        pha_i,
+                clk_i,
+                rst_i,
+                ena_i;   
+
+   /*AUTOREG*/
+   // Beginning of automatic regs (for this module's undeclared outputs)
+   reg [2:0]           rALU_OF;
+   reg [15:0]          rIMM_OF;
+   reg [31:0]          rOPA_OF;
+   reg [31:0]          rOPB_OF;
+   reg [5:0]           rOPC_OF;
+   reg [2:0]           rOPD_EX;
+   reg [2:0]           rOPD_MA;
+   reg [31:0]          rOPM_OF;
+   reg [31:0]          rOPX_OF;
+   reg [4:0]           rRA_OF;
+   reg [4:0]           rRD_EX;
+   reg [4:0]           rRD_MA;
+   reg [4:0]           rRD_OF;
+   // End of automatics
+
+   wire [31:0]                 wXCEOP = 32'hBA2D0020; // Vector 0x20
+   wire [31:0]                 wINTOP = 32'hB9CE0010; // Vector 0x10   
+   wire [31:0]                 wNOPOP = 32'h88000000; // branch-no-delay/stall
+      
+   wire                fSKP = (rBRA == 2'b10); // branch without delay
+
+   /* Partial decoding */
+   wire [5:0]          rOPC = rOPC_IF;
+   wire [4:0]          rRA = rRA_IF;
+   wire [4:0]          rRB = rRB_IF;   
+   wire                fSFT = (rOPC == 6'o44);
+   wire                fLOG = ({rOPC[5:4],rOPC[2]} == 3'o4);      
+   wire                fMUL = (rOPC == 6'o20) | (rOPC == 6'o30);
+   wire                fBSF = (rOPC == 6'o21) | (rOPC == 6'o31);
+   wire                fDIV = (rOPC == 6'o22);   
+   wire                fRTD = (rOPC == 6'o55);
+   wire                fBCC = (rOPC == 6'o47) | (rOPC == 6'o57);
+   wire                fBRU = (rOPC == 6'o46) | (rOPC == 6'o56);
+   wire                fBRA = fBRU & rRA[3];      
+   wire                fIMM = (rOPC == 6'o54);
+   wire                fMOV = (rOPC == 6'o45);      
+   wire                fLOD = ({rOPC[5:4],rOPC[2]} == 3'o6);
+   wire                fSTR = ({rOPC[5:4],rOPC[2]} == 3'o7);
+   wire                fLDST = (rOPC[5:4] == 2'o3);      
+   wire                fPUT = (rOPC == 6'o33) & rRB[4];
+   wire                fGET = (rOPC == 6'o33) & !rRB[4];
+      
+   /* 
+    IMMI TRAP
+    
+    This executes the IMMI instruction in the OF stage. This is not a
+    problem if the flow doesn't get interrupted. */
+   
+   reg [15:0]          rIMM0, rIMM1, rIMML[0:1];
+   reg                         rFIM0, rFIM1, rFIML[0:1];
+   wire [15:0]                 wIMM = rIMML[!pha_i];
+   wire [31:0]                 wSIMM;
+
+   wire                rFIM = (pha_i) ? rFIM0 : rFIM1;   
+   wire [15:0]                 rIMM = (pha_i) ? rIMM0 : rIMM1;
+   
+   assign              wSIMM[15:0] = rIMM_IF[15:0];   
+   assign              wSIMM[31:16] = (rFIM) ? 
+                                      {rIMM} : 
+                                      {(16){rIMM_IF[15]}};
+   
+   always @(posedge clk_i)
+     if (rst_i) begin
+       /*AUTORESET*/
+       // Beginning of autoreset for uninitialized flops
+       rFIM0 <= 1'h0;
+       rFIM1 <= 1'h0;
+       rIMM0 <= 16'h0;
+       rIMM1 <= 16'h0;
+       // End of automatics
+     end else if (ena_i) begin
+       if (pha_i) begin  
+          rFIM0 <= #1 fIMM & !fSKP;
+          rIMM0 <= #1 rIMM_IF;
+       end else begin
+          rFIM1 <= #1 fIMM & !fSKP;
+          rIMM1 <= #1 rIMM_IF;
+       end
+     end // else: !if(rst_i)
+
+   /*
+    IINTERCEPT FLAG
+    
+    Presently, only interrupts are intercepted. There is no reason why
+    it would be difficult to intercept exceptions in the same manner. 
+    
+    All interrupts are presently handled by T0 to simplify software
+    synchronisation and compatibility with single threaded apps. There
+    isn't a reason why it needs to stay this way if things change. */
+
+   wire fINT =!rFIM & !rBRA[1] & rINT & pha_i;
+   
+   /* Latch onto the operand */
+   // TODO: Optimise
+   
+   wire                fALU = (rOPD_EX == 3'o0);
+   wire                fOWRE = |rRD_EX;
+   wire                wOPBFWD = !rOPC_IF[3] & (rRB_IF == rRD_EX) & fALU & 
!fMOV & fOWRE;
+   wire                wOPAFWD = !(fBRU|fBCC) & (rRA_IF == rRD_EX) & fALU & 
fOWRE;
+   wire                wOPXFWD = (fBCC) & (rRA_IF == rRD_EX) & fALU & fOWRE;   
+   wire                wOPMFWD = (rRD_IF == rRD_EX) & fALU & fOWRE;   
+   
+   wire [1:0]          wOPB_MX = {rOPC_IF[3]|fINT, wOPBFWD|fINT};
+   wire [1:0]          wOPA_MX = {fBRU|fBCC| (fMOV & !rRB[3]) , wOPAFWD};
+   wire [1:0]          wOPX_MX = {fBCC, wOPXFWD};   
+   wire [1:0]          wOPM_MX = {fSTR, wOPMFWD};   
+   
+   always @(posedge clk_i)
+     if (rst_i) begin
+       /*AUTORESET*/
+       // Beginning of autoreset for uninitialized flops
+       rOPA_OF <= 32'h0;
+       rOPB_OF <= 32'h0;
+       rOPM_OF <= 32'h0;
+       rOPX_OF <= 32'h0;
+       // End of automatics
+     end else if (ena_i) begin
+
+       case (wOPX_MX)
+         // BCC
+         2'o2: rOPX_OF <= #1 rREGA_OF; // reg  
+         2'o3: rOPX_OF <= #1 rRES_EX; // forward
+         default: rOPX_OF <= #1 32'hX;   
+       endcase // case (wOPX_MX)
+
+       case (wOPM_MX)
+         2'o2: rOPM_OF <= #1 rREGD_OF; // reg
+         2'o3: rOPM_OF <= #1 rRES_EX; // forward
+         default: rOPM_OF <= #1 32'hX;   
+       endcase // case (wOPM_MX)
+       
+       // OP B
+       case (wOPB_MX)
+         2'o0: rOPB_OF <= #1 rREGB_OF; // reg
+         2'o1: rOPB_OF <= #1 rRES_EX; // forward
+         2'o2: rOPB_OF <= #1 wSIMM; // immediate
+         2'o3: rOPB_OF <= #1 { {(16){1'b0}}, wINTOP[15:0] };
+         default: rOPB_OF <= #1 32'hX;   
+       endcase // case (wOPB_MX)
+       
+       case (wOPA_MX)
+         2'o0: rOPA_OF <= #1 rREGA_OF; // reg
+         2'o1: rOPA_OF <= #1 rRES_EX; // forward
+         2'o2: rOPA_OF <= #1 {rPC_IF, 2'd0}; // pc 
+         default: rOPA_OF <= #1 32'hX;   
+       endcase // case (wOPA_MX)
+
+     end // if (ena_i)
+      
+   /* Hazard detection */
+
+   wire                fLOAD = (rOPD_EX == 3'o2);
+   wire                fMULT = (rOPD_EX == 3'o3);
+   wire                fWRE = |rRD_EX;   
+   wire                fOPBHZD = (rRB_IF == rRD_EX) & (fLOAD | fMULT) & !fMOV 
& !rOPC_IF[3] & fWRE;
+   wire                fOPAHZD = (rRA_IF == rRD_EX) & (fLOAD | fMULT) & !fBRU 
& fWRE;
+   wire                fOPDHZD = (rRD_IF == rRD_EX) & (fLOAD | fMULT) & fSTR & 
fWRE;   
+   wire                fHAZARD = fOPBHZD | fOPAHZD | fOPDHZD;
+   
+   wire                fSKIP = (rBRA == 2'o2) | // non-delay branch
+                       !(TXE | pha_i) | // disabled thread
+                       fOPBHZD | fOPAHZD; // hazards
+      
+   /* ALU Selector */
+   
+   always @(posedge clk_i)
+     if (rst_i) begin
+       /*AUTORESET*/
+       // Beginning of autoreset for uninitialized flops
+       rALU_OF <= 3'h0;
+       // End of automatics
+     end else if (ena_i) begin
+       /*
+       rALU_OF <= #1
+                  (fSKIP) ? 3'o1 : // NOP
+                  (fBRA | fMOV) ? 3'o3 :
+                  (fSFT) ? 3'o2 :
+                  (fLOG) ? 3'o1 :
+                  (fMUL) ? 3'o4 :
+                  (fBSF) ? 3'o5 :
+                  3'o0;        
+        */
+       rALU_OF <= #1
+                  (fINT) ? 3'o2 :
+                  (fSKIP) ? 3'o2 : // NOP
+                  (fBRA | fMOV) ? 3'o2 :
+                  (fSFT) ? 3'o2 :
+                  (fLOG) ? 3'o2 :
+                  (fBSF) ? 3'o1 :
+                  3'o0;        
+     end // if (ena_i)
+
+   /* WB Selector */
+
+   reg [2:0] rOPD_OF;
+   
+   always @(posedge clk_i)
+     if (rst_i) begin
+       /*AUTORESET*/
+       // Beginning of autoreset for uninitialized flops
+       rOPD_EX <= 3'h0;
+       rOPD_MA <= 3'h0;
+       rOPD_OF <= 3'h0;
+       // End of automatics
+     end else if (ena_i) begin
+       rOPD_MA <= #1 rOPD_EX;  
+       rOPD_EX <= #1 rOPD_OF;  
+       rOPD_OF <= #1
+                  (fINT) ? 3'o1 :
+                  (fSKIP) ? 3'o7: // NOP
+                  (fSTR | fRTD | fBCC) ? 3'o7 : // STR/RTD/BCC            
+                  (fLOD | fGET) ? 3'o2 : // RAM/FSL
+                  (fBRU) ? 3'o1 : // PCLNK
+                  (fMUL) ? 3'o3 : // MUL
+                  (|rRD_IF) ? 3'o0 : // ALU
+                  3'o7; // NOP
+     end // if (ena_i)
+
+   /* Pass Through */
+   
+   always @(posedge clk_i)
+     if (rst_i) begin
+       /*AUTORESET*/
+       // Beginning of autoreset for uninitialized flops
+       rIMM_OF <= 16'h0;
+       rOPC_OF <= 6'h0;
+       rRA_OF <= 5'h0;
+       rRD_EX <= 5'h0;
+       rRD_MA <= 5'h0;
+       rRD_OF <= 5'h0;
+       // End of automatics
+     end else if (ena_i) begin // if (rst_i)
+       rRD_MA <= #1 rRD_EX;
+       rRD_EX <= #1 rRD_OF;    
+       
+       // TODO: Interrrupt
+       case ({fINT, fSKIP})
+         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'o3,
+         2'o2: {rOPC_OF, rRD_OF, rRA_OF, rIMM_OF} <= #1 wINTOP; // interrupt
+         default: {rOPC_OF, rRD_OF, rRA_OF} <= #1 16'hX;         
+       endcase // case (fSKIP)
+       
+     end // if (ena_i)
+   
+
+endmodule // aeMB2_ofid
+
+/* $Log: aeMB2_ofid.v,v $
+/* Revision 1.2  2007/12/16 20:38:06  sybreon
+/* Minor optimisations.
+/*
+/* Revision 1.1  2007/12/16 03:24:20  sybreon
+/* Combined ID/OF blocks.
+/* */
\ No newline at end of file

Added: usrp2/trunk/fpga/opencores/aemb/rtl/verilog/aeMB2_opmx.v
===================================================================
--- usrp2/trunk/fpga/opencores/aemb/rtl/verilog/aeMB2_opmx.v                    
        (rev 0)
+++ usrp2/trunk/fpga/opencores/aemb/rtl/verilog/aeMB2_opmx.v    2008-01-04 
20:32:38 UTC (rev 7343)
@@ -0,0 +1,193 @@
+/* $Id: aeMB2_opmx.v,v 1.3 2007/12/13 20:12:11 sybreon Exp $
+**
+** AEMB2 OPERAND FETCH MUX
+** 
+** Copyright (C) 2004-2007 Shawn Tan Ser Ngiap <address@hidden>
+**  
+** This file is part of AEMB.
+**
+** AEMB is free software: you can redistribute it and/or modify it
+** under the terms of the GNU Lesser General Public License as
+** published by the Free Software Foundation, either version 3 of the
+** License, or (at your option) any later version.
+**
+** AEMB is distributed in the hope that it will be useful, but WITHOUT
+** ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+** or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General
+** Public License for more details.
+**
+** You should have received a copy of the GNU Lesser General Public
+** License along with AEMB. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+module aeMB2_opmx (/*AUTOARG*/
+   // Outputs
+   rOPM_OF, rOPX_OF, rOPA_OF, rOPB_OF,
+   // Inputs
+   rRES_EX, rRD_EX, rOPD_EX, rOPC_IF, rIMM_IF, rPC_IF, rRD_IF, rRA_IF,
+   rRB_IF, rREGD_OF, rREGA_OF, rREGB_OF, rBRA, pha_i, clk_i, rst_i,
+   ena_i
+   );
+   parameter TXE = 1;   
+
+   output [31:0] rOPM_OF, // used for store
+                rOPX_OF, // used for BCC checking
+                rOPA_OF, // OPA as per ISA
+                rOPB_OF; // OPB as per ISA
+
+   input [31:0]  rRES_EX;
+   input [4:0]          rRD_EX;
+   input [1:0]          rOPD_EX;   
+   
+   input [5:0]          rOPC_IF;
+   input [15:0]  rIMM_IF;
+   input [31:2]  rPC_IF;   
+   input [4:0]          rRD_IF,
+                rRA_IF,
+                rRB_IF;
+   
+   input [31:0]  rREGD_OF,
+                rREGA_OF,
+                rREGB_OF;
+
+   input [1:0]          rBRA;  
+   
+   // SYSTEM
+   input        pha_i,
+                clk_i,
+                rst_i,
+                ena_i;
+
+   /*AUTOREG*/
+   // Beginning of automatic regs (for this module's undeclared outputs)
+   reg [31:0]          rOPA_OF;
+   reg [31:0]          rOPB_OF;
+   reg [31:0]          rOPM_OF;
+   reg [31:0]          rOPX_OF;
+   // End of automatics
+
+   wire                fSKP = (rBRA == 2'b10); // branch without delay
+
+   /* Partial decoding */
+   wire [5:0]          rOPC = rOPC_IF;
+   wire [4:0]          rRA = rRA_IF;
+   wire [4:0]          rRB = rRB_IF;   
+   wire                fSFT = (rOPC == 6'o44);
+   wire                fLOG = ({rOPC[5:4],rOPC[2]} == 3'o4);      
+   wire                fMUL = (rOPC == 6'o20) | (rOPC == 6'o30);
+   wire                fBSF = (rOPC == 6'o21) | (rOPC == 6'o31);
+   wire                fDIV = (rOPC == 6'o22);   
+   wire                fRTD = (rOPC == 6'o55);
+   wire                fBCC = (rOPC == 6'o47) | (rOPC == 6'o57);
+   wire                fBRU = (rOPC == 6'o46) | (rOPC == 6'o56);
+   wire                fBRA = fBRU & rRA[3];      
+   wire                fIMM = (rOPC == 6'o54);
+   wire                fMOV = (rOPC == 6'o45);      
+   wire                fLOD = ({rOPC[5:4],rOPC[2]} == 3'o6);
+   wire                fSTR = ({rOPC[5:4],rOPC[2]} == 3'o7);
+   wire                fLDST = (rOPC[5:4] == 2'o3);      
+   wire                fPUT = (rOPC == 6'o33) & rRB[4];
+   wire                fGET = (rOPC == 6'o33) & !rRB[4];
+      
+   /* IMMI implementation */
+   
+   reg [15:0]          rIMM0, rIMM1, rIMML[0:1];
+   reg                         rFIM0, rFIM1, rFIML[0:1];
+   wire [15:0]                 wIMM = rIMML[!pha_i];
+   wire [31:0]                 wSIMM;
+
+   wire                rFIM = (pha_i) ? rFIM0 : rFIM1;   
+   wire [15:0]                 rIMM = (pha_i) ? rIMM0 : rIMM1;
+   
+   assign              wSIMM[15:0] = rIMM_IF[15:0];   
+   assign              wSIMM[31:16] = (rFIM) ? 
+                                      {rIMM} : 
+                                      {(16){rIMM_IF[15]}};
+   
+   always @(posedge clk_i)
+     if (rst_i) begin
+       /*AUTORESET*/
+       // Beginning of autoreset for uninitialized flops
+       rFIM0 <= 1'h0;
+       rFIM1 <= 1'h0;
+       rIMM0 <= 16'h0;
+       rIMM1 <= 16'h0;
+       // End of automatics
+     end else if (ena_i) begin
+       if (pha_i) begin  
+          rFIM0 <= #1 fIMM & !fSKP;
+          rIMM0 <= #1 rIMM_IF;
+       end else begin
+          rFIM1 <= #1 fIMM & !fSKP;
+          rIMM1 <= #1 rIMM_IF;
+       end
+     end // else: !if(rst_i)
+   
+   /* Latch onto the operand */
+   // TODO: Optimise
+   
+   wire                fALU = (rOPD_EX == 3'o0);
+   wire                fWRE = |rRD_EX;
+   wire                wOPBFWD = !rOPC_IF[3] & (rRB_IF == rRD_EX) & fALU & 
!fMOV & fWRE;
+   wire                wOPAFWD = !(fBRU|fBCC) & (rRA_IF == rRD_EX) & fALU & 
fWRE;
+   wire                wOPXFWD = (fBCC) & (rRA_IF == rRD_EX) & fALU & fWRE;   
+   wire                wOPMFWD = (rRD_IF == rRD_EX) & fALU & fWRE;   
+   
+   wire [1:0]          wOPB_MX = {rOPC_IF[3], wOPBFWD};
+   wire [1:0]          wOPA_MX = {fBRU|fBCC| (fMOV & !rRB[3]) , wOPAFWD};
+   wire [1:0]          wOPX_MX = {fBCC, wOPXFWD};   
+   wire [1:0]          wOPM_MX = {fSTR, wOPMFWD};   
+   
+   always @(posedge clk_i)
+     if (rst_i) begin
+       /*AUTORESET*/
+       // Beginning of autoreset for uninitialized flops
+       rOPA_OF <= 32'h0;
+       rOPB_OF <= 32'h0;
+       rOPM_OF <= 32'h0;
+       rOPX_OF <= 32'h0;
+       // End of automatics
+     end else if (ena_i) begin
+
+       case (wOPX_MX)
+         // BCC
+         2'o2: rOPX_OF <= #1 rREGA_OF; // reg  
+         2'o3: rOPX_OF <= #1 rRES_EX; // forward
+         default: rOPX_OF <= #1 32'hX;   
+       endcase // case (wOPX_MX)
+
+       case (wOPM_MX)
+         2'o2: rOPM_OF <= #1 rREGD_OF; // reg
+         2'o3: rOPM_OF <= #1 rRES_EX; // forward
+         default: rOPM_OF <= #1 32'hX;   
+       endcase // case (wOPM_MX)
+       
+       // OP B
+       case (wOPB_MX)
+         2'o0: rOPB_OF <= #1 rREGB_OF; // reg
+         2'o1: rOPB_OF <= #1 rRES_EX; // forward
+         2'o2: rOPB_OF <= #1 wSIMM; // immediate
+         default: rOPB_OF <= #1 32'hX;   
+       endcase // case (wOPB_MX)
+       
+       case (wOPA_MX)
+         2'o0: rOPA_OF <= #1 rREGA_OF; // reg
+         2'o1: rOPA_OF <= #1 rRES_EX; // forward
+         2'o2: rOPA_OF <= #1 {rPC_IF, 2'd0}; // pc 
+         default: rOPA_OF <= #1 32'hX;   
+       endcase // case (wOPA_MX)
+
+     end // if (ena_i)
+   
+endmodule // aeMB2_opmx
+
+/* $Log: aeMB2_opmx.v,v $
+/* Revision 1.3  2007/12/13 20:12:11  sybreon
+/* Code cleanup + minor speed regression.
+/*
+/* Revision 1.2  2007/12/12 19:16:59  sybreon
+/* Minor optimisations (~10% faster)
+/*
+/* Revision 1.1  2007/12/11 00:43:17  sybreon
+/* initial import
+/* */
\ No newline at end of file

Added: usrp2/trunk/fpga/opencores/aemb/rtl/verilog/aeMB2_regf.v
===================================================================
--- usrp2/trunk/fpga/opencores/aemb/rtl/verilog/aeMB2_regf.v                    
        (rev 0)
+++ usrp2/trunk/fpga/opencores/aemb/rtl/verilog/aeMB2_regf.v    2008-01-04 
20:32:38 UTC (rev 7343)
@@ -0,0 +1,224 @@
+/* $Id: aeMB2_regf.v,v 1.3 2007/12/13 20:12:11 sybreon Exp $
+**
+** AEMB2 REGISTER FILE
+** 
+** Copyright (C) 2004-2007 Shawn Tan Ser Ngiap <address@hidden>
+**  
+** This file is part of AEMB.
+**
+** AEMB is free software: you can redistribute it and/or modify it
+** under the terms of the GNU Lesser General Public License as
+** published by the Free Software Foundation, either version 3 of the
+** License, or (at your option) any later version.
+**
+** AEMB is distributed in the hope that it will be useful, but WITHOUT
+** ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+** or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General
+** Public License for more details.
+**
+** You should have received a copy of the GNU Lesser General Public
+** License along with AEMB. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+module aeMB2_regf (/*AUTOARG*/
+   // Outputs
+   dwb_dat_o, cwb_dat_o, rREGD_OF, rREGA_OF, rREGB_OF,
+   // Inputs
+   dwb_dat_i, dwb_ack_i, cwb_dat_i, cwb_ack_i, rRA_IF, rRB_IF, rRD_IF,
+   rRD_MA, rOPM_OF, rOPA_OF, rOPC_OF, rPC_MA, rMUL_MA, rRES_MA,
+   rOPD_MA, rSEL_MA, clk_i, rst_i, ena_i, pha_i
+   );
+   parameter TXE = 1;
+   parameter MUL = 1;   
+   
+   // DWB
+   output [31:0] dwb_dat_o;
+   input [31:0]  dwb_dat_i;
+   input        dwb_ack_i;   
+   
+   // FSL
+   output [31:0] cwb_dat_o;   
+   input [31:0]  cwb_dat_i;
+   input        cwb_ack_i;   
+   
+   // INTERNAL
+   output [31:0] rREGD_OF,
+                rREGA_OF,
+                rREGB_OF;   
+
+   input [4:0]          rRA_IF,
+                rRB_IF,
+                rRD_IF,
+                rRD_MA;
+
+   input [31:0]  rOPM_OF;
+   input [31:0]  rOPA_OF;   
+   input [5:0]          rOPC_OF;
+   
+   
+   input [31:2]  rPC_MA; ///< link PC
+   input [31:0]  rMUL_MA; ///< multiplier 2nd stage
+   input [31:0]  rRES_MA;   
+
+   input [2:0]          rOPD_MA;   
+   input [3:0]          rSEL_MA; ///< data select info
+   
+   // SYSTEM
+   input        clk_i, 
+                rst_i, 
+                ena_i, 
+                pha_i;
+
+   /*AUTOREG*/
+   // Beginning of automatic regs (for this module's undeclared outputs)
+   reg [31:0]          cwb_dat_o;
+   reg [31:0]          dwb_dat_o;
+   // End of automatics
+
+
+   /*     
+    LATCH FSL/RAM. 
+    
+    This is done on completion of a bus cycle, regardless of the
+    pipeline status. It's safe to do this as the data is only written
+    to the registers later. */
+   
+   reg [31:0]          rCWB_MA,
+                       rDWB_MA;
+   
+   always @(posedge clk_i)
+     if (rst_i) begin
+       /*AUTORESET*/
+       // Beginning of autoreset for uninitialized flops
+       rCWB_MA <= 32'h0;
+       rDWB_MA <= 32'h0;
+       // End of automatics
+     end else begin
+       if (dwb_ack_i) rDWB_MA <= #1 dwb_dat_i;
+       if (cwb_ack_i) rCWB_MA <= #1 cwb_dat_i; 
+     end
+   
+   /* 
+    LOAD RESIZER 
+    
+    Resize the latched data for writing into the register. It also
+    acts as a selector between FSL and DWB. */
+   
+   reg [31:0]   rMEM;
+   always @(/*AUTOSENSE*/rCWB_MA or rDWB_MA or rSEL_MA) begin
+      case (rSEL_MA)
+       // 8'bits
+       4'h8: rMEM <= {24'd0, rDWB_MA[31:24]};
+       4'h4: rMEM <= {24'd0, rDWB_MA[23:16]};
+       4'h2: rMEM <= {24'd0, rDWB_MA[15:8]};
+       4'h1: rMEM <= {24'd0, rDWB_MA[7:0]};    
+       // 16'bits
+       4'hC: rMEM <= {16'd0, rDWB_MA[31:16]};
+       4'h3: rMEM <= {16'd0, rDWB_MA[15:0]};   
+       // 32'bits
+       4'h0: rMEM <= rCWB_MA;
+       4'hF: rMEM <= rDWB_MA;
+       default: rMEM <= 32'hX; 
+      endcase // case (rSEL_MA)
+   end // always @ (...
+
+   /*
+    WRITE BACK
+    
+    The appropriate data to write into the register file is selected.
+    */
+   
+   wire [31:0] wREGW;   
+   reg [31:0] rREGD;
+   always @(/*AUTOSENSE*/rMEM or rMUL_MA or rOPD_MA or rPC_MA
+           or rRES_MA or wREGW)
+      case (rOPD_MA)
+       3'o0: rREGD <= rRES_MA; // ALU
+       3'o1: rREGD <= {rPC_MA, 2'o0}; // PCLNK
+       3'o2: rREGD <= rMEM; // RAM/FSL
+       3'o3: rREGD <= (MUL) ? rMUL_MA : 32'hX; // Multiplier
+       3'o7: rREGD <= wREGW; // Unchanged
+       default: rREGD <= 32'hX; // Undefined   
+      endcase // case (rOPD_MA)
+
+   /* 
+    REGISTER FILE
+    
+    Multi-banked dual-port register file. This should be inferred as
+    distributed RAM in an FPGA. */
+   
+   reg [31:0]   rRAMA [(32<<TXE)-1:0],
+                rRAMB [(32<<TXE)-1:0],
+                rRAMD [(32<<TXE)-1:0];
+
+   wire [TXE+4:0] wRA = {!pha_i, rRA_IF};
+   wire [TXE+4:0] wRB = {!pha_i, rRB_IF};
+   wire [TXE+4:0] wRD = {!pha_i, rRD_IF};   
+   wire [TXE+4:0] wRW = {pha_i, rRD_MA};   
+   
+   assign       rREGA_OF = rRAMA[wRA];
+   assign       rREGB_OF = rRAMB[wRB];
+   assign       rREGD_OF = rRAMD[wRD];
+   assign       wREGW = rRAMD[wRW];   
+   
+   always @(posedge clk_i)
+     if ((ena_i & |rRD_MA) | rst_i) begin
+       rRAMA[wRW] <= #1 rREGD;
+       rRAMB[wRW] <= #1 rREGD;
+       rRAMD[wRW] <= #1 rREGD;
+     end
+   
+   /* 
+    STORE SIZER
+    
+    This resizes the data to be placed on the data bus. To make it
+    easy, it merely replicates the data across the whole bus. It
+    relies on the byte select signal to indicate which lanes to
+    use. */
+   
+   always @(posedge clk_i)
+     if (rst_i) begin
+       /*AUTORESET*/
+       // Beginning of autoreset for uninitialized flops
+       cwb_dat_o <= 32'h0;
+       dwb_dat_o <= 32'h0;
+       // End of automatics
+     end else if (ena_i) begin
+       case (rOPC_OF[1:0])
+         2'o0: dwb_dat_o <= #1 {(4){rOPM_OF[7:0]}};
+         2'o1: dwb_dat_o <= #1 {(2){rOPM_OF[15:0]}};
+         2'o2: dwb_dat_o <= #1 rOPM_OF;
+         default: dwb_dat_o <= #1 32'hX;        
+       endcase // case (rOPC_OF[1:0])
+
+       case (rOPC_OF[1:0])
+         2'o3: cwb_dat_o <= #1 rOPA_OF;          
+         default: cwb_dat_o <= #1 32'hX;        
+       endcase // case (rOPC_OF[1:0])
+
+     end // if (ena_i)
+   
+   // synopsys translate_off   
+   /* random initial condition for RAM */   
+   integer r;
+   initial begin
+      for (r=0; r<128; r=r+1) begin
+        rRAMA[r] <= $random;    
+        rRAMB[r] <= $random;    
+        rRAMD[r] <= $random;    
+      end
+   end
+   // synopsys translate_on
+   
+endmodule // aeMB2_regf
+
+/* $Log: aeMB2_regf.v,v $
+/* Revision 1.3  2007/12/13 20:12:11  sybreon
+/* Code cleanup + minor speed regression.
+/*
+/* Revision 1.2  2007/12/12 19:16:59  sybreon
+/* Minor optimisations (~10% faster)
+/*
+/* Revision 1.1  2007/12/11 00:43:17  sybreon
+/* initial import
+/* */
\ No newline at end of file

Added: usrp2/trunk/fpga/opencores/aemb/rtl/verilog/aeMB2_sim.v
===================================================================
--- usrp2/trunk/fpga/opencores/aemb/rtl/verilog/aeMB2_sim.v                     
        (rev 0)
+++ usrp2/trunk/fpga/opencores/aemb/rtl/verilog/aeMB2_sim.v     2008-01-04 
20:32:38 UTC (rev 7343)
@@ -0,0 +1,332 @@
+/* $Id: aeMB2_sim.v,v 1.2 2007/12/29 00:31:48 sybreon Exp $
+**
+** AEMB2 SIMULATION WRAPPER
+** Copyright (C) 2004-2007 Shawn Tan Ser Ngiap <address@hidden>
+**  
+** This file is part of AEMB.
+**
+** AEMB is free software: you can redistribute it and/or modify it
+** under the terms of the GNU Lesser General Public License as
+** published by the Free Software Foundation, either version 3 of the
+** License, or (at your option) any later version.
+**
+** AEMB is distributed in the hope that it will be useful, but WITHOUT
+** ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+** or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General
+** Public License for more details.
+**
+** You should have received a copy of the GNU Lesser General Public
+** License along with AEMB. If not, see <http:**www.gnu.org/licenses/>.
+*/
+
+module aeMB2_sim (/*AUTOARG*/
+   // Outputs
+   iwb_wre_o, iwb_tga_o, iwb_stb_o, iwb_adr_o, dwb_wre_o, dwb_tga_o,
+   dwb_stb_o, dwb_sel_o, dwb_dat_o, dwb_cyc_o, dwb_adr_o, cwb_wre_o,
+   cwb_tga_o, cwb_stb_o, cwb_sel_o, cwb_dat_o, cwb_adr_o,
+   // Inputs
+   sys_rst_i, sys_int_i, sys_clk_i, iwb_dat_i, iwb_ack_i, dwb_dat_i,
+   dwb_ack_i, cwb_dat_i, cwb_ack_i
+   );
+
+   parameter IWB=16;
+   parameter DWB=16;
+
+   parameter TXE = 1; ///< thread execution enable
+   
+   parameter MUL = 1; ///< enable hardware multiplier
+   parameter BSF = 1; ///< enable barrel shifter
+   parameter FSL = 1; ///< enable FSL bus
+   parameter DIV = 0; ///< enable hardware divider   
+   
+   /*AUTOOUTPUT*/
+   // Beginning of automatic outputs (from unused autoinst outputs)
+   output [6:2]                cwb_adr_o;              // From sim of 
aeMB2_edk32.v
+   output [31:0]       cwb_dat_o;              // From sim of aeMB2_edk32.v
+   output [3:0]                cwb_sel_o;              // From sim of 
aeMB2_edk32.v
+   output              cwb_stb_o;              // From sim of aeMB2_edk32.v
+   output [1:0]                cwb_tga_o;              // From sim of 
aeMB2_edk32.v
+   output              cwb_wre_o;              // From sim of aeMB2_edk32.v
+   output [DWB-1:2]    dwb_adr_o;              // From sim of aeMB2_edk32.v
+   output              dwb_cyc_o;              // From sim of aeMB2_edk32.v
+   output [31:0]       dwb_dat_o;              // From sim of aeMB2_edk32.v
+   output [3:0]                dwb_sel_o;              // From sim of 
aeMB2_edk32.v
+   output              dwb_stb_o;              // From sim of aeMB2_edk32.v
+   output              dwb_tga_o;              // From sim of aeMB2_edk32.v
+   output              dwb_wre_o;              // From sim of aeMB2_edk32.v
+   output [IWB-1:2]    iwb_adr_o;              // From sim of aeMB2_edk32.v
+   output              iwb_stb_o;              // From sim of aeMB2_edk32.v
+   output              iwb_tga_o;              // From sim of aeMB2_edk32.v
+   output              iwb_wre_o;              // From sim of aeMB2_edk32.v
+   // End of automatics
+   /*AUTOINPUT*/
+   // Beginning of automatic inputs (from unused autoinst inputs)
+   input               cwb_ack_i;              // To sim of aeMB2_edk32.v
+   input [31:0]                cwb_dat_i;              // To sim of 
aeMB2_edk32.v
+   input               dwb_ack_i;              // To sim of aeMB2_edk32.v
+   input [31:0]                dwb_dat_i;              // To sim of 
aeMB2_edk32.v
+   input               iwb_ack_i;              // To sim of aeMB2_edk32.v
+   input [31:0]                iwb_dat_i;              // To sim of 
aeMB2_edk32.v
+   input               sys_clk_i;              // To sim of aeMB2_edk32.v
+   input               sys_int_i;              // To sim of aeMB2_edk32.v
+   input               sys_rst_i;              // To sim of aeMB2_edk32.v
+   // End of automatics
+   /*AUTOWIRE*/
+   
+   aeMB2_edk32
+     #(/*AUTOINSTPARAM*/
+       // Parameters
+       .IWB                            (IWB),
+       .DWB                            (DWB),
+       .TXE                            (TXE),
+       .MUL                            (MUL),
+       .BSF                            (BSF),
+       .FSL                            (FSL))
+   sim
+     (/*AUTOINST*/
+      // Outputs
+      .cwb_adr_o                       (cwb_adr_o[6:2]),
+      .cwb_dat_o                       (cwb_dat_o[31:0]),
+      .cwb_sel_o                       (cwb_sel_o[3:0]),
+      .cwb_stb_o                       (cwb_stb_o),
+      .cwb_tga_o                       (cwb_tga_o[1:0]),
+      .cwb_wre_o                       (cwb_wre_o),
+      .dwb_adr_o                       (dwb_adr_o[DWB-1:2]),
+      .dwb_cyc_o                       (dwb_cyc_o),
+      .dwb_dat_o                       (dwb_dat_o[31:0]),
+      .dwb_sel_o                       (dwb_sel_o[3:0]),
+      .dwb_stb_o                       (dwb_stb_o),
+      .dwb_tga_o                       (dwb_tga_o),
+      .dwb_wre_o                       (dwb_wre_o),
+      .iwb_adr_o                       (iwb_adr_o[IWB-1:2]),
+      .iwb_stb_o                       (iwb_stb_o),
+      .iwb_tga_o                       (iwb_tga_o),
+      .iwb_wre_o                       (iwb_wre_o),
+      // Inputs
+      .cwb_ack_i                       (cwb_ack_i),
+      .cwb_dat_i                       (cwb_dat_i[31:0]),
+      .dwb_ack_i                       (dwb_ack_i),
+      .dwb_dat_i                       (dwb_dat_i[31:0]),
+      .iwb_ack_i                       (iwb_ack_i),
+      .iwb_dat_i                       (iwb_dat_i[31:0]),
+      .sys_clk_i                       (sys_clk_i),
+      .sys_int_i                       (sys_int_i),
+      .sys_rst_i                       (sys_rst_i));
+
+   // synopsys translate_off
+   
+   wire [31:0]                 iwb_adr = {iwb_adr_o, 2'd0};
+   wire [31:0]                 dwb_adr = {dwb_adr_o, 2'd0};
+   wire [31:0]                 wMSR = sim.aslu.wMSR[31:0];   
+   
+   always @(posedge sim.clk_i) if (sim.ena_i) begin   
+
+      $write ("\n", ($stime/10));
+      $writeh (" T", sim.pha_i);
+      $writeh(" PC=", iwb_adr);
+      
+      $writeh ("\t| ");
+      
+      case (sim.rOPC_IF)
+       6'o00: if (sim.rRD_IF == 0) $write("   "); else $write("ADD");
+       6'o01: $write("SUB");   
+       6'o02: $write("ADDC");  
+       6'o03: $write("SUBC");  
+       6'o04: $write("ADDK");  
+       6'o05: case (sim.rIMM_IF[1:0])
+                2'o0: $write("SUBK");  
+                2'o1: $write("CMP");   
+                2'o3: $write("CMPU");  
+                default: $write("XXX");
+              endcase // case (sim.rIMM_IF[1:0])
+       6'o06: $write("ADDKC"); 
+       6'o07: $write("SUBKC"); 
+       
+       6'o10: $write("ADDI");  
+       6'o11: $write("SUBI");  
+       6'o12: $write("ADDIC"); 
+       6'o13: $write("SUBIC"); 
+       6'o14: $write("ADDIK"); 
+       6'o15: $write("SUBIK"); 
+       6'o16: $write("ADDIKC");        
+       6'o17: $write("SUBIKC");        
+
+       6'o20: $write("MUL");   
+       6'o21: case (sim.rALT_IF[10:9])
+                2'o0: $write("BSRL");           
+                2'o1: $write("BSRA");           
+                2'o2: $write("BSLL");           
+                default: $write("XXX");                 
+              endcase // case (sim.rALT_IF[10:9])
+       6'o22: $write("IDIV");  
+
+       6'o30: $write("MULI");  
+       6'o31: case (sim.rALT_IF[10:9])
+                2'o0: $write("BSRLI");          
+                2'o1: $write("BSRAI");          
+                2'o2: $write("BSLLI");          
+                default: $write("XXX");                 
+              endcase // case (sim.rALT_IF[10:9])
+       6'o33: case (sim.rRB_IF[4:2])
+                3'o0: $write("GET");
+                3'o4: $write("PUT");            
+                3'o2: $write("NGET");
+                3'o6: $write("NPUT");           
+                3'o1: $write("CGET");
+                3'o5: $write("CPUT");           
+                3'o3: $write("NCGET");
+                3'o7: $write("NCPUT");          
+              endcase // case (sim.rRB_IF[4:2])
+
+       6'o40: $write("OR");
+       6'o41: $write("AND");   
+       6'o42: if (sim.rRD_IF == 0) $write("   "); else $write("XOR");
+       6'o43: $write("ANDN");  
+       6'o44: case (sim.rIMM_IF[6:5])
+                2'o0: $write("SRA");
+                2'o1: $write("SRC");
+                2'o2: $write("SRL");
+                2'o3: if (sim.rIMM_IF[0]) $write("SEXT16"); else 
$write("SEXT8");               
+              endcase // case (sim.rIMM_IF[6:5])
+       
+       6'o45: $write("MOV");   
+       6'o46: case (sim.rRA_IF[3:2])
+                3'o0: $write("BR");             
+                3'o1: $write("BRL");            
+                3'o2: $write("BRA");            
+                3'o3: $write("BRAL");           
+              endcase // case (sim.rRA_IF[3:2])
+       
+       6'o47: case (sim.rRD_IF[2:0])
+                3'o0: $write("BEQ");   
+                3'o1: $write("BNE");   
+                3'o2: $write("BLT");   
+                3'o3: $write("BLE");   
+                3'o4: $write("BGT");   
+                3'o5: $write("BGE");
+                default: $write("XXX");                 
+              endcase // case (sim.rRD_IF[2:0])
+       
+       6'o50: $write("ORI");   
+       6'o51: $write("ANDI");  
+       6'o52: $write("XORI");  
+       6'o53: $write("ANDNI"); 
+       6'o54: $write("IMMI");  
+       6'o55: case (sim.rRD_IF[1:0])
+                2'o0: $write("RTSD");
+                2'o1: $write("RTID");
+                2'o2: $write("RTBD");
+                default: $write("XXX");                 
+              endcase // case (sim.rRD_IF[1:0])
+       6'o56: case (sim.rRA_IF[3:2])
+                3'o0: $write("BRI");            
+                3'o1: $write("BRLI");           
+                3'o2: $write("BRAI");           
+                3'o3: $write("BRALI");          
+              endcase // case (sim.rRA_IF[3:2])
+       6'o57: case (sim.rRD_IF[2:0])
+                3'o0: $write("BEQI");  
+                3'o1: $write("BNEI");  
+                3'o2: $write("BLTI");  
+                3'o3: $write("BLEI");  
+                3'o4: $write("BGTI");  
+                3'o5: $write("BGEI");  
+                default: $write("XXX");                 
+              endcase // case (sim.rRD_IF[2:0])
+       
+       6'o60: $write("LBU");   
+       6'o61: $write("LHU");   
+       6'o62: $write("LW");    
+       6'o64: $write("SB");    
+       6'o65: $write("SH");    
+       6'o66: $write("SW");    
+       
+       6'o70: $write("LBUI");  
+       6'o71: $write("LHUI");  
+       6'o72: $write("LWI");   
+       6'o74: $write("SBI");   
+       6'o75: $write("SHI");   
+       6'o76: $write("SWI");
+
+       default: $write("XXX"); 
+      endcase // case (sim.rOPC_IF)
+
+      case (sim.rOPC_IF[3])
+       1'b1: $writeh("\t r",sim.rRD_IF,", r",sim.rRA_IF,", h",sim.rIMM_IF);
+       1'b0: $writeh("\t r",sim.rRD_IF,", r",sim.rRA_IF,", r",sim.rRB_IF,"  
");        
+      endcase // case (sim.rOPC_IF[3])
+
+      if (sim.bpcu.fHZD)
+       $write ("*");      
+      
+      // ALU
+      $write("\t|");
+      $writeh(" A=",sim.rOPA_OF);
+      $writeh(" B=",sim.rOPB_OF);
+      $writeh(" C=",sim.rOPX_OF);
+      $writeh(" M=",sim.rOPM_OF);
+      
+      $writeh(" MSR=", wMSR," ");
+
+      case (sim.rALU_OF)
+       3'o0: $write(" ADD");
+       3'o1: $write(" BSF");
+       3'o2: $write(" SLM");
+       3'o3: $write(" MOV");
+       default: $write(" XXX");
+      endcase // case (sim.rALU_OF)
+
+      // MA
+      $write ("\t| ");      
+      if (sim.dwb_stb_o)
+       $writeh("@",sim.rRES_EX);
+      else
+       $writeh("=",sim.rRES_EX);
+
+      
+      case (sim.rBRA)
+       2'b00: $write(" ");
+       2'b01: $write(".");     
+       2'b10: $write("-");
+       2'b11: $write("+");     
+      endcase // case (sim.rBRA)
+      
+      // WRITEBACK
+      $write("\t|");
+      
+      if (|sim.rRD_MA) begin
+        case (sim.rOPD_MA)
+          2'o2: begin
+             if (sim.rSEL_MA != 4'h0) 
$writeh("R",sim.rRD_MA,"=RAM(",sim.regf.rREGD,")");
+             if (sim.rSEL_MA == 4'h0) 
$writeh("R",sim.rRD_MA,"=FSL(",sim.regf.rREGD,")");
+          end
+          2'o1: $writeh("R",sim.rRD_MA,"=LNK(",sim.regf.rREGD,")");
+          2'o0: $writeh("R",sim.rRD_MA,"=ALU(",sim.regf.rREGD,")");
+        endcase // case (sim.rOPD_MA)
+      end
+
+      /*
+      // STORE
+      if (dwb_stb_o & dwb_wre_o) begin
+        $writeh("RAM(", dwb_adr ,")=", dwb_dat_o);
+        case (dwb_sel_o)
+          4'hF: $write(":L");
+          4'h3,4'hC: $write(":W");
+          4'h1,4'h2,4'h4,4'h8: $write(":B");
+        endcase // case (dwb_sel_o)
+        
+      end
+       */
+   end // if (sim.ena_i)
+   
+   // synopsys translate_on
+      
+endmodule // aeMB2_sim
+
+/* $Log: aeMB2_sim.v,v $
+/* Revision 1.2  2007/12/29 00:31:48  sybreon
+/* Minor cleanup
+/*
+/* Revision 1.1  2007/12/18 18:54:36  sybreon
+/* Partitioned simulation model.
+/* */
\ No newline at end of file

Added: usrp2/trunk/fpga/opencores/aemb/rtl/verilog/aeMB2_sysc.v
===================================================================
--- usrp2/trunk/fpga/opencores/aemb/rtl/verilog/aeMB2_sysc.v                    
        (rev 0)
+++ usrp2/trunk/fpga/opencores/aemb/rtl/verilog/aeMB2_sysc.v    2008-01-04 
20:32:38 UTC (rev 7343)
@@ -0,0 +1,214 @@
+/* $Id: aeMB2_sysc.v,v 1.5 2007/12/21 22:28:56 sybreon Exp $
+**
+** AEMB2 SYSTEM CONTROL
+** 
+** Copyright (C) 2004-2007 Shawn Tan Ser Ngiap <address@hidden>
+**  
+** This file is part of AEMB.
+**
+** AEMB is free software: you can redistribute it and/or modify it
+** under the terms of the GNU Lesser General Public License as
+** published by the Free Software Foundation, either version 3 of the
+** License, or (at your option) any later version.
+**
+** AEMB is distributed in the hope that it will be useful, but WITHOUT
+** ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+** or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General
+** Public License for more details.
+**
+** You should have received a copy of the GNU Lesser General Public
+** License along with AEMB. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+module aeMB2_sysc (/*AUTOARG*/
+   // Outputs
+   rINT, rXCE, pha_o, clk_o, rst_o, ena_o, iwb_stb_o, iwb_wre_o,
+   dwb_cyc_o, dwb_stb_o, dwb_wre_o, cwb_stb_o, cwb_wre_o,
+   // Inputs
+   rIMM_OF, rOPC_OF, rRA_OF, rMSR_BE, rMSR_BIP, rMSR_IE, rOPC_IF,
+   iwb_ack_i, dwb_ack_i, cwb_ack_i, sys_int_i, sys_clk_i, sys_rst_i
+   );
+   parameter TXE = 1;
+   parameter FSL = 1;   
+   
+   // INTERNAL
+   input [15:0] rIMM_OF;   
+   input [5:0]         rOPC_OF;
+   input [4:0]         rRA_OF;
+   input       rMSR_BE,
+               rMSR_BIP,
+               //rMSR_TXE,
+               rMSR_IE;   
+   input [5:0]         rOPC_IF;
+   
+   output      rINT,
+               rXCE;
+   
+   output      pha_o,
+               clk_o, 
+               rst_o, 
+               ena_o;   
+   
+   // EXTERNAL
+   output      iwb_stb_o,
+               iwb_wre_o,
+               dwb_cyc_o,
+               dwb_stb_o,
+               dwb_wre_o,
+               cwb_stb_o,
+               cwb_wre_o;   
+   
+   input       iwb_ack_i,
+               dwb_ack_i,
+               cwb_ack_i;   
+      
+   // SYSTEM
+   input       sys_int_i,
+              sys_clk_i, 
+              sys_rst_i;
+
+   /*AUTOREG*/
+   // Beginning of automatic regs (for this module's undeclared outputs)
+   reg                 cwb_stb_o;
+   reg                 cwb_wre_o;
+   reg                 dwb_cyc_o;
+   reg                 dwb_stb_o;
+   reg                 dwb_wre_o;
+   reg                 iwb_stb_o;
+   reg                 pha_o;
+   reg                 rINT;
+   reg                 rXCE;
+   reg                 rst_o;
+   // End of automatics
+
+   
+   /* Partial decoding */
+   wire [5:0]          rOPC = rOPC_OF;
+   wire [4:0]          rRA = rRA_OF;
+   wire [4:0]          rRB = rIMM_OF[15:11];
+   
+   wire                fSFT = (rOPC == 6'o44);
+   wire                fLOG = ({rOPC[5:4],rOPC[2]} == 3'o4);      
+   wire                fMUL = (rOPC == 6'o20) | (rOPC == 6'o30);
+   wire                fBSF = (rOPC == 6'o21) | (rOPC == 6'o31);
+   wire                fDIV = (rOPC == 6'o22);   
+   wire                fRTD = (rOPC == 6'o55);
+   wire                fBCC = (rOPC == 6'o47) | (rOPC == 6'o57);
+   wire                fBRU = (rOPC == 6'o46) | (rOPC == 6'o56);
+   wire                fBRA = fBRU & rRA[3];      
+   wire                fIMM = (rOPC == 6'o54);
+   wire                fMOV = (rOPC == 6'o45);      
+   wire                fLOD = ({rOPC[5:4],rOPC[2]} == 3'o6);
+   wire                fSTR = ({rOPC[5:4],rOPC[2]} == 3'o7);
+   wire                fLDST = (rOPC[5:4] == 2'o3);      
+   wire                fPUT = (rOPC == 6'o33) & rRB[4];
+   wire                fGET = (rOPC == 6'o33) & !rRB[4];
+   
+   /* instantiate a clock manager if necessary */
+   
+   assign              clk_o = sys_clk_i;   
+
+   
+   /* delay the reset signal for POR */
+     
+   always @(posedge clk_o)
+     if (sys_rst_i) begin
+       rst_o <= 1'b1;  
+     end else if (!pha_o) begin
+       rst_o <= #1 1'b0;       
+     end
+
+   /* calculate the async enable signal */
+   
+   assign              ena_o = !((cwb_ack_i ^ cwb_stb_o) | // FSL clean
+                                 (dwb_ack_i ^ dwb_stb_o) | // DWB clean
+                                 (iwb_ack_i ^ iwb_stb_o)); // IWB clean  
+
+
+   /* Toggle the FGMT phase. This toggles twice during POR to reset
+   /* the various RAM locations (for a LUT based optimisation). */
+   
+   always @(posedge clk_o)
+     if (sys_rst_i) begin
+       pha_o <= 1'b1;  
+       /*AUTORESET*/
+     end else if (ena_o) begin
+       pha_o <= #1 !pha_o;     
+     end
+
+   /* Level triggered interrupt latch flag */
+
+   // check for interrupt acknowledge
+   wire                fINTACK = ena_o & (rOPC_OF == 6'o56) & (rRA_OF == 
5'h0E);   
+                  
+   always @(posedge clk_o)
+     if (rst_o) begin
+       /*AUTORESET*/
+       // Beginning of autoreset for uninitialized flops
+       rINT <= 1'h0;
+       // End of automatics
+     end else if (rMSR_IE) begin
+       rINT <= #1 (rINT | sys_int_i) & !fINTACK;       
+     end
+
+   /* Hardwre exception catcher */
+
+   // check for exception acknowledge
+   wire                fXCEACK = ena_o & (rOPC_OF == 6'o56) & (rRA_OF == 
5'h0F);   
+
+   // check for invalid instruction
+   wire                fILLEGAL;
+   assign              fILLEGAL = ({rOPC_IF[5:4],rOPC_IF[1:0]} == 4'hF) | // 
LD/ST
+                                  ((rOPC_IF[5:3] == 3'o3) & 
+                                   ((rOPC_OF[2:0] != 3'o2) | 
+                                    (rOPC_OF[2]))) | // GET/PUT
+                                  ((rOPC_IF[5:3] == 3'o2) &
+                                   (rOPC_IF[2:1] != 2'o0)) // MUL/BSF
+                                    ;
+      
+   /* Handle wishbone handshakes */
+   
+   assign iwb_wre_o = 1'b0;
+   
+   always @(posedge clk_o)
+     if (rst_o) begin
+       /*AUTORESET*/
+       // Beginning of autoreset for uninitialized flops
+       cwb_stb_o <= 1'h0;
+       cwb_wre_o <= 1'h0;
+       dwb_cyc_o <= 1'h0;
+       dwb_stb_o <= 1'h0;
+       dwb_wre_o <= 1'h0;
+       iwb_stb_o <= 1'h0;
+       // End of automatics
+     end else if (ena_o) begin
+       iwb_stb_o <= #1 (TXE | pha_o);
+
+       dwb_cyc_o <= #1 fLOD | fSTR | rMSR_BE;  
+       dwb_stb_o <= #1 fLOD | fSTR;
+       dwb_wre_o <= #1 fSTR;
+       
+       cwb_stb_o <= #1 (FSL) ? (fGET | fPUT) : 1'bX;
+       cwb_wre_o <= #1 (FSL) ? fPUT : 1'bX;    
+     end
+   
+
+   
+endmodule // aeMB2_sysc
+
+/* $Log: aeMB2_sysc.v,v $
+/* Revision 1.5  2007/12/21 22:28:56  sybreon
+/* Minor enable fix
+/*
+/* Revision 1.4  2007/12/16 03:25:02  sybreon
+/* Added interrupt support.
+/*
+/* Revision 1.3  2007/12/13 20:12:11  sybreon
+/* Code cleanup + minor speed regression.
+/*
+/* Revision 1.2  2007/12/12 19:16:59  sybreon
+/* Minor optimisations (~10% faster)
+/*
+/* Revision 1.1  2007/12/11 00:43:17  sybreon
+/* initial import
+/* */
\ No newline at end of file





reply via email to

[Prev in Thread] Current Thread [Next in Thread]