Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,13 @@ All notable changes to Vortex are documented here. The format is based on
follows the version pins recorded in [VERSION](VERSION) (`VORTEX_VERSION`,
`TOOLCHAIN_REV`, `GEM5_REV`).

## [Unreleased]

### Fixed

- **SimX cache flush walk raced a same-tick replay.** `processFlush()` gated on `TFifo::empty()`, which hides entries inside the pipe's latency window; the end-of-kernel walk could sweep a set before a store replayed from the MSHR that tick dirtied its line, and the write was lost. The guard now uses `size()`.
- **SimX arbiter input grouping.** `TxArbiter`/`TxRxArbiter` grouped inputs by `log2ceil(inputs / outputs)` where `VX_stream_arb` uses CDIV, so a request count that is not a multiple of the output count left the trailing inputs unserved.

## [3.0] — 2026-06-08

The 3.0 release introduces a fixed-function graphics stack (rasterizer, texture units, and output mergers), tensor core structured sparsity (2:4), warpgroup-level matrix multiplication (WGMMA), global-to-local data transfer acceleration (DXA), a new hardware kernel scheduler (KMU) and Command Processor (CP) architecture, a new asynchronous runtime API (`vortex2.h`), asynchronous barriers with arrive/wait/event semantics, compressed instruction set (RVC) support, hardware atomics, an MMU/SV32 virtual memory stack, a Mesa/lavapipe Vulkan backend (`vortexpipe`), HIP via chipStar, gem5 integration, a SimX v3 TLM architecture with fixed-size handshake channels, productized Synopsys and Yosys ASIC synthesis flows, and a refreshed toolchain (LLVM 20, POCL 7.0). Build and configuration infrastructure was reworked: TOML-driven HW configuration ([VX_config.toml](VX_config.toml) + [VX_types.toml](VX_types.toml)) decoupling SimX/runtime from the RTL source tree, a `VX_CFG_` macro namespace that resolves toolchain preprocessor collisions, retirement of the global `toolchain_env.sh` to enable parallel multi-version Vortex worktrees on the same shell, consolidation of `kernel/`/`runtime/` under a shared `sw/` root, a single-source [VERSION](VERSION) file driving CI toolchain pinning, Perfetto trace export ([ci/perfetto.py](ci/perfetto.py)), and new top-level [AGENTS.md](AGENTS.md) + [CONTRIBUTING.md](CONTRIBUTING.md) for AI-agent and contributor workflows.
Expand Down
7 changes: 5 additions & 2 deletions sim/simx/mem/cache.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1569,9 +1569,12 @@ class CacheBank : public SimObject<CacheBank> {
void processFlush() {
// Wait for in-flight requests to drain before walking lines, otherwise an
// outstanding fill could install a fresh line behind our scan and leave
// a dirty victim un-evicted.
// a dirty victim un-evicted. pipe_req_ occupancy must come from size():
// TFifo::empty() hides entries still inside the pipe's latency window, and
// a replayed store pushed this very tick would dirty its line behind the
// walk.
if (pending_fill_reqs_ != 0
|| !pipe_req_->empty()
|| pipe_req_->size() != 0
|| !mshr_.empty()) {
return;
}
Expand Down
4 changes: 2 additions & 2 deletions sim/simx/types.h
Original file line number Diff line number Diff line change
Expand Up @@ -1463,7 +1463,7 @@ class TxArbiter : public SimObject<TxArbiter<Type>> {
, Inputs(num_inputs, this)
, Outputs(num_outputs, this)
, delay_(delay)
, lg2_num_reqs_(log2ceil(num_inputs / num_outputs))
, lg2_num_reqs_(log2ceil((num_inputs + num_outputs - 1) / num_outputs))
, arbiters_(num_outputs, {type, 1u << lg2_num_reqs_})
{
assert(num_inputs <= 64);
Expand Down Expand Up @@ -1692,7 +1692,7 @@ class TxRxArbiter : public SimObject<TxRxArbiter<Req, Rsp>> {
, RspIn(num_outputs, this)
, arbiter_(nullptr)
, rsp_delay_(rsp_delay)
, lg2_num_reqs_(log2ceil(num_inputs / num_outputs))
, lg2_num_reqs_(log2ceil((num_inputs + num_outputs - 1) / num_outputs))
{
if (num_inputs != num_outputs) {
arbiter_ = ReqArb::Create(name, type, num_inputs, num_outputs, req_delay);
Expand Down