1
0
Fork 0
sifive-blocks/src/main/scala/devices/terminal/Terminal.scala

116 lines
3.3 KiB
Scala

// See LICENSE for license details.
package sifive.blocks.devices.terminal
import Chisel._
import chisel3.core.{Input, Output}
import chisel3.experimental.{Analog, MultiIOModule}
import freechips.rocketchip.config.{Field, Parameters}
import freechips.rocketchip.diplomacy.{LazyModule, LazyModuleImp}
import freechips.rocketchip.regmapper._
import freechips.rocketchip.subsystem.{BaseSubsystem}
import freechips.rocketchip.tilelink._
import freechips.rocketchip.util.AsyncQueue
import sifive.blocks.util.NonBlockingEnqueue
case class TerminalParams (
address: BigInt
)
class TerminalSysIO extends Bundle {
val clk = Input(Clock())
val reset = Input(Bool())
}
class TerminalDVIIO extends Bundle {
val d = Output(Bits(12.W))
val clk_p = Output(Bits(1.W))
val clk_n = Output(Bits(1.W))
val hsync = Output(Bool())
val vsync = Output(Bool())
val de = Output(Bool())
val reset = Output(Bool())
val i2c_scl = Analog(1.W)
val i2c_sda = Analog(1.W)
}
class Terminal extends BlackBox {
val io = IO(new Bundle {
val sys = new TerminalSysIO
val dvi = new TerminalDVIIO
val write_enable = Input(Bool())
val write_data = Input(UInt(8.W))
})
override def desiredName: String = "terminal"
}
trait TerminalRegBundle extends Bundle {
val port_sys = new TerminalSysIO
val port_dvi = new TerminalDVIIO
}
trait TerminalRegModule extends MultiIOModule with HasRegMap {
val params: TerminalParams
val io: TerminalRegBundle
val term = Module(new Terminal)
io.port_sys <> term.io.sys
io.port_dvi <> term.io.dvi
val crossing = Module(new AsyncQueue(UInt(8.W), depth=1, safe=false))
crossing.io.enq_clock := clock
crossing.io.enq_reset := Bool(false)
crossing.io.deq_clock := io.port_sys.clk
crossing.io.deq_reset := Bool(false)
// wire up dequeue to terminal io
term.io.write_enable := crossing.io.deq.valid
term.io.write_data := crossing.io.deq.bits
crossing.io.deq.ready := Bool(true) // terminal can read at every cycle
regmap(
0 -> NonBlockingEnqueue(crossing.io.enq)
)
}
class TLTerminal(w: Int, params: TerminalParams)(implicit p: Parameters)
extends TLRegisterRouter (
params.address,
"terminal",
Seq("klemens,terminal0"),
beatBytes = w
)(
new TLRegBundle(params, _) with TerminalRegBundle
)(
new TLRegModule(params, _, _) with TerminalRegModule
)
//-- TerminalPeriphery
case object PeripheryTerminalKey extends Field[TerminalParams]
trait HasPeripheryTerminal { this: BaseSubsystem =>
val params = p(PeripheryTerminalKey)
val terminal_name = Some("terminal_0")
val terminal = LazyModule(new TLTerminal(pbus.beatBytes, params))
.suggestName(terminal_name)
pbus.toVariableWidthSlave(terminal_name) { terminal.node }
}
trait HasPeripheryTerminalBundle {
val terminal: TerminalSysIO
val dvi: TerminalDVIIO
}
trait HasPeripheryTerminalModuleImp extends LazyModuleImp with HasPeripheryTerminalBundle {
val outer: HasPeripheryTerminal
val terminal = IO(new TerminalSysIO)
val dvi = IO(new TerminalDVIIO)
// right sides defined in TerminalRegBundle
terminal <> outer.terminal.module.io.port_sys
dvi <> outer.terminal.module.io.port_dvi
}