xref: /XiangShan/src/main/scala/xiangshan/cache/dcache/mainpipe/AMOALU.scala (revision 38c29594d00da67087523376f6a6f3243679884e)
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