Compare commits
4 Commits
9e53a6ba43
...
12ddbeb508
Author | SHA1 | Date |
---|---|---|
David Anderson | 12ddbeb508 | |
David Anderson | eb2bb40fd3 | |
David Anderson | 76a1a36006 | |
David Anderson | f45ff0d105 |
|
@ -0,0 +1,190 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"math"
|
||||||
|
"strings"
|
||||||
|
"unicode"
|
||||||
|
|
||||||
|
tea "github.com/charmbracelet/bubbletea"
|
||||||
|
lip "github.com/charmbracelet/lipgloss"
|
||||||
|
"github.com/creachadair/mds/slice"
|
||||||
|
)
|
||||||
|
|
||||||
|
type HexViewUpdateMem struct {
|
||||||
|
addr int
|
||||||
|
bytes []byte
|
||||||
|
}
|
||||||
|
|
||||||
|
type HexView struct {
|
||||||
|
AddrStyle lip.Style
|
||||||
|
ZeroStyle lip.Style
|
||||||
|
HexStyle lip.Style
|
||||||
|
|
||||||
|
write func(int, byte) tea.Cmd
|
||||||
|
firstAddr int // top of viewport
|
||||||
|
bytes []byte
|
||||||
|
selectedAddr int
|
||||||
|
editing bool
|
||||||
|
editNibble int // 0 or 1
|
||||||
|
newByte byte
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewHexView(size int, writeByte func(addr int, val byte) tea.Cmd) HexView {
|
||||||
|
st := lip.NewStyle()
|
||||||
|
ret := HexView{
|
||||||
|
AddrStyle: st,
|
||||||
|
ZeroStyle: st,
|
||||||
|
HexStyle: st,
|
||||||
|
write: writeByte,
|
||||||
|
bytes: make([]byte, size),
|
||||||
|
}
|
||||||
|
return ret
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m HexView) Width() int {
|
||||||
|
hexdumpWidth := 16*3 + 2 // including spaces between dquads
|
||||||
|
addrWidth := m.addrNibbles() // Hex nibbles needed to represent all addrs
|
||||||
|
return addrWidth + 4 + hexdumpWidth
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m HexView) SelectedAddr() int {
|
||||||
|
return m.selectedAddr
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m HexView) addrFormat() string {
|
||||||
|
return fmt.Sprintf("%%%dx", m.addrNibbles())
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m HexView) addrNibbles() int {
|
||||||
|
return int(math.Ceil(math.Log2(float64(len(m.bytes)-1)))) / 4
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m HexView) Update(msg tea.Msg) (HexView, tea.Cmd) {
|
||||||
|
if m.editing {
|
||||||
|
return m.updateEditMode(msg)
|
||||||
|
} else {
|
||||||
|
return m.updateViewMode(msg)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m HexView) updateEditMode(msg tea.Msg) (HexView, tea.Cmd) {
|
||||||
|
switch msg := msg.(type) {
|
||||||
|
case HexViewUpdateMem:
|
||||||
|
copy(m.bytes[msg.addr:], msg.bytes)
|
||||||
|
case tea.KeyMsg:
|
||||||
|
switch msg.Type {
|
||||||
|
case tea.KeyLeft:
|
||||||
|
if m.editNibble == 1 {
|
||||||
|
m.editNibble = 0
|
||||||
|
}
|
||||||
|
case tea.KeyRight:
|
||||||
|
if m.editNibble == 0 {
|
||||||
|
m.editNibble = 1
|
||||||
|
}
|
||||||
|
case tea.KeyEsc:
|
||||||
|
m.editing = false
|
||||||
|
case tea.KeyEnter:
|
||||||
|
m.editing = false
|
||||||
|
return m, m.write(m.selectedAddr, m.newByte)
|
||||||
|
case tea.KeyRunes:
|
||||||
|
if unicode.In(msg.Runes[0], unicode.ASCII_Hex_Digit) {
|
||||||
|
nibble := hexToNibble(msg.Runes[0])
|
||||||
|
if m.editNibble == 0 {
|
||||||
|
m.newByte = (nibble << 4) + (m.newByte & 0xF)
|
||||||
|
m.editNibble++
|
||||||
|
} else {
|
||||||
|
m.newByte = (m.newByte & 0xF0) + nibble
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return m, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func hexToNibble(r rune) byte {
|
||||||
|
switch {
|
||||||
|
case r >= '0' && r <= '9':
|
||||||
|
return byte(r - '0')
|
||||||
|
case r >= 'a' && r <= 'f':
|
||||||
|
return byte(r - 'a' + 10)
|
||||||
|
case r >= 'A' && r <= 'F':
|
||||||
|
return byte(r - 'A' + 10)
|
||||||
|
}
|
||||||
|
panic("invalid hex rune")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m HexView) updateViewMode(msg tea.Msg) (HexView, tea.Cmd) {
|
||||||
|
switch msg := msg.(type) {
|
||||||
|
case HexViewUpdateMem:
|
||||||
|
copy(m.bytes[msg.addr:], msg.bytes)
|
||||||
|
case tea.KeyMsg:
|
||||||
|
switch msg.String() {
|
||||||
|
case "up":
|
||||||
|
if m.selectedAddr >= 16 {
|
||||||
|
m.selectedAddr -= 16
|
||||||
|
}
|
||||||
|
case "down":
|
||||||
|
if m.selectedAddr < len(m.bytes)-16 {
|
||||||
|
m.selectedAddr += 16
|
||||||
|
}
|
||||||
|
case "left":
|
||||||
|
if m.selectedAddr > 0 {
|
||||||
|
m.selectedAddr--
|
||||||
|
}
|
||||||
|
case "right":
|
||||||
|
if m.selectedAddr < len(m.bytes)-1 {
|
||||||
|
m.selectedAddr++
|
||||||
|
}
|
||||||
|
case "pgdown":
|
||||||
|
// TODO
|
||||||
|
case "pgup":
|
||||||
|
// TODO
|
||||||
|
case "w":
|
||||||
|
m.editing = true
|
||||||
|
m.editNibble = 0
|
||||||
|
m.newByte = m.bytes[m.selectedAddr]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return m, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m HexView) View(height int) string {
|
||||||
|
maxLen := 16 * height
|
||||||
|
endAddr := min(len(m.bytes), m.firstAddr+maxLen)
|
||||||
|
var ret strings.Builder
|
||||||
|
addrFormat := m.addrFormat()
|
||||||
|
for line, bytes := range slice.Chunks(m.bytes[m.firstAddr:endAddr], 16) {
|
||||||
|
lineAddr := m.firstAddr + (16 * line)
|
||||||
|
ret.WriteString(m.AddrStyle.Render(fmt.Sprintf(addrFormat, lineAddr)))
|
||||||
|
ret.WriteString(" ")
|
||||||
|
for i, b := range bytes {
|
||||||
|
byteAddr := lineAddr + i
|
||||||
|
if i == 8 {
|
||||||
|
ret.WriteString(" ")
|
||||||
|
} else if i != 0 {
|
||||||
|
ret.WriteByte(' ')
|
||||||
|
}
|
||||||
|
if m.editing && byteAddr == m.selectedAddr {
|
||||||
|
st := m.HexStyle.Underline(true)
|
||||||
|
s1, s2 := st.Reverse(true), st
|
||||||
|
if m.editNibble == 1 {
|
||||||
|
s1, s2 = s2, s1
|
||||||
|
}
|
||||||
|
b = m.newByte
|
||||||
|
ret.WriteString(s1.Render(fmt.Sprintf("%01x", b>>4)))
|
||||||
|
ret.WriteString(s2.Render(fmt.Sprintf("%01x", b&0xF)))
|
||||||
|
} else {
|
||||||
|
st := m.HexStyle
|
||||||
|
if m.selectedAddr == byteAddr {
|
||||||
|
st = m.HexStyle.Reverse(true)
|
||||||
|
} else if b == 0 {
|
||||||
|
st = m.ZeroStyle
|
||||||
|
}
|
||||||
|
ret.WriteString(st.Render(fmt.Sprintf("%02x", b)))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ret.WriteByte('\n')
|
||||||
|
}
|
||||||
|
return strings.TrimRight(ret.String(), "\n")
|
||||||
|
}
|
|
@ -19,15 +19,13 @@ func main() {
|
||||||
}
|
}
|
||||||
defer dbg.Close()
|
defer dbg.Close()
|
||||||
|
|
||||||
fmt.Println("Writing...")
|
|
||||||
if err := dbg.Write(0x42, 123); err != nil {
|
if err := dbg.Write(0x42, 123); err != nil {
|
||||||
log.Fatalf("writing to memory: %v", err)
|
log.Fatalf("writing to memory: %v", err)
|
||||||
}
|
}
|
||||||
v, err := dbg.Read(0x42)
|
|
||||||
if err != nil {
|
if err := UI(dbg); err != nil {
|
||||||
log.Fatalf("reading from memory: %v", err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
fmt.Printf("addr 0: %02x\n", v)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type Debugger struct {
|
type Debugger struct {
|
||||||
|
@ -73,7 +71,7 @@ func (d *Debugger) Read(addr int) (byte, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
packet := encode(addr, false, 0)
|
packet := encode(addr, false, 0)
|
||||||
fmt.Printf("Writing: %02x %02x %02x %02x\n", packet[0], packet[1], packet[2], packet[3])
|
//fmt.Printf("Writing: %02x %02x %02x %02x\n", packet[0], packet[1], packet[2], packet[3])
|
||||||
if _, err := d.port.Write(packet[:]); err != nil {
|
if _, err := d.port.Write(packet[:]); err != nil {
|
||||||
return 0, err
|
return 0, err
|
||||||
}
|
}
|
||||||
|
@ -97,9 +95,21 @@ func (d *Debugger) Write(addr int, val byte) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
packet := encode(addr, true, val)
|
packet := encode(addr, true, val)
|
||||||
fmt.Printf("Writing: %02x %02x %02x %02x\n", packet[0], packet[1], packet[2], packet[3])
|
//fmt.Printf("Writing: %02x %02x %02x %02x\n", packet[0], packet[1], packet[2], packet[3])
|
||||||
if _, err := d.port.Write(packet[:]); err != nil {
|
if _, err := d.port.Write(packet[:]); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (d *Debugger) Dump(startAddr int, count int) ([]byte, error) {
|
||||||
|
ret := make([]byte, count)
|
||||||
|
var err error
|
||||||
|
for i := range ret {
|
||||||
|
ret[i], err = d.Read(startAddr + i)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ret, nil
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,201 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"strings"
|
||||||
|
"unicode"
|
||||||
|
|
||||||
|
tea "github.com/charmbracelet/bubbletea"
|
||||||
|
lip "github.com/charmbracelet/lipgloss"
|
||||||
|
)
|
||||||
|
|
||||||
|
func UI(dbg *Debugger) error {
|
||||||
|
p := tea.NewProgram(initialModel(dbg)) //failed{0, 0, true}, tea.WithAltScreen())
|
||||||
|
if _, err := p.Run(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
var (
|
||||||
|
amber = lip.Color("#ffb00")
|
||||||
|
slate = lip.Color("235")
|
||||||
|
text = lip.NewStyle().Foreground(amber).Background(slate)
|
||||||
|
faintText = text.Faint(true)
|
||||||
|
box = text.Border(lip.NormalBorder(), true, true, true, true).
|
||||||
|
BorderForeground(amber).
|
||||||
|
BorderBackground(slate)
|
||||||
|
)
|
||||||
|
|
||||||
|
type msgErr struct {
|
||||||
|
err error
|
||||||
|
}
|
||||||
|
|
||||||
|
type msgUpdateStatus struct {
|
||||||
|
status string
|
||||||
|
}
|
||||||
|
|
||||||
|
type debugger struct {
|
||||||
|
width int
|
||||||
|
height int
|
||||||
|
dbg *Debugger
|
||||||
|
hex HexView
|
||||||
|
lastErr error
|
||||||
|
bottomMsg string
|
||||||
|
}
|
||||||
|
|
||||||
|
func initialModel(dbg *Debugger) debugger {
|
||||||
|
ret := debugger{
|
||||||
|
width: 0,
|
||||||
|
height: 0,
|
||||||
|
dbg: dbg,
|
||||||
|
bottomMsg: "",
|
||||||
|
}
|
||||||
|
hex := NewHexView(128*1024, ret.writeByte)
|
||||||
|
hex.AddrStyle = text
|
||||||
|
hex.ZeroStyle = faintText
|
||||||
|
hex.HexStyle = text
|
||||||
|
ret.hex = hex
|
||||||
|
return ret
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m debugger) Init() tea.Cmd {
|
||||||
|
return m.dumpMemory(0x200)
|
||||||
|
}
|
||||||
|
|
||||||
|
func staticMsg(msg tea.Msg) tea.Cmd {
|
||||||
|
return func() tea.Msg {
|
||||||
|
return msg
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m debugger) dumpMemory(count int) tea.Cmd {
|
||||||
|
var ret []tea.Cmd
|
||||||
|
for i := 0; i < count; i += 16 {
|
||||||
|
ret = append(ret, func() tea.Msg {
|
||||||
|
mem, err := m.dbg.Dump(i, 16)
|
||||||
|
if err != nil {
|
||||||
|
return msgErr{err}
|
||||||
|
}
|
||||||
|
return HexViewUpdateMem{i, mem}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
return tea.Sequence(ret...)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m debugger) writeByte(addr int, val byte) tea.Cmd {
|
||||||
|
return tea.Sequence(
|
||||||
|
staticMsg(msgUpdateStatus{"Writing..."}),
|
||||||
|
func() tea.Msg {
|
||||||
|
if err := m.dbg.Write(addr, val); err != nil {
|
||||||
|
return msgUpdateStatus{fmt.Sprintf("Write failed: %v", err)}
|
||||||
|
}
|
||||||
|
return tea.BatchMsg{
|
||||||
|
staticMsg(HexViewUpdateMem{addr, []byte{val}}),
|
||||||
|
staticMsg(msgUpdateStatus{"Written!"}),
|
||||||
|
}
|
||||||
|
},
|
||||||
|
m.dumpMemory(0x200),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m debugger) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
|
||||||
|
switch msg := msg.(type) {
|
||||||
|
case tea.WindowSizeMsg:
|
||||||
|
m.width = msg.Width
|
||||||
|
m.height = msg.Height
|
||||||
|
case tea.KeyMsg:
|
||||||
|
switch msg.String() {
|
||||||
|
case "ctrl+c", "q":
|
||||||
|
return m, tea.Quit
|
||||||
|
case "r":
|
||||||
|
return m, m.dumpMemory(0x200)
|
||||||
|
}
|
||||||
|
case msgErr:
|
||||||
|
m.lastErr = msg.err
|
||||||
|
return m, nil
|
||||||
|
case msgUpdateStatus:
|
||||||
|
m.bottomMsg = msg.status
|
||||||
|
}
|
||||||
|
var cmd tea.Cmd
|
||||||
|
m.hex, cmd = m.hex.Update(msg)
|
||||||
|
return m, cmd
|
||||||
|
}
|
||||||
|
|
||||||
|
// func (m debugger) values(addr int) string {
|
||||||
|
// var v [4]byte
|
||||||
|
// copy(v[:], m.vram[addr:])
|
||||||
|
// var out strings.Builder
|
||||||
|
// out.WriteString(text.Render("Bin: "))
|
||||||
|
// out.WriteString(renderBytes(v[:], "%08b", "_"))
|
||||||
|
// out.WriteByte('\n')
|
||||||
|
// out.WriteString(text.Render("Hex: "))
|
||||||
|
// out.WriteString(renderBytes(v[:], "%02x", "_"))
|
||||||
|
// out.WriteByte('\n')
|
||||||
|
// out.WriteString(text.Render("Dec: "))
|
||||||
|
// out.WriteString(faintText.Render("["))
|
||||||
|
// out.WriteString(dimZero(fmt.Sprintf("%3d", v[0])))
|
||||||
|
// out.WriteString(faintText.Render("] ["))
|
||||||
|
// out.WriteString(dimZero(fmt.Sprintf("%5d", binary.BigEndian.Uint16(v[:]))))
|
||||||
|
// out.WriteString(faintText.Render("] ["))
|
||||||
|
// out.WriteString(dimZero(fmt.Sprintf("%10d", binary.BigEndian.Uint32(v[:]))))
|
||||||
|
// out.WriteString(faintText.Render("]"))
|
||||||
|
|
||||||
|
// return out.String()
|
||||||
|
// }
|
||||||
|
|
||||||
|
func (m debugger) View() string {
|
||||||
|
if m.width < 80 || m.height < 20 {
|
||||||
|
return lip.Place(m.width, m.height, lip.Center, lip.Center, "Please embiggen your terminal")
|
||||||
|
}
|
||||||
|
|
||||||
|
statusBar := text.Width(m.width).Height(1).Align(lip.Center)
|
||||||
|
topSegment := statusBar.Width(m.width / 3).Reverse(true)
|
||||||
|
|
||||||
|
hexBox := lip.NewStyle().Border(lip.NormalBorder()).BorderForeground(amber).BorderBackground(slate).Padding(1, 2)
|
||||||
|
hexHeight := m.height - 2 - hexBox.GetVerticalFrameSize()
|
||||||
|
hex := hexBox.Render(m.hex.View(hexHeight))
|
||||||
|
|
||||||
|
topLeft := text.Reverse(true).Bold(true).Render("Addr: ") + text.Reverse(true).Render(fmt.Sprintf("0x%-5x", m.hex.SelectedAddr()))
|
||||||
|
topLeft = topSegment.Padding(0, 1).Align(lip.Left).Render(topLeft)
|
||||||
|
topMid := topSegment.Bold(true).Render("GARY Debugger")
|
||||||
|
topRight := topSegment.Render("")
|
||||||
|
topStatus := lip.JoinHorizontal(lip.Top, topLeft, topMid, topRight)
|
||||||
|
bottomStatus := statusBar.Render(m.bottomMsg)
|
||||||
|
|
||||||
|
top := lip.JoinVertical(lip.Center, topStatus, hex, bottomStatus)
|
||||||
|
return top
|
||||||
|
}
|
||||||
|
|
||||||
|
func renderByte(b byte, format string) string {
|
||||||
|
ret := fmt.Sprintf(format, b)
|
||||||
|
if b == 0 {
|
||||||
|
return faintText.Render(ret)
|
||||||
|
}
|
||||||
|
return text.Render(ret)
|
||||||
|
}
|
||||||
|
|
||||||
|
func renderBytes(bs []byte, format string, sep string) string {
|
||||||
|
var s strings.Builder
|
||||||
|
for i, b := range bs {
|
||||||
|
s.WriteString(renderByte(b, format))
|
||||||
|
if i < len(bs)-1 {
|
||||||
|
s.WriteString(faintText.Render(sep))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return s.String()
|
||||||
|
}
|
||||||
|
|
||||||
|
func dimZero(s string) string {
|
||||||
|
allZero := true
|
||||||
|
for _, r := range s {
|
||||||
|
if !unicode.IsSpace(r) && r != '0' {
|
||||||
|
allZero = false
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if allZero {
|
||||||
|
return faintText.Render(s)
|
||||||
|
}
|
||||||
|
return text.Render(s)
|
||||||
|
}
|
|
@ -20,7 +20,7 @@
|
||||||
dfu-util
|
dfu-util
|
||||||
fujprog
|
fujprog
|
||||||
git
|
git
|
||||||
go_1_22
|
go_1_23
|
||||||
gotools
|
gotools
|
||||||
gtkwave
|
gtkwave
|
||||||
imagemagick
|
imagemagick
|
||||||
|
|
32
go.mod
32
go.mod
|
@ -1,9 +1,33 @@
|
||||||
module git.sentinel65x.com/dave/gary
|
module git.sentinel65x.com/dave/gary
|
||||||
|
|
||||||
go 1.22.6
|
go 1.23
|
||||||
|
|
||||||
|
toolchain go1.23.0
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/creack/goselect v0.1.2 // indirect
|
github.com/charmbracelet/bubbles v0.20.0
|
||||||
go.bug.st/serial v1.6.2 // indirect
|
github.com/charmbracelet/bubbletea v1.1.1
|
||||||
golang.org/x/sys v0.0.0-20220829200755-d48e67d00261 // indirect
|
github.com/charmbracelet/lipgloss v0.13.0
|
||||||
|
github.com/creachadair/mds v0.21.2
|
||||||
|
go.bug.st/serial v1.6.2
|
||||||
|
)
|
||||||
|
|
||||||
|
require (
|
||||||
|
github.com/atotto/clipboard v0.1.4 // indirect
|
||||||
|
github.com/aymanbagabas/go-osc52/v2 v2.0.1 // indirect
|
||||||
|
github.com/charmbracelet/x/ansi v0.2.3 // indirect
|
||||||
|
github.com/charmbracelet/x/term v0.2.0 // indirect
|
||||||
|
github.com/creack/goselect v0.1.2 // indirect
|
||||||
|
github.com/erikgeiser/coninput v0.0.0-20211004153227-1c3628e74d0f // indirect
|
||||||
|
github.com/lucasb-eyer/go-colorful v1.2.0 // indirect
|
||||||
|
github.com/mattn/go-isatty v0.0.20 // indirect
|
||||||
|
github.com/mattn/go-localereader v0.0.1 // indirect
|
||||||
|
github.com/mattn/go-runewidth v0.0.16 // indirect
|
||||||
|
github.com/muesli/ansi v0.0.0-20230316100256-276c6243b2f6 // indirect
|
||||||
|
github.com/muesli/cancelreader v0.2.2 // indirect
|
||||||
|
github.com/muesli/termenv v0.15.2 // indirect
|
||||||
|
github.com/rivo/uniseg v0.4.7 // indirect
|
||||||
|
golang.org/x/sync v0.8.0 // indirect
|
||||||
|
golang.org/x/sys v0.24.0 // indirect
|
||||||
|
golang.org/x/text v0.3.8 // indirect
|
||||||
)
|
)
|
||||||
|
|
45
go.sum
45
go.sum
|
@ -1,6 +1,51 @@
|
||||||
|
github.com/atotto/clipboard v0.1.4 h1:EH0zSVneZPSuFR11BlR9YppQTVDbh5+16AmcJi4g1z4=
|
||||||
|
github.com/atotto/clipboard v0.1.4/go.mod h1:ZY9tmq7sm5xIbd9bOK4onWV4S6X0u6GY7Vn0Yu86PYI=
|
||||||
|
github.com/aymanbagabas/go-osc52/v2 v2.0.1 h1:HwpRHbFMcZLEVr42D4p7XBqjyuxQH5SMiErDT4WkJ2k=
|
||||||
|
github.com/aymanbagabas/go-osc52/v2 v2.0.1/go.mod h1:uYgXzlJ7ZpABp8OJ+exZzJJhRNQ2ASbcXHWsFqH8hp8=
|
||||||
|
github.com/charmbracelet/bubbles v0.20.0 h1:jSZu6qD8cRQ6k9OMfR1WlM+ruM8fkPWkHvQWD9LIutE=
|
||||||
|
github.com/charmbracelet/bubbles v0.20.0/go.mod h1:39slydyswPy+uVOHZ5x/GjwVAFkCsV8IIVy+4MhzwwU=
|
||||||
|
github.com/charmbracelet/bubbletea v1.1.1 h1:KJ2/DnmpfqFtDNVTvYZ6zpPFL9iRCRr0qqKOCvppbPY=
|
||||||
|
github.com/charmbracelet/bubbletea v1.1.1/go.mod h1:9Ogk0HrdbHolIKHdjfFpyXJmiCzGwy+FesYkZr7hYU4=
|
||||||
|
github.com/charmbracelet/lipgloss v0.13.0 h1:4X3PPeoWEDCMvzDvGmTajSyYPcZM4+y8sCA/SsA3cjw=
|
||||||
|
github.com/charmbracelet/lipgloss v0.13.0/go.mod h1:nw4zy0SBX/F/eAO1cWdcvy6qnkDUxr8Lw7dvFrAIbbY=
|
||||||
|
github.com/charmbracelet/x/ansi v0.2.3 h1:VfFN0NUpcjBRd4DnKfRaIRo53KRgey/nhOoEqosGDEY=
|
||||||
|
github.com/charmbracelet/x/ansi v0.2.3/go.mod h1:dk73KoMTT5AX5BsX0KrqhsTqAnhZZoCBjs7dGWp4Ktw=
|
||||||
|
github.com/charmbracelet/x/term v0.2.0 h1:cNB9Ot9q8I711MyZ7myUR5HFWL/lc3OpU8jZ4hwm0x0=
|
||||||
|
github.com/charmbracelet/x/term v0.2.0/go.mod h1:GVxgxAbjUrmpvIINHIQnJJKpMlHiZ4cktEQCN6GWyF0=
|
||||||
|
github.com/creachadair/mds v0.21.2 h1:D5130qi/kqmu+gGUQyDNOhrocGQp075ziTCgttxhh3k=
|
||||||
|
github.com/creachadair/mds v0.21.2/go.mod h1:1ltMWZd9yXhaHEoZwBialMaviWVUpRPvMwVP7saFAzM=
|
||||||
github.com/creack/goselect v0.1.2 h1:2DNy14+JPjRBgPzAd1thbQp4BSIihxcBf0IXhQXDRa0=
|
github.com/creack/goselect v0.1.2 h1:2DNy14+JPjRBgPzAd1thbQp4BSIihxcBf0IXhQXDRa0=
|
||||||
github.com/creack/goselect v0.1.2/go.mod h1:a/NhLweNvqIYMuxcMOuWY516Cimucms3DglDzQP3hKY=
|
github.com/creack/goselect v0.1.2/go.mod h1:a/NhLweNvqIYMuxcMOuWY516Cimucms3DglDzQP3hKY=
|
||||||
|
github.com/erikgeiser/coninput v0.0.0-20211004153227-1c3628e74d0f h1:Y/CXytFA4m6baUTXGLOoWe4PQhGxaX0KpnayAqC48p4=
|
||||||
|
github.com/erikgeiser/coninput v0.0.0-20211004153227-1c3628e74d0f/go.mod h1:vw97MGsxSvLiUE2X8qFplwetxpGLQrlU1Q9AUEIzCaM=
|
||||||
|
github.com/lucasb-eyer/go-colorful v1.2.0 h1:1nnpGOrhyZZuNyfu1QjKiUICQ74+3FNCN69Aj6K7nkY=
|
||||||
|
github.com/lucasb-eyer/go-colorful v1.2.0/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0=
|
||||||
|
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
|
||||||
|
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
|
||||||
|
github.com/mattn/go-localereader v0.0.1 h1:ygSAOl7ZXTx4RdPYinUpg6W99U8jWvWi9Ye2JC/oIi4=
|
||||||
|
github.com/mattn/go-localereader v0.0.1/go.mod h1:8fBrzywKY7BI3czFoHkuzRoWE9C+EiG4R1k4Cjx5p88=
|
||||||
|
github.com/mattn/go-runewidth v0.0.15 h1:UNAjwbU9l54TA3KzvqLGxwWjHmMgBUVhBiTjelZgg3U=
|
||||||
|
github.com/mattn/go-runewidth v0.0.15/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
|
||||||
|
github.com/mattn/go-runewidth v0.0.16 h1:E5ScNMtiwvlvB5paMFdw9p4kSQzbXFikJ5SQO6TULQc=
|
||||||
|
github.com/mattn/go-runewidth v0.0.16/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
|
||||||
|
github.com/muesli/ansi v0.0.0-20230316100256-276c6243b2f6 h1:ZK8zHtRHOkbHy6Mmr5D264iyp3TiX5OmNcI5cIARiQI=
|
||||||
|
github.com/muesli/ansi v0.0.0-20230316100256-276c6243b2f6/go.mod h1:CJlz5H+gyd6CUWT45Oy4q24RdLyn7Md9Vj2/ldJBSIo=
|
||||||
|
github.com/muesli/cancelreader v0.2.2 h1:3I4Kt4BQjOR54NavqnDogx/MIoWBFa0StPA8ELUXHmA=
|
||||||
|
github.com/muesli/cancelreader v0.2.2/go.mod h1:3XuTXfFS2VjM+HTLZY9Ak0l6eUKfijIfMUZ4EgX0QYo=
|
||||||
|
github.com/muesli/termenv v0.15.2 h1:GohcuySI0QmI3wN8Ok9PtKGkgkFIk7y6Vpb5PvrY+Wo=
|
||||||
|
github.com/muesli/termenv v0.15.2/go.mod h1:Epx+iuz8sNs7mNKhxzH4fWXGNpZwUaJKRS1noLXviQ8=
|
||||||
|
github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
|
||||||
|
github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ=
|
||||||
|
github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88=
|
||||||
go.bug.st/serial v1.6.2 h1:kn9LRX3sdm+WxWKufMlIRndwGfPWsH1/9lCWXQCasq8=
|
go.bug.st/serial v1.6.2 h1:kn9LRX3sdm+WxWKufMlIRndwGfPWsH1/9lCWXQCasq8=
|
||||||
go.bug.st/serial v1.6.2/go.mod h1:UABfsluHAiaNI+La2iESysd9Vetq7VRdpxvjx7CmmOE=
|
go.bug.st/serial v1.6.2/go.mod h1:UABfsluHAiaNI+La2iESysd9Vetq7VRdpxvjx7CmmOE=
|
||||||
|
golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ=
|
||||||
|
golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
|
||||||
|
golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.0.0-20220829200755-d48e67d00261 h1:v6hYoSR9T5oet+pMXwUWkbiVqx/63mlHjefrHmxwfeY=
|
golang.org/x/sys v0.0.0-20220829200755-d48e67d00261 h1:v6hYoSR9T5oet+pMXwUWkbiVqx/63mlHjefrHmxwfeY=
|
||||||
golang.org/x/sys v0.0.0-20220829200755-d48e67d00261/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.0.0-20220829200755-d48e67d00261/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
|
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
|
golang.org/x/sys v0.24.0 h1:Twjiwq9dn6R1fQcyiK+wQyHWfaz/BJB+YIpzU/Cv3Xg=
|
||||||
|
golang.org/x/sys v0.24.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||||
|
golang.org/x/text v0.3.8 h1:nAL+RVCQ9uMn3vJZbV+MRnydTJFPf8qqY42YiA6MrqY=
|
||||||
|
golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ=
|
||||||
|
|
|
@ -457,7 +457,10 @@ module mkEBRCore#(EBRPortConfig cfgA,
|
||||||
if (!rcfgA.enabled)
|
if (!rcfgA.enabled)
|
||||||
noAction;
|
noAction;
|
||||||
else
|
else
|
||||||
vEBR.portA.put(chip_select, write, zeroExtend(pack(address)), zeroExtend(pack(datain)));
|
vEBR.portA.put(chip_select,
|
||||||
|
write,
|
||||||
|
zeroExtend(pack(address)) << valueOf(addr_a_pad),
|
||||||
|
zeroExtend(pack(datain)));
|
||||||
endmethod
|
endmethod
|
||||||
method data_a read();
|
method data_a read();
|
||||||
if (!rcfgA.enabled)
|
if (!rcfgA.enabled)
|
||||||
|
@ -472,7 +475,10 @@ module mkEBRCore#(EBRPortConfig cfgA,
|
||||||
if (!rcfgB.enabled)
|
if (!rcfgB.enabled)
|
||||||
noAction;
|
noAction;
|
||||||
else
|
else
|
||||||
vEBR.portB.put(chip_select, write, zeroExtend(pack(address)), zeroExtend(pack(datain)));
|
vEBR.portB.put(chip_select,
|
||||||
|
write,
|
||||||
|
zeroExtend(pack(address)) << valueOf(addr_b_pad),
|
||||||
|
zeroExtend(pack(datain)));
|
||||||
endmethod
|
endmethod
|
||||||
method data_b read();
|
method data_b read();
|
||||||
if (!rcfgB.enabled)
|
if (!rcfgB.enabled)
|
||||||
|
|
|
@ -105,6 +105,7 @@ module mkTestFull(FSM);
|
||||||
|
|
||||||
let fsm <- mkFSM(seq
|
let fsm <- mkFSM(seq
|
||||||
dut.cpu.request.put(VRAMRequest{addr: 1, data: tagged Valid 42});
|
dut.cpu.request.put(VRAMRequest{addr: 1, data: tagged Valid 42});
|
||||||
|
dut.cpu.request.put(VRAMRequest{addr: 2, data: tagged Valid 45});
|
||||||
dut.cpu.request.put(VRAMRequest{addr: 1, data: tagged Invalid});
|
dut.cpu.request.put(VRAMRequest{addr: 1, data: tagged Invalid});
|
||||||
action
|
action
|
||||||
let resp <- dut.cpu.response.get();
|
let resp <- dut.cpu.response.get();
|
||||||
|
@ -112,6 +113,13 @@ module mkTestFull(FSM);
|
||||||
$display("vram read: ", fshow(resp));
|
$display("vram read: ", fshow(resp));
|
||||||
dynamicAssert(resp.data == 42, "wrong data read after writing");
|
dynamicAssert(resp.data == 42, "wrong data read after writing");
|
||||||
endaction
|
endaction
|
||||||
|
dut.cpu.request.put(VRAMRequest{addr: 2, data: tagged Invalid});
|
||||||
|
action
|
||||||
|
let resp <- dut.cpu.response.get();
|
||||||
|
if (testflags.verbose)
|
||||||
|
$display("vram read: ", fshow(resp));
|
||||||
|
dynamicAssert(resp.data == 45, "wrong data read after writing");
|
||||||
|
endaction
|
||||||
endseq);
|
endseq);
|
||||||
return fsm;
|
return fsm;
|
||||||
endmodule
|
endmodule
|
||||||
|
|
Loading…
Reference in New Issue