URL
https://opencores.org/ocsvn/aemb/aemb/trunk
Subversion Repositories aemb
[/] [aemb/] [branches/] [DEV_SYBREON/] [rtl/] [verilog/] [aeMB2_aslu.v] - Rev 78
Go to most recent revision | Compare with Previous | Blame | View Log
/* $Id: aeMB2_aslu.v,v 1.1 2007-12-11 00:43:17 sybreon Exp $ ** ** AEMB2 INTEGER ARITHMETIC SHIFT LOGIC UNIT ** ** Copyright (C) 2004-2007 Shawn Tan Ser Ngiap <shawn.tan@aeste.net> ** ** 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, rMUL_MA, rRES_MA, rRES_EX, rMSR_IE, rMSR_BE, rMSR_BIP, // Inputs rIMM_OF, rALU_OF, rOPC_OF, rRA_OF, rRD_OF, rPC_OF, rOPA_OF, rOPB_OF, pha_i, clk_i, rst_i, ena_i ); parameter DWB = 32; parameter MUL = 0; parameter BSF = 1; parameter FSL = 1; parameter TXE = 1; parameter LUT = 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; // PIPELINE output [31:0] rMUL_MA; output [31:0] rRES_MA, rRES_EX; output rMSR_IE, rMSR_BE, rMSR_BIP; input [15:0] rIMM_OF; input [2:0] rALU_OF; input [5:0] rOPC_OF; input [4:0] rRA_OF, rRD_OF; input [31:2] rPC_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 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_CL[0:TXE]; 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]; // --- ADD/SUB SELECTOR ---- // FIXME: Redesign // TODO: Refactor // TODO: Verify signed compare wire rMSR_CX = (!pha_i) ? rMSR_C0 : (TXE) ? rMSR_C1 : 1'bX; wire rMSR_C = (LUT) ? rMSR_CL[pha_i] : rMSR_CX; 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 {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 SELECTOR -------------------------------------- reg [31:0] rRES_LOG; always @(/*AUTOSENSE*/rOPA or rOPB or rOPC) case (rOPC[1: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[1:0]) // --- SHIFTER SELECTOR ------------------------------------ reg [31:0] rRES_SFT; reg rRES_SFTC; always @(/*AUTOSENSE*/rIMM or rMSR_C or rOPA) case (rIMM[6:5]) 2'o0: {rRES_SFT, rRES_SFTC} <= #1 {rOPA[31],rOPA[31:0]}; 2'o1: {rRES_SFT, rRES_SFTC} <= #1 {rMSR_C,rOPA[31:0]}; 2'o2: {rRES_SFT, rRES_SFTC} <= #1 {1'b0,rOPA[31:0]}; 2'o3: {rRES_SFT, rRES_SFTC} <= #1 (rIMM[0]) ? { {(16){rOPA[15]}}, rOPA[15:0], rMSR_C} : { {(24){rOPA[7]}}, rOPA[7:0], rMSR_C}; endcase // case (rIMM[6:5]) // --- MOVE SELECTOR --------------------------------------- wire wTXE = (TXE) ? 2'd1 : 2'd0; wire [31:0] wMSR = {rMSR_C, // MSR_CC pha_i, // Current phase !pha_i, // Current phase wTXE, // Thread Execution Enabled 4'h0, // Reserved 8'hAE, // Vendor 8'h32, // Version 4'h0, // Reserved rMSR_BIP, // MSR_BIP rMSR_C, // MSR_C rMSR_IE, // MSR_IE rMSR_BE}; // MSR_BE 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*/fMFPC or fMFSR or rOPA or rOPB or rPC_OF or rRA or wMSR) rRES_MOV <= (fMFSR) ? wMSR : (fMFPC) ? {rPC_OF, 2'd0} : (rRA[3]) ? rOPB : rOPA; // --- MULTIPLIER ------------------------------------------ // 2-stage reg [31:0] rRES_MUL; always @(posedge clk_i) begin rMUL_MA <= (MUL) ? rRES_MUL : 32'hX; rRES_MUL <= (rOPA * rOPB); end // --- BARREL SHIFTER -------------------------------------- // 1-stage reg [31:0] rRES_BSF; reg [31:0] xBSRL, xBSRA, xBSLL; // Infer a logical left barrel shifter. always @(/*AUTOSENSE*/rOPA or rOPB) xBSLL <= rOPA << rOPB[4:0]; // Infer a logical right barrel shifter. always @(/*AUTOSENSE*/rOPA or rOPB) xBSRL <= rOPA >> rOPB[4:0]; // Infer a 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]) 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]) // --- MSR REGISTER ----------------- reg xMSR_C; // C wire fMTS = (rOPC == 6'o45) & rIMM[14]; wire fADDC = ({rOPC[5:4], rOPC[2]} == 3'o0); always @(/*AUTOSENSE*/fADDC or fMTS or rALU_OF or rMSR_C or rOPA or rRES_ADDC or rRES_SFTC) 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 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 always @(posedge clk_i) if (ena_i) rMSR_CL[pha_i] <= xMSR_C; // 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 rMSR_BE <= 1'h0; rMSR_BIP <= 1'h0; rMSR_IE <= 1'h0; // End of automatics end else if (ena_i) begin rMSR_IE <= #1 (fINT) ? 1'b0 : (fRTID) ? 1'b1 : (fMTS) ? rOPA[1] : rMSR_IE; rMSR_BIP <= #1 (fBRK) ? 1'b1 : (fRTBD) ? 1'b0 : (fMTS) ? rOPA[3] : rMSR_BIP; rMSR_BE <= #1 (fMTS) ? rOPA[0] : rMSR_BE; end // --- RESULT SELECTOR ------------------------------------------- // Selects results from functional units. // 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'o4: rRES_EX <= (MUL) ? rRES_MUL : 32'hX; 3'o5: rRES_EX <= #1 (BSF) ? rRES_BSF : 32'hX; default: rRES_EX <= #1 32'hX; endcase // case (rALU_OF) end // if (ena_i) // --- DATA/FSL WISHBONE ----- 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 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) // synopsys translate_off integer r; initial begin for (r=0; r<TXE; r=r+1) begin rMSR_CL[r] <= $random; end end // synopsys translate_on endmodule // aeMB2_aslu /* $Log: not supported by cvs2svn $ */
Go to most recent revision | Compare with Previous | Blame | View Log