[Top][All Lists]
[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
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [Commit-gnuradio] r7343 - usrp2/trunk/fpga/opencores/aemb/rtl/verilog,
matt <=