Add continuous mode to HNY2026

Implemented a new `continuous` flag in `HnyConfig` and added a `sent` register in `HNY2026` to track
whether the message has been fully transmitted. When `continuous` is `false`, the module stops
sending after one full cycle.
This commit is contained in:
Nikolay Puzanov 2026-01-10 17:22:59 +03:00
parent 7a6c9c4f24
commit 6ae8b4fc26
4 changed files with 36 additions and 6 deletions

View File

@ -143,13 +143,18 @@ class HNY2026(cfg: HnyConfig, str: String) extends Module {
val sender = Module(new CharSender(cfg)) val sender = Module(new CharSender(cfg))
val chars = VecInit(str.map(_.toByte.U(cfg.dataWidth.W))) val chars = VecInit(str.map(_.toByte.U(cfg.dataWidth.W)))
val charCnt = RegInit(UInt(log2Up(str.length()).W), 0.U) val charCnt = RegInit(UInt(log2Up(str.length()).W), 0.U)
val sent = RegInit(false.B)
sender.io.data.valid := true.B sender.io.data.valid := !sent
sender.io.data.bits := chars(charCnt) sender.io.data.bits := chars(charCnt)
when(sender.io.data.ready) { when(sender.io.data.ready) {
when(charCnt === (chars.length - 1).U) { when(charCnt === (chars.length - 1).U) {
charCnt := 0.U charCnt := 0.U
if(!cfg.continuous) {
sent := true.B
}
} otherwise { } otherwise {
charCnt := charCnt + 1.U charCnt := charCnt + 1.U
} }
@ -188,7 +193,8 @@ object HNY2026 extends App {
clockFreq = clockFreq, clockFreq = clockFreq,
frameRate = 30, frameRate = 30,
frameRateAccuracy = 0.0001, frameRateAccuracy = 0.0001,
dataWidth = 8 dataWidth = 8,
continuous = true
) )
ChiselStage.emitSystemVerilogFile( ChiselStage.emitSystemVerilogFile(

View File

@ -26,10 +26,13 @@ import chisel3.util._
* stream is `dataWidth + 2` bits, the * stream is `dataWidth + 2` bits, the
* additional bits being a parity bit and a * additional bits being a parity bit and a
* empty ending bit. * empty ending bit.
* @param continuous If true, the display will cycle continuously.
* If false, the display will show the message once and stop.
*/ */
case class HnyConfig( case class HnyConfig(
clockFreq: Int = 27000000, clockFreq: Int = 27000000,
frameRate: Double = 30.0, frameRate: Double = 30.0,
frameRateAccuracy: Double = 0.0001, frameRateAccuracy: Double = 0.0001,
dataWidth: Int = 8 dataWidth: Int = 8,
continuous: Boolean = true
) )

View File

@ -35,7 +35,20 @@ object TestGen_CharSender extends App {
*/ */
object TestGen_HNY2026 extends App { object TestGen_HNY2026 extends App {
println(ChiselStage.emitSystemVerilog( println(ChiselStage.emitSystemVerilog(
new HNY2026(HnyConfig(27000000, 30.3), "Hello!"), new HNY2026(HnyConfig(27000000, 30.3, continuous = false), "Hello!"),
firtoolOpts = Array(
"--disable-all-randomization",
"--strip-debug-info"
)
))
}
/**
* Run: mill hny2026.runMain hny2026.TestGen_HNY2026_Continuous
*/
object TestGen_HNY2026_Continuous extends App {
println(ChiselStage.emitSystemVerilog(
new HNY2026(HnyConfig(27000000, 30.3, continuous = true), "Hello!"),
firtoolOpts = Array( firtoolOpts = Array(
"--disable-all-randomization", "--disable-all-randomization",
"--strip-debug-info" "--strip-debug-info"

View File

@ -175,8 +175,16 @@ class HNY2026Test extends AnyFlatSpec with ChiselSim {
behavior of "HNY2026" behavior of "HNY2026"
it should s"send string '$str'" in { it should s"send string '$str' in non countinous mode" in {
simulate(new HNY2026(cfg, str)) { dut => simulate(new HNY2026(cfg.copy(continuous = false), str)) { dut =>
enableWaves()
dut.clock.step((cfg.clockFreq / cfg.frameRate * cfg.dataWidth * str.length() * 2).toInt)
println("See results in the wave diagram.")
}
}
it should s"send string '$str' in countinous mode" in {
simulate(new HNY2026(cfg.copy(continuous = true), str)) { dut =>
enableWaves() enableWaves()
dut.clock.step((cfg.clockFreq / cfg.frameRate * cfg.dataWidth * str.length() * 2).toInt) dut.clock.step((cfg.clockFreq / cfg.frameRate * cfg.dataWidth * str.length() * 2).toInt)
println("See results in the wave diagram.") println("See results in the wave diagram.")