Skip to content

Instantly share code, notes, and snippets.

@chick
Created November 3, 2020 04:37
Show Gist options
  • Save chick/f3135f0139541e5e404919a97720a2d0 to your computer and use it in GitHub Desktop.
Save chick/f3135f0139541e5e404919a97720a2d0 to your computer and use it in GitHub Desktop.
// SPDX-License-Identifier: Apache-2.0
package chiseltest.tests
package gbvga
import chisel3._
import chisel3.util._
import chisel3.experimental.BundleLiterals._
import chisel3.stage.{ChiselGeneratorAnnotation, ChiselStage}
import chiseltest.tests.gbvga.GbConst.{GBHEIGHT, GBWIDTH}
class VgaColors extends Bundle {
val red = UInt(6.W)
val green = UInt(6.W)
val blue = UInt(6.W)
}
object GbConst {
val GBWIDTH = 16384
val GBHEIGHT = 3
//...
/* "#9BBC0F"*/
val GB_GREEN0 = (new VgaColors()).Lit(_.red -> "h26".U(6.W),
_.green -> "h2F".U(6.W),
_.blue -> "h03".U(6.W))
/* "#8BAC0F"*/
val GB_GREEN1 = (new VgaColors()).Lit(_.red -> "h1E".U(6.W),
_.green -> "h27".U(6.W),
_.blue -> "h03".U(6.W))
/* "#306230"*/
val GB_GREEN2 = (new VgaColors()).Lit(_.red -> "h0C".U(6.W),
_.green -> "h18".U(6.W),
_.blue -> "h0C".U(6.W))
/*"#0F380F"*/
val GB_GREEN3 = (new VgaColors()).Lit(_.red -> "h03".U(6.W),
_.green -> "h0E".U(6.W),
_.blue -> "h03".U(6.W))
val GB_BLACK = (new VgaColors()).Lit(_.red -> "h26".U(6.W),
_.green -> "h2F".U(6.W),
_.blue -> "h03".U(6.W))
}
import GbConst._
class HVSync() extends Module {
val io = IO(new Bundle {
val hsync = Output(Bool())
val vsync = Output(Bool())
val display_on = Output(Bool())
})
io.hsync := true.B
io.vsync := true.B
io.display_on := true.B
}
class MemVga extends Module {
val io = IO(new Bundle {
/* memory read interface */
val mem_addr = Output(UInt((log2Ceil(GBWIDTH*GBHEIGHT)).W))
val mem_data = Input(UInt(2.W))
val mem_read = Output(Bool())
/* VGA output signals */
val vga_hsync = Output(Bool())
val vga_vsync = Output(Bool())
val vga_color = Output(new VgaColors())
})
val GbColors = VecInit(Array(GB_GREEN0, GB_GREEN1, GB_GREEN2, GB_GREEN3))
val vga_height = GBHEIGHT*2
val vga_width = GBWIDTH*2
val hvsync = Module(new HVSync()) // Synchronize VGA module
io.vga_hsync := hvsync.io.hsync
io.vga_vsync := hvsync.io.vsync
val gblines = RegInit(0.U((log2Ceil(GBWIDTH)).W))
val gbcols = RegInit(0.U((log2Ceil(GBHEIGHT)).W))
val gbpix = RegInit(0.U((log2Ceil(GBWIDTH*GBHEIGHT)).W))
/* state machine */
val sInit :: sPixInc :: sLineInc :: sWait :: Nil = Enum(4)
val state = RegInit(sInit)
switch(state) {
is(sInit) {
when(hvsync.io.display_on){
state := sPixInc
}
}
is(sPixInc) {
when(gbcols >= (GBWIDTH - 1).U &&
gblines <= (GBHEIGHT -1).U){
state := sLineInc
}
when(gblines > (GBHEIGHT - 1).U){
state := sWait
}
}
is(sLineInc) {
state := sWait
}
is(sWait) {
when(!hvsync.io.hsync){
when(gblines < GBHEIGHT.U) {
state := sPixInc
}
}
when(!hvsync.io.vsync){
state := sInit
}
}
}
/* pixel count */
when(hvsync.io.display_on){
when(state===sPixInc) {
gbpix := gbpix + 1.U
gbcols := gbcols + 1.U
}
when(state===sLineInc) {
gblines := gblines + 1.U
gbcols := 0.U
}
}
when(state===sInit) {
gbpix := 0.U
gbcols := 0.U
gblines := 0.U
}
/* Vga colors */
io.vga_color := GB_BLACK
when(hvsync.io.display_on && (state===sPixInc)){
io.vga_color := GbColors(io.mem_data)
// switch(io.mem_data) {
// is("b00".U) {
// io.vga_color := GB_GREEN0
// }
// is("b01".U) {
// io.vga_color := GB_GREEN1
// }
// is("b10".U) {
// io.vga_color := GB_GREEN2
// }
// is("b11".U) {
// io.vga_color := GB_GREEN3
// }
// }
}
/* Memory interface */
io.mem_addr := gbpix
io.mem_read := true.B
}
object MemVgaDriver extends App {
(new ChiselStage).execute(args,
Seq(ChiselGeneratorAnnotation(() => new MemVga())))
println((new ChiselStage).emitFirrtl(new MemVga()))
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment