1*96b1e495SWilliam Wang// See LICENSE.SiFive for license details. 2*96b1e495SWilliam Wang// See LICENSE.Berkeley for license details. 3*96b1e495SWilliam Wang 41f0e2dc7SJiawei Lin/*************************************************************************************** 51f0e2dc7SJiawei Lin* Copyright (c) 2020-2021 Institute of Computing Technology, Chinese Academy of Sciences 61f0e2dc7SJiawei Lin* Copyright (c) 2020-2021 Peng Cheng Laboratory 71f0e2dc7SJiawei Lin* 81f0e2dc7SJiawei Lin* XiangShan is licensed under Mulan PSL v2. 91f0e2dc7SJiawei Lin* You can use this software according to the terms and conditions of the Mulan PSL v2. 101f0e2dc7SJiawei Lin* You may obtain a copy of Mulan PSL v2 at: 111f0e2dc7SJiawei Lin* http://license.coscl.org.cn/MulanPSL2 121f0e2dc7SJiawei Lin* 131f0e2dc7SJiawei Lin* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, 141f0e2dc7SJiawei Lin* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, 151f0e2dc7SJiawei Lin* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. 161f0e2dc7SJiawei Lin* 171f0e2dc7SJiawei Lin* See the Mulan PSL v2 for more details. 181f0e2dc7SJiawei Lin***************************************************************************************/ 191f0e2dc7SJiawei Lin 201f0e2dc7SJiawei Linpackage xiangshan.cache 211f0e2dc7SJiawei Lin 221f0e2dc7SJiawei Linimport chisel3._ 231f0e2dc7SJiawei Linimport chisel3.util._ 241f0e2dc7SJiawei Lin 251f0e2dc7SJiawei Linclass AMOALU(operandBits: Int) extends Module 261f0e2dc7SJiawei Lin with MemoryOpConstants { 271f0e2dc7SJiawei Lin val minXLen = 32 281f0e2dc7SJiawei Lin val widths = (0 to log2Ceil(operandBits / minXLen)).map(minXLen << _) 291f0e2dc7SJiawei Lin 301f0e2dc7SJiawei Lin val io = IO(new Bundle { 311f0e2dc7SJiawei Lin val mask = Input(UInt((operandBits/8).W)) 321f0e2dc7SJiawei Lin val cmd = Input(Bits(M_SZ.W)) 331f0e2dc7SJiawei Lin val lhs = Input(Bits(operandBits.W)) 341f0e2dc7SJiawei Lin val rhs = Input(Bits(operandBits.W)) 351f0e2dc7SJiawei Lin val out = Output(Bits(operandBits.W)) 361f0e2dc7SJiawei Lin val out_unmasked = Output(Bits(operandBits.W)) 371f0e2dc7SJiawei Lin }) 381f0e2dc7SJiawei Lin 391f0e2dc7SJiawei Lin val max = io.cmd === M_XA_MAX || io.cmd === M_XA_MAXU 401f0e2dc7SJiawei Lin val min = io.cmd === M_XA_MIN || io.cmd === M_XA_MINU 411f0e2dc7SJiawei Lin val add = io.cmd === M_XA_ADD 421f0e2dc7SJiawei Lin val logic_and = io.cmd === M_XA_OR || io.cmd === M_XA_AND 431f0e2dc7SJiawei Lin val logic_xor = io.cmd === M_XA_XOR || io.cmd === M_XA_OR 441f0e2dc7SJiawei Lin 451f0e2dc7SJiawei Lin val adder_out = { 461f0e2dc7SJiawei Lin // partition the carry chain to support sub-xLen addition 471f0e2dc7SJiawei Lin val mask = ~(0.U(operandBits.W) +: widths.init.map(w => !io.mask(w/8-1) << (w-1))).reduce(_|_) 481f0e2dc7SJiawei Lin (io.lhs & mask) + (io.rhs & mask) 491f0e2dc7SJiawei Lin } 501f0e2dc7SJiawei Lin 511f0e2dc7SJiawei Lin val less = { 521f0e2dc7SJiawei Lin // break up the comparator so the lower parts will be CSE'd 531f0e2dc7SJiawei Lin def isLessUnsigned(x: UInt, y: UInt, n: Int): Bool = { 541f0e2dc7SJiawei Lin if (n == minXLen) x(n-1, 0) < y(n-1, 0) 551f0e2dc7SJiawei Lin else x(n-1, n/2) < y(n-1, n/2) || x(n-1, n/2) === y(n-1, n/2) && isLessUnsigned(x, y, n/2) 561f0e2dc7SJiawei Lin } 571f0e2dc7SJiawei Lin 581f0e2dc7SJiawei Lin def isLess(x: UInt, y: UInt, n: Int): Bool = { 591f0e2dc7SJiawei Lin val signed = { 601f0e2dc7SJiawei Lin val mask = M_XA_MIN ^ M_XA_MINU 611f0e2dc7SJiawei Lin (io.cmd & mask) === (M_XA_MIN & mask) 621f0e2dc7SJiawei Lin } 631f0e2dc7SJiawei Lin Mux(x(n-1) === y(n-1), isLessUnsigned(x, y, n), Mux(signed, x(n-1), y(n-1))) 641f0e2dc7SJiawei Lin } 651f0e2dc7SJiawei Lin 661f0e2dc7SJiawei Lin PriorityMux(widths.reverse.map(w => (io.mask(w/8/2), isLess(io.lhs, io.rhs, w)))) 671f0e2dc7SJiawei Lin } 681f0e2dc7SJiawei Lin 691f0e2dc7SJiawei Lin val minmax = Mux(Mux(less, min, max), io.lhs, io.rhs) 701f0e2dc7SJiawei Lin val logic = 711f0e2dc7SJiawei Lin Mux(logic_and, io.lhs & io.rhs, 0.U) | 721f0e2dc7SJiawei Lin Mux(logic_xor, io.lhs ^ io.rhs, 0.U) 731f0e2dc7SJiawei Lin val out = 741f0e2dc7SJiawei Lin Mux(add, adder_out, 751f0e2dc7SJiawei Lin Mux(logic_and || logic_xor, logic, 761f0e2dc7SJiawei Lin minmax)) 771f0e2dc7SJiawei Lin 781f0e2dc7SJiawei Lin val wmask = FillInterleaved(8, io.mask) 791f0e2dc7SJiawei Lin io.out := wmask & out | ~wmask & io.lhs 801f0e2dc7SJiawei Lin io.out_unmasked := out 811f0e2dc7SJiawei Lin} 82