Skip to content
Draft
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
9 changes: 9 additions & 0 deletions .claude/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"permissions": {
"allow": [
"WebFetch(domain:github.com)",
"Bash(buck2 cquery:*)",
"Bash(BSV_LIB_DIR=/custom/test/path buck2 audit config:*)"
]
}
}
28 changes: 26 additions & 2 deletions hdl/ip/bsv/BUCK
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ bsv_library(
srcs = ["SettableCRC.bsv"],
)

# Generate git version BSV file
# Generate git version BSV file (legacy, kept for cobble compatibility)
genrule(
name = "git_version_bsv",
visibility = ["PUBLIC"],
Expand All @@ -40,13 +40,37 @@ genrule(
cmd_exe = "echo Not supported on Windows",
)

# bsv_library
# bsv_library (legacy, kept for cobble compatibility)
bsv_library(
visibility = ["PUBLIC"],
name = "GitVersion",
srcs = [":git_version_bsv"],
)

# BRAM-backed version ROM for post-P&R stamping. Replaces GitVersion
# in bitstream flows so that version data doesn't invalidate the cache.
bsv_library(
visibility = ["PUBLIC"],
name = "VersionROM",
srcs = ["VersionROM.bsv"],
)

export_file(
name = "version_rom_template_hex",
src = "version_rom_template.hex",
visibility = ["PUBLIC"],
)

# Volatile genrule: generates replacement hex with real git data.
# Only consumed by bitstream rules, so cache invalidation is limited
# to the final stamp+pack steps.
genrule(
name = "version_rom_replacement_hex",
visibility = ["PUBLIC"],
out = "version_rom_replacement.hex",
bash = "python3 $(location //tools:gen_version_hex) $OUT",
)

# bsv_library
bsv_library(
visibility = ["PUBLIC"],
Expand Down
25 changes: 0 additions & 25 deletions hdl/ip/bsv/I2C/BUCK
Original file line number Diff line number Diff line change
@@ -1,30 +1,5 @@
load("//tools:bsv.bzl", "bsv_bluesim_tests")
load("//tools:bsv.bzl", "bsv_library")
load("//tools:rdl.bzl", "rdl_file")

# rdl_file
# Note: Buck2 RDL rule enforces strict naming convention
# BSV outputs use "Regs" suffix, VHDL uses "_pkg" suffix
rdl_file(
visibility = ["PUBLIC"],
name = "I2CCore_rdl",
outputs = [
"I2CCoreRegs.bsv",
"I2CCore.html",
"I2CCore.json",
],
src = "I2CCore.rdl",
)

# bsv_library
bsv_library(
visibility = ["PUBLIC"],
name = "I2CCoreRegs",
srcs = [":I2CCore_rdl"],
deps = [
"//hdl/ip/bsv:RegCommon",
],
)

# bsv_library
bsv_library(
Expand Down
72 changes: 0 additions & 72 deletions hdl/ip/bsv/I2C/I2CCore.rdl

This file was deleted.

62 changes: 62 additions & 0 deletions hdl/ip/bsv/VersionROM.bsv
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
// Copyright 2025 Oxide Computer Company
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at https://mozilla.org/MPL/2.0/.

package VersionROM;

export VersionROMIfc(..);
export mkVersionROM;

import Vector::*;

// Public interface matching the original git_version package layout.
// version[0] is the LSB of the commit count, version[3] is MSB.
// sha[0] is the LSB of the short hash, sha[3] is MSB.
interface VersionROMIfc;
method Vector#(4, Bit#(8)) version;
method Vector#(4, Bit#(8)) sha;
endinterface

// Raw BVI interface matching the Verilog output ports.
interface VersionROM_BVI;
method Bit#(32) version_raw;
method Bit#(32) sha_raw;
method Bool ready;
endinterface

import "BVI" VersionROM =
module vVersionROM(VersionROM_BVI);
default_clock clk(CLK, (* unused *) CLK_GATE);
no_reset;

method VERSION version_raw();
method SHA sha_raw();
method READY ready();

schedule (version_raw) CF (version_raw, sha_raw, ready);
schedule (sha_raw) CF (sha_raw, ready);
schedule (ready) CF (ready);
endmodule

// Wrapper that converts Bit#(32) outputs to Vector#(4, Bit#(8)).
// The ROM stores bytes in big-endian order (MSB at lowest address),
// so we reverse after unpack to put the LSB at index 0, matching the
// original git_version package convention.
// No implicit conditions — values are zero for the first 9 clock
// cycles after reset, then hold the ROM contents (sentinel pattern
// until post-P&R stamping replaces them with real git data).
module mkVersionROM(VersionROMIfc);
VersionROM_BVI rom <- vVersionROM;

method Vector#(4, Bit#(8)) version;
return reverse(unpack(rom.version_raw));
endmethod

method Vector#(4, Bit#(8)) sha;
return reverse(unpack(rom.sha_raw));
endmethod
endmodule

endpackage
82 changes: 82 additions & 0 deletions hdl/ip/bsv/VersionROM.v
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
// Copyright 2025 Oxide Computer Company
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at https://mozilla.org/MPL/2.0/.

// Version ROM for post-P&R stamping.
//
// A 256x8 BRAM ROM initialized with sentinel values. After place and
// route, icebram/ecpbram replaces the sentinel pattern with real git
// version and SHA data. This avoids volatile genrules that invalidate
// the build cache on every commit.
//
// Memory layout:
// [0:3] - Version (commit count), sentinel: DE AD BE EF
// [4:7] - SHA (short git hash), sentinel: CA FE BA BE
// [8:255] - Reserved (zeros)
//
// On startup, a small FSM reads bytes 0-7 from the BRAM and latches
// them into output registers. READY asserts after 9 clock cycles.

module VersionROM(
input CLK,
output [31:0] VERSION,
output [31:0] SHA,
output READY
);

(* ram_style = "block" *)
reg [7:0] mem [0:255];

initial begin : init_mem
integer i;
for (i = 0; i < 256; i = i + 1)
mem[i] = 8'h00;
// Version sentinel
mem[0] = 8'hDE;
mem[1] = 8'hAD;
mem[2] = 8'hBE;
mem[3] = 8'hEF;
// SHA sentinel
mem[4] = 8'hCA;
mem[5] = 8'hFE;
mem[6] = 8'hBA;
mem[7] = 8'hBE;
end

reg [3:0] cnt = 4'd0;
reg [7:0] rom_rdata;
reg [31:0] version_r = 32'd0;
reg [31:0] sha_r = 32'd0;
reg ready_r = 1'b0;

// BRAM read: address driven by counter, data available next cycle
always @(posedge CLK)
rom_rdata <= mem[cnt[2:0]];

// Latch bytes into output registers as they arrive from BRAM
always @(posedge CLK) begin
if (!ready_r) begin
case (cnt)
4'd1: version_r[31:24] <= rom_rdata;
4'd2: version_r[23:16] <= rom_rdata;
4'd3: version_r[15:8] <= rom_rdata;
4'd4: version_r[7:0] <= rom_rdata;
4'd5: sha_r[31:24] <= rom_rdata;
4'd6: sha_r[23:16] <= rom_rdata;
4'd7: sha_r[15:8] <= rom_rdata;
4'd8: begin
sha_r[7:0] <= rom_rdata;
ready_r <= 1'b1;
end
endcase
cnt <= cnt + 4'd1;
end
end

assign VERSION = version_r;
assign SHA = sha_r;
assign READY = ready_r;

endmodule
Loading