diff options
Diffstat (limited to '')
| -rw-r--r-- | nix/flake.nix | 5 | ||||
| -rw-r--r-- | tb/interval_timer.cpp | 2 | ||||
| -rw-r--r-- | tb/jtag_uart.cpp | 110 | ||||
| -rw-r--r-- | tb/jtag_uart.hpp | 17 | ||||
| -rwxr-xr-x | tb/sim/sim.py | 2 | ||||
| -rw-r--r-- | tb/top/conspiracion.cpp | 20 |
6 files changed, 140 insertions, 16 deletions
diff --git a/nix/flake.nix b/nix/flake.nix index b9f443a..3a291fa 100644 --- a/nix/flake.nix +++ b/nix/flake.nix @@ -5,6 +5,7 @@ in { devShells."${system}".default = pkgs.mkShell { buildInputs = with pkgs; [ + ncurses openssl SDL2 ]; @@ -30,8 +31,8 @@ export CROSS_COMPILE=arm-none-eabi- export MAKEFLAGS="AR=gcc-ar" - export CXXFLAGS="-O3 -flto $(pkg-config --cflags sdl2)" - export LDFLAGS="-O3 -flto $(pkg-config --libs sdl2)" + export CXXFLAGS="-O3 -flto $(pkg-config --cflags sdl2 ncursesw)" + export LDFLAGS="-O3 -flto $(pkg-config --libs sdl2 ncursesw)" # <https://discourse.nixos.org/t/fonts-in-nix-installed-packages-on-a-non-nixos-system/5871/7> export LOCALE_ARCHIVE="${pkgs.glibcLocales}/lib/locale/locale-archive" diff --git a/tb/interval_timer.cpp b/tb/interval_timer.cpp index f593894..f790030 100644 --- a/tb/interval_timer.cpp +++ b/tb/interval_timer.cpp @@ -1,3 +1,5 @@ +#include <cstdint> + #include "avalon.hpp" #include "interval_timer.hpp" diff --git a/tb/jtag_uart.cpp b/tb/jtag_uart.cpp index 78d438e..3bef42e 100644 --- a/tb/jtag_uart.cpp +++ b/tb/jtag_uart.cpp @@ -1,3 +1,7 @@ +#include <cstdint> + +#include <ncursesw/ncurses.h> + #include "avalon.hpp" #include "jtag_uart.hpp" @@ -7,22 +11,87 @@ namespace taller::avalon : slave(base, 8, 4) {} + jtag_uart::~jtag_uart() noexcept + { + release(); + } + + void jtag_uart::tick() noexcept + { + if(!took_over || rx_avail == sizeof rx) + { + return; + } + + if(countdown > 0) + { + --countdown; + return; + } + + countdown = 10'000; + + int input = getch(); + if(input != ERR) + { + unsigned index = rx_next + rx_avail; + if(index >= sizeof rx) + { + index -= sizeof rx; + } + + rx[index] = input; + ++rx_avail; + } + + ctrl_ac = 1; + } + bool jtag_uart::read(std::uint32_t addr, std::uint32_t &data) noexcept { + bool valid_read; + bool ctrl_ri; + bool ctrl_wi; + bool ctrl_rrdy; + + std::uint8_t read; + switch(addr) { case 0: - data = 0; //TODO + read = rx[rx_next]; + valid_read = rx_avail > 0; + + if(valid_read) + { + --rx_avail; + rx_next = rx_next + 1 < sizeof rx ? rx_next + 1 : 0; + } + + data + = rx_avail << 16 + | valid_read << 15 + | (read & 0xff); + break; case 1: - data = - static_cast<std::uint32_t>(ctrl_re) << 0 - | static_cast<std::uint32_t>(ctrl_we) << 1 - //TODO: varios bits - | static_cast<std::uint32_t>(ctrl_ac) << 10 - //TODO: disponibilidad de tx fifo - | static_cast<std::uint32_t>(255) << 10; + ctrl_ri = ctrl_re && rx_avail > 0; + + // Siempre se puede escribir + ctrl_wi = ctrl_we; + + // Este bit no existe pero U-Boot lo espera por alguna razón + ctrl_rrdy = rx_avail > 0; + + data + = ctrl_re << 0 + | ctrl_we << 1 + | ctrl_ri << 8 + | ctrl_wi << 9 + | ctrl_ac << 10 + | ctrl_rrdy << 12 + | 63 << 16; break; } @@ -36,6 +105,8 @@ namespace taller::avalon { case 0: putchar(data & 0xff); + fflush(stdout); + ctrl_ac = 1; break; @@ -52,4 +123,27 @@ namespace taller::avalon return true; } + + void jtag_uart::takeover() noexcept + { + if(took_over) + { + return; + } + + assert(::initscr() != nullptr); + assert(::noecho() != ERR); + assert(::nodelay(stdscr, TRUE) != ERR); + assert(::cbreak() != ERR); + + took_over = true; + } + + void jtag_uart::release() noexcept + { + if(took_over) + { + ::endwin(); + } + } } diff --git a/tb/jtag_uart.hpp b/tb/jtag_uart.hpp index 6db50f8..3c378c3 100644 --- a/tb/jtag_uart.hpp +++ b/tb/jtag_uart.hpp @@ -11,14 +11,25 @@ namespace taller::avalon { public: jtag_uart(std::uint32_t base) noexcept; + ~jtag_uart() noexcept; + + void tick() noexcept; virtual bool read(std::uint32_t addr, std::uint32_t &data) noexcept final override; virtual bool write(std::uint32_t addr, std::uint32_t data, unsigned byte_enable) noexcept final override; + void takeover() noexcept; + void release() noexcept; + private: - bool ctrl_re = false; - bool ctrl_we = false; - bool ctrl_ac = true; + unsigned countdown = 0; + unsigned rx_avail = 0; + unsigned rx_next = 0; + bool ctrl_re = false; + bool ctrl_we = false; + bool ctrl_ac = true; + bool took_over = false; + std::uint8_t rx[64]; }; } diff --git a/tb/sim/sim.py b/tb/sim/sim.py index b14e0fd..91fc348 100755 --- a/tb/sim/sim.py +++ b/tb/sim/sim.py @@ -249,7 +249,7 @@ mem_dumps = module_get('mem_dumps', []) if init := module_get('init'): init() -exec_args = [verilated, '--headless', '--cycles', str(cycles), '--dump-regs'] +exec_args = [verilated, '--headless', '--no-tty', '--cycles', str(cycles), '--dump-regs'] for rng in mem_dumps: length = rng.stop - rng.start diff --git a/tb/top/conspiracion.cpp b/tb/top/conspiracion.cpp index d710bde..bf0ee89 100644 --- a/tb/top/conspiracion.cpp +++ b/tb/top/conspiracion.cpp @@ -192,6 +192,11 @@ int main(int argc, char **argv) parser, "headless", "Disable video output", {"headless"} ); + args::Flag no_tty + ( + parser, "no-tty", "Disable TTY takeoveer", {"no-tty"} + ); + args::ValueFlag<unsigned> cycles ( parser, "cycles", "Number of core cycles to run", {"cycles"}, 256 @@ -251,7 +256,7 @@ int main(int argc, char **argv) interconnect<Vconspiracion_vga_domain> avl_vga(*top.conspiracion->plat->vga); mem<std::uint32_t> hps_ddr3(0x0000'0000, 512 << 20); - jtag_uart ttyj0(0x3000'0000); + jtag_uart ttyJ0(0x3000'0000); interval_timer timer(0x3002'0000); mem<std::uint32_t> vram(0x3800'0000, 64 << 20); null vram_null(0x3800'0000, 64 << 20, 2); @@ -267,7 +272,7 @@ int main(int argc, char **argv) bool enable_video = !headless; avl.attach(hps_ddr3); - avl.attach(ttyj0); + avl.attach(ttyJ0); avl.attach(timer); for(auto &slave : consts) @@ -334,6 +339,7 @@ int main(int argc, char **argv) if(top.clk_clk) { + ttyJ0.tick(); timer.tick(); } @@ -364,6 +370,11 @@ int main(int argc, char **argv) tick(); }; + if(!no_tty) + { + ttyJ0.takeover(); + } + top.halt = 0; top.rst_n = 0; cycle(); @@ -378,6 +389,11 @@ int main(int argc, char **argv) } } + if(!no_tty) + { + ttyJ0.release(); + } + if(enable_trace) { trace.close(); |
