| /* |
| Copyright 2024 Google LLC |
| |
| http://www.apache.org/licenses/LICENSE-2.0 |
| |
| Unless required by applicable law or agreed to in writing, software |
| distributed under the License is distributed on an "AS IS" BASIS, |
| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| See the License for the specific language governing permissions and |
| limitations under the License. |
| |
| SPDX-License-Identifier: Apache-2.0 |
| */ |
| |
| package DMAController.Frontend |
| |
| import DMAController.Bus._ |
| import DMAController.CSR.{CSRBusBundle} |
| import chisel3._ |
| import chisel3.util._ |
| |
| class TLULCSR(addrWidth : Int, dataWidth : Int) extends CSRBus[TLULDevice]{ |
| val io = IO(new Bundle{ |
| val ctl = new TLULDevice(addrWidth, dataWidth) |
| val bus = new CSRBusBundle |
| }) |
| |
| val sIdle :: sGet :: sPut :: Nil = Enum(3) |
| val state = RegInit(sIdle) |
| |
| val rsp = WireInit(TLResp.AccessAck) |
| val valid = WireInit(false.B) |
| |
| val addr = RegInit(0.U(addrWidth.W)) |
| val wdata = RegInit(0.U(dataWidth.W)) |
| val sourceId = RegInit(0.U) |
| val size = RegInit(0.U) |
| |
| val write = WireInit(false.B) |
| |
| io.ctl.a <> TLULA.tieOff(addrWidth, dataWidth) |
| |
| // TLUL response |
| io.ctl.d.data := io.bus.dataIn |
| io.ctl.d.opcode := rsp |
| io.ctl.d.valid := valid |
| io.ctl.d.param := 0.U |
| io.ctl.d.size := size |
| io.ctl.d.corrupt := 0.U |
| io.ctl.d.sink := 0.U |
| io.ctl.d.source := sourceId |
| io.ctl.d.denied := 0.U |
| |
| // CSR Interface |
| io.bus.addr := addr |
| io.bus.dataOut := wdata |
| |
| io.bus.write := write |
| io.bus.read := (state === sGet) |
| |
| switch(state) { |
| is(sIdle) { |
| io.ctl.a.ready := true.B |
| valid := false.B |
| write := false.B |
| addr := io.ctl.a.address(5, 2) |
| when(io.ctl.a.valid) { |
| size := io.ctl.a.size |
| sourceId := io.ctl.a.source |
| |
| when(io.ctl.a.opcode === TLOp.Get) { |
| state := sGet |
| addr := io.ctl.a.address(5, 2) |
| }.elsewhen(io.ctl.a.opcode === TLOp.PutFull || |
| io.ctl.a.opcode === TLOp.PutPartial) { |
| addr := io.ctl.a.address(5, 2) |
| wdata := io.ctl.a.data |
| state := sPut |
| } |
| } |
| } |
| is(sGet) { |
| state := sGet |
| rsp := TLResp.AccessAckData |
| valid := true.B |
| when(io.ctl.d.ready) { |
| state := sIdle |
| } |
| } |
| is(sPut) { |
| state := sPut |
| rsp := TLResp.AccessAck |
| valid := true.B |
| when(io.ctl.d.ready) { |
| write := true.B |
| state := sIdle |
| } |
| } |
| } |
| |
| |
| } |