mirror of
https://github.com/handsomezhuzhu/2025-yatcpu.git
synced 2026-02-20 20:10:14 +00:00
117 lines
3.3 KiB
Scala
117 lines
3.3 KiB
Scala
// Copyright 2021 Howard Lau
|
|
//
|
|
// 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.
|
|
|
|
package peripheral
|
|
|
|
import chisel3._
|
|
|
|
|
|
class VGASync extends Module {
|
|
val io = IO(new Bundle {
|
|
val hsync = Output(Bool())
|
|
val vsync = Output(Bool())
|
|
val video_on = Output(Bool())
|
|
val p_tick = Output(Bool())
|
|
val f_tick = Output(Bool())
|
|
val x = Output(UInt(10.W))
|
|
val y = Output(UInt(10.W))
|
|
})
|
|
|
|
val DisplayHorizontal = ScreenInfo.DisplayHorizontal
|
|
val DisplayVertical = ScreenInfo.DisplayVertical
|
|
|
|
val BorderLeft = 48
|
|
val BorderRight = 16
|
|
val BorderTop = 10
|
|
val BorderBottom = 33
|
|
|
|
val RetraceHorizontal = 96
|
|
val RetraceVertical = 2
|
|
|
|
val MaxHorizontal = DisplayHorizontal + BorderLeft + BorderRight + RetraceHorizontal - 1
|
|
val MaxVertical = DisplayVertical + BorderTop + BorderBottom + RetraceVertical - 1
|
|
|
|
val RetraceHorizontalStart = DisplayHorizontal + BorderRight
|
|
val RetraceHorizontalEnd = RetraceHorizontalStart + RetraceHorizontal - 1
|
|
|
|
val RetraceVerticalStart = DisplayVertical + BorderBottom
|
|
val RetraceVerticalEnd = RetraceVerticalStart + RetraceVertical - 1
|
|
|
|
val pixel = RegInit(UInt(2.W), 0.U)
|
|
val pixel_next = Wire(UInt(2.W))
|
|
val pixel_tick = Wire(Bool())
|
|
|
|
val v_count_reg = RegInit(UInt(10.W), 0.U)
|
|
val h_count_reg = RegInit(UInt(10.W), 0.U)
|
|
|
|
val v_count_next = Wire(UInt(10.W))
|
|
val h_count_next = Wire(UInt(10.W))
|
|
|
|
val vsync_reg = RegInit(Bool(), false.B)
|
|
val hsync_reg = RegInit(Bool(), false.B)
|
|
|
|
val vsync_next = Wire(Bool())
|
|
val hsync_next = Wire(Bool())
|
|
|
|
pixel_next := pixel + 1.U
|
|
pixel_tick := pixel === 0.U
|
|
|
|
h_count_next := Mux(
|
|
pixel_tick,
|
|
Mux(h_count_reg === MaxHorizontal.U, 0.U, h_count_reg + 1.U),
|
|
h_count_reg
|
|
)
|
|
|
|
v_count_next := Mux(
|
|
pixel_tick && h_count_reg === MaxHorizontal.U,
|
|
Mux(v_count_reg === MaxVertical.U, 0.U, v_count_reg + 1.U),
|
|
v_count_reg
|
|
)
|
|
|
|
hsync_next := h_count_reg >= RetraceHorizontalStart.U && h_count_reg <= RetraceHorizontalEnd.U
|
|
vsync_next := v_count_reg >= RetraceVerticalStart.U && v_count_reg <= RetraceVerticalEnd.U
|
|
|
|
pixel := pixel_next
|
|
hsync_reg := hsync_next
|
|
vsync_reg := vsync_next
|
|
v_count_reg := v_count_next
|
|
h_count_reg := h_count_next
|
|
|
|
io.video_on := h_count_reg < DisplayHorizontal.U && v_count_reg < DisplayVertical.U
|
|
io.hsync := hsync_reg
|
|
io.vsync := vsync_reg
|
|
io.x := h_count_reg
|
|
io.y := v_count_reg
|
|
io.p_tick := pixel_tick
|
|
io.f_tick := io.x === 0.U && io.y === 0.U
|
|
}
|
|
|
|
class VGADisplay extends Module {
|
|
val io = IO(new Bundle() {
|
|
val x = Output(UInt(16.W))
|
|
val y = Output(UInt(16.W))
|
|
val video_on = Output(Bool())
|
|
|
|
val hsync = Output(Bool())
|
|
val vsync = Output(Bool())
|
|
})
|
|
|
|
val sync = Module(new VGASync)
|
|
io.hsync := sync.io.hsync
|
|
io.vsync := sync.io.vsync
|
|
io.x := sync.io.x
|
|
io.y := sync.io.y
|
|
io.video_on := sync.io.y
|
|
}
|