1// See LICENSE.SiFive for license details. 2// See LICENSE.Berkeley for license details. 3 4/*************************************************************************************** 5* Copyright (c) 2020-2021 Institute of Computing Technology, Chinese Academy of Sciences 6* Copyright (c) 2020-2021 Peng Cheng Laboratory 7* 8* XiangShan is licensed under Mulan PSL v2. 9* You can use this software according to the terms and conditions of the Mulan PSL v2. 10* You may obtain a copy of Mulan PSL v2 at: 11* http://license.coscl.org.cn/MulanPSL2 12* 13* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, 14* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, 15* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. 16* 17* See the Mulan PSL v2 for more details. 18***************************************************************************************/ 19 20package xiangshan.cache 21 22import chisel3._ 23import chisel3.util._ 24 25class StoreGen(typ: UInt, addr: UInt, dat: UInt, maxSize: Int) { 26 val size = typ(log2Up(log2Up(maxSize)+1)-1,0) 27 def misaligned = 28 (addr & ((1.U << size) - 1.U)(log2Up(maxSize)-1,0)).orR 29 30 def mask = { 31 var res = 1.U 32 for (i <- 0 until log2Up(maxSize)) { 33 val upper = Mux(addr(i), res, 0.U) | Mux(size >= (i+1).U, ((BigInt(1) << (1 << i))-1).U, 0.U) 34 val lower = Mux(addr(i), 0.U, res) 35 res = Cat(upper, lower) 36 } 37 res 38 } 39 40 protected def genData(i: Int): UInt = 41 if (i >= log2Up(maxSize)) dat 42 else Mux(size === i.U, Fill(1 << (log2Up(maxSize)-i), dat((8 << i)-1,0)), genData(i+1)) 43 44 def data = genData(0) 45 def wordData = genData(2) 46} 47 48class LoadGen(typ: UInt, signed: Bool, addr: UInt, dat: UInt, zero: Bool, maxSize: Int) { 49 private val size = new StoreGen(typ, addr, dat, maxSize).size 50 51 private def genData(logMinSize: Int): UInt = { 52 var res = dat 53 for (i <- log2Up(maxSize)-1 to logMinSize by -1) { 54 val pos = 8 << i 55 val shifted = Mux(addr(i), res(2*pos-1,pos), res(pos-1,0)) 56 val doZero = (i == 0).B && zero 57 val zeroed = Mux(doZero, 0.U, shifted) 58 res = Cat(Mux(size === i.U || doZero, Fill(8*maxSize-pos, signed && zeroed(pos-1)), res(8*maxSize-1,pos)), zeroed) 59 } 60 res 61 } 62 63 def wordData = genData(2) 64 def data = genData(0) 65} 66 67class AMOALU(operandBits: Int) extends Module 68 with MemoryOpConstants { 69 val minXLen = 32 70 val widths = (0 to log2Ceil(operandBits / minXLen)).map(minXLen << _) 71 72 val io = IO(new Bundle { 73 val mask = Input(UInt((operandBits/8).W)) 74 val cmd = Input(Bits(M_SZ.W)) 75 val lhs = Input(Bits(operandBits.W)) 76 val rhs = Input(Bits(operandBits.W)) 77 val out = Output(Bits(operandBits.W)) 78 val out_unmasked = Output(Bits(operandBits.W)) 79 }) 80 81 val max = io.cmd === M_XA_MAX || io.cmd === M_XA_MAXU 82 val min = io.cmd === M_XA_MIN || io.cmd === M_XA_MINU 83 val add = io.cmd === M_XA_ADD 84 val logic_and = io.cmd === M_XA_OR || io.cmd === M_XA_AND 85 val logic_xor = io.cmd === M_XA_XOR || io.cmd === M_XA_OR 86 87 val adder_out = { 88 // partition the carry chain to support sub-xLen addition 89 val mask = ~(0.U(operandBits.W) +: widths.init.map(w => !io.mask(w/8-1) << (w-1))).reduce(_|_) 90 (io.lhs & mask) + (io.rhs & mask) 91 } 92 93 val less = { 94 // break up the comparator so the lower parts will be CSE'd 95 def isLessUnsigned(x: UInt, y: UInt, n: Int): Bool = { 96 if (n == minXLen) x(n-1, 0) < y(n-1, 0) 97 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) 98 } 99 100 def isLess(x: UInt, y: UInt, n: Int): Bool = { 101 val signed = { 102 val mask = M_XA_MIN ^ M_XA_MINU 103 (io.cmd & mask) === (M_XA_MIN & mask) 104 } 105 Mux(x(n-1) === y(n-1), isLessUnsigned(x, y, n), Mux(signed, x(n-1), y(n-1))) 106 } 107 108 PriorityMux(widths.reverse.map(w => (io.mask(w/8/2), isLess(io.lhs, io.rhs, w)))) 109 } 110 111 val minmax = Mux(Mux(less, min, max), io.lhs, io.rhs) 112 val logic = 113 Mux(logic_and, io.lhs & io.rhs, 0.U) | 114 Mux(logic_xor, io.lhs ^ io.rhs, 0.U) 115 val out = 116 Mux(add, adder_out, 117 Mux(logic_and || logic_xor, logic, 118 minmax)) 119 120 val wmask = FillInterleaved(8, io.mask) 121 io.out := wmask & out | ~wmask & io.lhs 122 io.out_unmasked := out 123} 124