blob: 60e6c9617edbe5539d1416caf1fed859682447b9 [file] [log] [blame]
// SPDX-FileCopyrightText: 2020 Muhammad Hadir Khan
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// 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 uart0
import chisel3._
import chisel3.util._
import chisel3.dontTouch
class Rx extends Module {
val io = IO(new Bundle {
val CLK_PER_BIT = Input(UInt(16.W))
val rxd = Input(Bits(1.W))
val valid = Output(Bool())
val data = Output(Bits(8.W))
})
val CLCK_PER_BIT = dontTouch(Wire(UInt(32.W)))
CLCK_PER_BIT := io.CLK_PER_BIT
val idle :: start :: data :: stop :: cleanup :: Nil = Enum(5)
val stateReg = RegInit(idle)
val clockCount = RegInit(0.U(8.W))
val bitIndex = RegInit(0.U(4.W))
val validReg = RegInit(0.U(1.W))
//val dataReg = RegInit(VecInit(Seq.fill(8)(0.U(1.W))))
val rxReg = RegNext(RegNext(io.rxd, 1.U), 1.U)
val shiftReg = RegInit('A'.U(8.W))
switch(stateReg) {
is(idle) {
validReg := 0.U
clockCount := 0.U
bitIndex := 0.U
when(io.rxd === 0.U) {
stateReg := start
}.otherwise {
stateReg := idle
}
}
is(start) {
when(clockCount === ((CLCK_PER_BIT - 1.U) / 2.U)) {
when(io.rxd === 0.U) {
clockCount := 0.U
stateReg := data
}.otherwise {
stateReg := idle
}
}.otherwise {
clockCount := clockCount + 1.U
stateReg := start
}
}
is(data) {
when(clockCount < (CLCK_PER_BIT - 1.U)) {
clockCount := clockCount + 1.U
stateReg := data
}.otherwise {
clockCount := 0.U
shiftReg := Cat(rxReg, shiftReg >> 1)
//dataReg(bitIndex) := io.rxd
when(bitIndex < 7.U) {
bitIndex := bitIndex + 1.U
stateReg := data
}.otherwise {
bitIndex := 0.U
stateReg := stop
}
}
}
is(stop) {
when(clockCount < (CLCK_PER_BIT - 1.U)) {
clockCount := clockCount + 1.U
stateReg := stop
}.otherwise {
validReg := 1.U
clockCount := 0.U
stateReg := cleanup
}
}
is(cleanup) {
stateReg := idle
validReg := 0.U
}
}
io.data := shiftReg
//io.data := dataReg.asUInt()
io.valid := validReg
}