feat(tb): add Vivado XSIM Verilog testbenches for all 10 sync modules
Add file-based vector testbenches ( + ) for: - mod_add_sync, rng_sync, poly_arith_sync, comp_decomp_sync - s_bram/sd_bram, sha3_chain_top - ntt_core, poly_mul_sync - sample_cbd_sync, sample_ntt_sync Each module includes: - tb_<module>_xsim.v: Vivado XSIM testbench - gen_vectors.py: Python vector generator (stdlib only) - vectors/<module>_input.hex: test input vectors - xsim_run.tcl: compile + elaborate + simulate script
This commit is contained in:
88
sync_rtl/storage/TB/gen_vectors.py
Normal file
88
sync_rtl/storage/TB/gen_vectors.py
Normal file
@@ -0,0 +1,88 @@
|
||||
#!/usr/bin/env python3
|
||||
"""gen_vectors.py — Generate BRAM test vectors for tb_storage_xsim.v
|
||||
|
||||
Vector format (64 bits = 16 hex chars per line):
|
||||
bit [63] : module (0=s_bram, 1=sd_bram)
|
||||
bit [62] : cmd (0=write, 1=read-verify)
|
||||
bits [61:56] : addr (6-bit address)
|
||||
bits [55:32] : reserved (zeros)
|
||||
bits [31:0] : data (write data / expected read data)
|
||||
|
||||
Output: vectors/storage_input.hex
|
||||
"""
|
||||
|
||||
import os
|
||||
|
||||
VECTORS_DIR = os.path.join(os.path.dirname(__file__), "vectors")
|
||||
OUTPUT_FILE = os.path.join(VECTORS_DIR, "storage_input.hex")
|
||||
|
||||
# Module selects
|
||||
S_BRAM = 0 # bit 63 = 0
|
||||
SD_BRAM = 1 # bit 63 = 1
|
||||
|
||||
# Commands
|
||||
CMD_WRITE = 0 # bit 62 = 0
|
||||
CMD_READ = 1 # bit 62 = 1
|
||||
|
||||
def encode(module: int, cmd: int, addr: int, data: int) -> int:
|
||||
"""Pack module, cmd, addr, data into a 64-bit test vector word."""
|
||||
word = 0
|
||||
word |= (module & 0x1) << 63
|
||||
word |= (cmd & 0x1) << 62
|
||||
word |= (addr & 0x3F) << 56 # 6-bit addr in bits 61:56
|
||||
# bits 55:32 reserved (zero)
|
||||
word |= (data & 0xFFFF_FFFF) # bits 31:0
|
||||
return word
|
||||
|
||||
|
||||
def main():
|
||||
os.makedirs(VECTORS_DIR, exist_ok=True)
|
||||
|
||||
vectors = []
|
||||
|
||||
# ── s_bram writes ──
|
||||
vectors.append(encode(S_BRAM, CMD_WRITE, 0, 0x00000000)) # all-zeros edge
|
||||
vectors.append(encode(S_BRAM, CMD_WRITE, 1, 0x11111111))
|
||||
vectors.append(encode(S_BRAM, CMD_WRITE, 2, 0x22222222))
|
||||
vectors.append(encode(S_BRAM, CMD_WRITE, 10, 0xAAAAAAAA))
|
||||
vectors.append(encode(S_BRAM, CMD_WRITE, 20, 0xCCCCCCCC))
|
||||
vectors.append(encode(S_BRAM, CMD_WRITE, 63, 0xFFFFFFFF)) # max addr edge
|
||||
vectors.append(encode(S_BRAM, CMD_WRITE, 30, 0xDEADBEEF))
|
||||
|
||||
# ── s_bram reads (verify) ──
|
||||
vectors.append(encode(S_BRAM, CMD_READ, 0, 0x00000000))
|
||||
vectors.append(encode(S_BRAM, CMD_READ, 1, 0x11111111))
|
||||
vectors.append(encode(S_BRAM, CMD_READ, 2, 0x22222222))
|
||||
vectors.append(encode(S_BRAM, CMD_READ, 10, 0xAAAAAAAA))
|
||||
vectors.append(encode(S_BRAM, CMD_READ, 20, 0xCCCCCCCC))
|
||||
vectors.append(encode(S_BRAM, CMD_READ, 63, 0xFFFFFFFF))
|
||||
vectors.append(encode(S_BRAM, CMD_READ, 30, 0xDEADBEEF))
|
||||
|
||||
# ── sd_bram writes ──
|
||||
vectors.append(encode(SD_BRAM, CMD_WRITE, 0, 0x00000000)) # all-zeros edge
|
||||
vectors.append(encode(SD_BRAM, CMD_WRITE, 1, 0x33333333))
|
||||
vectors.append(encode(SD_BRAM, CMD_WRITE, 2, 0x44444444))
|
||||
vectors.append(encode(SD_BRAM, CMD_WRITE, 10, 0x55555555))
|
||||
vectors.append(encode(SD_BRAM, CMD_WRITE, 63, 0xFFFFFFFF)) # max addr edge
|
||||
vectors.append(encode(SD_BRAM, CMD_WRITE, 15, 0xCAFEBABE))
|
||||
vectors.append(encode(SD_BRAM, CMD_WRITE, 20, 0xBEEFCAFE))
|
||||
|
||||
# ── sd_bram reads (verify) ──
|
||||
vectors.append(encode(SD_BRAM, CMD_READ, 0, 0x00000000))
|
||||
vectors.append(encode(SD_BRAM, CMD_READ, 1, 0x33333333))
|
||||
vectors.append(encode(SD_BRAM, CMD_READ, 2, 0x44444444))
|
||||
vectors.append(encode(SD_BRAM, CMD_READ, 10, 0x55555555))
|
||||
vectors.append(encode(SD_BRAM, CMD_READ, 63, 0xFFFFFFFF))
|
||||
vectors.append(encode(SD_BRAM, CMD_READ, 15, 0xCAFEBABE))
|
||||
vectors.append(encode(SD_BRAM, CMD_READ, 20, 0xBEEFCAFE))
|
||||
|
||||
# Write hex file (16 hex chars = 64 bits per line, uppercase, no prefix)
|
||||
with open(OUTPUT_FILE, "w") as f:
|
||||
for v in vectors:
|
||||
f.write(f"{v:016X}\n")
|
||||
|
||||
print(f"Generated {len(vectors)} vectors → {OUTPUT_FILE}")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
380
sync_rtl/storage/TB/tb_storage_xsim.v
Normal file
380
sync_rtl/storage/TB/tb_storage_xsim.v
Normal file
@@ -0,0 +1,380 @@
|
||||
// tb_storage_xsim.v - Vivado xsim testbench for s_bram and sd_bram
|
||||
//
|
||||
// Tests both single-port (s_bram) and simple dual-port (sd_bram) BRAM
|
||||
// using $readmemh file-based test vectors.
|
||||
//
|
||||
// Vector format (64 bits = 16 hex chars per line):
|
||||
// bit [63] : module (0=s_bram, 1=sd_bram)
|
||||
// bit [62] : cmd (0=write, 1=read-verify)
|
||||
// bits [61:56] : addr (6-bit address)
|
||||
// bits [55:32] : reserved
|
||||
// bits [31:0] : data (write data / expected read data)
|
||||
//
|
||||
// Test coverage:
|
||||
// - Write then read (same address)
|
||||
// - Write multiple addresses then read all
|
||||
// - Read during write on different addresses (sd_bram only)
|
||||
// - Address wrap (addr 63, max for A=6)
|
||||
// - All-zeros data edge case
|
||||
//
|
||||
// Parameters: W=32, D=64, A=6
|
||||
|
||||
`timescale 1ns / 1ps
|
||||
|
||||
module tb_storage_xsim;
|
||||
|
||||
// ================================================================
|
||||
// Parameters
|
||||
// ================================================================
|
||||
parameter W = 32;
|
||||
parameter D = 64;
|
||||
parameter A = 6;
|
||||
parameter VECTOR_FILE = "sync_rtl/storage/TB/vectors/storage_input.hex";
|
||||
parameter RESULT_FILE = "sync_rtl/storage/TB/vectors/storage_result.hex";
|
||||
parameter MAX_VECTORS = 256;
|
||||
parameter TIMEOUT_CYCLES = 2000;
|
||||
|
||||
// ================================================================
|
||||
// DUT signals — s_bram (single-port)
|
||||
// ================================================================
|
||||
reg clk;
|
||||
reg rst_n;
|
||||
reg s_rd_en;
|
||||
reg [A-1:0] s_rd_addr;
|
||||
wire [W-1:0] s_rd_data;
|
||||
reg s_wr_en;
|
||||
reg [A-1:0] s_wr_addr;
|
||||
reg [W-1:0] s_wr_data;
|
||||
|
||||
// ================================================================
|
||||
// DUT signals — sd_bram (simple dual-port)
|
||||
// ================================================================
|
||||
reg [A-1:0] sd_rd_addr;
|
||||
wire [W-1:0] sd_rd_data;
|
||||
reg sd_wr_en;
|
||||
reg [A-1:0] sd_wr_addr;
|
||||
reg [W-1:0] sd_wr_data;
|
||||
|
||||
// ================================================================
|
||||
// DUT instantiations
|
||||
// ================================================================
|
||||
s_bram #(.W(W), .D(D), .A(A)) u_sbram (
|
||||
.clk (clk),
|
||||
.rd_en (s_rd_en),
|
||||
.rd_addr (s_rd_addr),
|
||||
.rd_data (s_rd_data),
|
||||
.wr_en (s_wr_en),
|
||||
.wr_addr (s_wr_addr),
|
||||
.wr_data (s_wr_data)
|
||||
);
|
||||
|
||||
sd_bram #(.W(W), .D(D), .A(A)) u_sdbram (
|
||||
.clk (clk),
|
||||
.rd_addr (sd_rd_addr),
|
||||
.rd_data (sd_rd_data),
|
||||
.wr_en (sd_wr_en),
|
||||
.wr_addr (sd_wr_addr),
|
||||
.wr_data (sd_wr_data)
|
||||
);
|
||||
|
||||
// ================================================================
|
||||
// Clock generation: 100 MHz (10 ns period)
|
||||
// ================================================================
|
||||
initial clk = 1'b0;
|
||||
always #5 clk = ~clk;
|
||||
|
||||
// ================================================================
|
||||
// Vector memory (loaded by $readmemh)
|
||||
// ================================================================
|
||||
reg [63:0] vector_mem [0:MAX_VECTORS-1];
|
||||
integer vec_count;
|
||||
integer idx;
|
||||
integer cycle_count;
|
||||
integer result_fd;
|
||||
integer pass_count;
|
||||
integer fail_count;
|
||||
|
||||
// ================================================================
|
||||
// Main test sequence
|
||||
// ================================================================
|
||||
initial begin
|
||||
// Load vectors from hex file
|
||||
vec_count = 0;
|
||||
$readmemh(VECTOR_FILE, vector_mem);
|
||||
|
||||
// Count non-X entries
|
||||
begin
|
||||
integer found_end;
|
||||
found_end = 0;
|
||||
for (idx = 0; idx < MAX_VECTORS; idx = idx + 1) begin
|
||||
if (!found_end && (vector_mem[idx] === 64'hx || vector_mem[idx] === 64'hz))
|
||||
found_end = 1;
|
||||
else if (!found_end)
|
||||
vec_count = vec_count + 1;
|
||||
end
|
||||
end
|
||||
|
||||
if (vec_count == 0) begin
|
||||
$display("ERROR: No vectors loaded from %s", VECTOR_FILE);
|
||||
$display(" Check that the file exists.");
|
||||
$display(" Format: 16 hex chars = {module, cmd, addr, reserved, data}");
|
||||
$finish;
|
||||
end
|
||||
|
||||
$display("INFO: Loaded %0d test vectors from %s", vec_count, VECTOR_FILE);
|
||||
|
||||
// Open result file
|
||||
result_fd = $fopen(RESULT_FILE, "w");
|
||||
if (result_fd == 0) begin
|
||||
$display("ERROR: Cannot open result file: %s", RESULT_FILE);
|
||||
$finish;
|
||||
end
|
||||
|
||||
// Initialize all DUT inputs
|
||||
s_rd_en <= 1'b0;
|
||||
s_rd_addr <= {A{1'b0}};
|
||||
s_wr_en <= 1'b0;
|
||||
s_wr_addr <= {A{1'b0}};
|
||||
s_wr_data <= {W{1'b0}};
|
||||
|
||||
sd_rd_addr <= {A{1'b0}};
|
||||
sd_wr_en <= 1'b0;
|
||||
sd_wr_addr <= {A{1'b0}};
|
||||
sd_wr_data <= {W{1'b0}};
|
||||
|
||||
// Reset sequence: rst_n low for 3 cycles, then high
|
||||
rst_n <= 1'b0;
|
||||
repeat (3) @(posedge clk);
|
||||
rst_n <= 1'b1;
|
||||
@(posedge clk);
|
||||
|
||||
pass_count = 0;
|
||||
fail_count = 0;
|
||||
|
||||
// ============================================================
|
||||
// Process each vector
|
||||
// ============================================================
|
||||
for (idx = 0; idx < vec_count; idx = idx + 1) begin
|
||||
begin
|
||||
reg vec_module;
|
||||
reg vec_cmd;
|
||||
reg [A-1:0] vec_addr;
|
||||
reg [W-1:0] vec_data;
|
||||
|
||||
vec_module = vector_mem[idx][63];
|
||||
vec_cmd = vector_mem[idx][62];
|
||||
vec_addr = vector_mem[idx][61:56];
|
||||
vec_data = vector_mem[idx][31:0];
|
||||
|
||||
if (vec_module == 1'b0) begin
|
||||
// ── s_bram ──────────────────────────────
|
||||
if (vec_cmd == 1'b0) begin
|
||||
// Write
|
||||
s_wr_en <= 1'b1;
|
||||
s_wr_addr <= vec_addr;
|
||||
s_wr_data <= vec_data;
|
||||
s_rd_en <= 1'b0;
|
||||
s_rd_addr <= {A{1'b0}};
|
||||
@(posedge clk);
|
||||
s_wr_en <= 1'b0;
|
||||
end else begin
|
||||
// Read-verify
|
||||
s_rd_en <= 1'b1;
|
||||
s_rd_addr <= vec_addr;
|
||||
s_wr_en <= 1'b0;
|
||||
s_wr_addr <= {A{1'b0}};
|
||||
s_wr_data <= {W{1'b0}};
|
||||
@(posedge clk); // 1-cycle read latency
|
||||
// rd_data valid now
|
||||
if (s_rd_data !== vec_data) begin
|
||||
$display("FAIL: s_bram addr=%0d expected=0x%08h got=0x%08h",
|
||||
vec_addr, vec_data, s_rd_data);
|
||||
$fwrite(result_fd, "FAIL: s_bram addr=%0d exp=0x%08h got=0x%08h\n",
|
||||
vec_addr, vec_data, s_rd_data);
|
||||
fail_count = fail_count + 1;
|
||||
end else begin
|
||||
pass_count = pass_count + 1;
|
||||
end
|
||||
s_rd_en <= 1'b0;
|
||||
end
|
||||
|
||||
end else begin
|
||||
// ── sd_bram ─────────────────────────────
|
||||
if (vec_cmd == 1'b0) begin
|
||||
// Write
|
||||
sd_wr_en <= 1'b1;
|
||||
sd_wr_addr <= vec_addr;
|
||||
sd_wr_data <= vec_data;
|
||||
@(posedge clk);
|
||||
sd_wr_en <= 1'b0;
|
||||
end else begin
|
||||
// Read-verify: drive read address, wait 1 cycle
|
||||
sd_rd_addr <= vec_addr;
|
||||
@(posedge clk); // 1-cycle read latency
|
||||
// rd_data valid now
|
||||
if (sd_rd_data !== vec_data) begin
|
||||
$display("FAIL: sd_bram addr=%0d expected=0x%08h got=0x%08h",
|
||||
vec_addr, vec_data, sd_rd_data);
|
||||
$fwrite(result_fd, "FAIL: sd_bram addr=%0d exp=0x%08h got=0x%08h\n",
|
||||
vec_addr, vec_data, sd_rd_data);
|
||||
fail_count = fail_count + 1;
|
||||
end else begin
|
||||
pass_count = pass_count + 1;
|
||||
end
|
||||
end
|
||||
end
|
||||
end // inner begin block
|
||||
end
|
||||
|
||||
// ============================================================
|
||||
// Edge-case tests (hardcoded, beyond hex vectors)
|
||||
// ============================================================
|
||||
|
||||
// ── s_bram: write-priority (rd_en + wr_en both high) ──
|
||||
begin
|
||||
$display("INFO: s_bram write-priority test");
|
||||
// Write 0xCAFECAFE to addr 5
|
||||
s_wr_en <= 1'b1; s_wr_addr <= 6'd5; s_wr_data <= 32'hCAFECAFE;
|
||||
s_rd_en <= 1'b1; s_rd_addr <= 6'd5; // same addr, rd also asserted
|
||||
@(posedge clk);
|
||||
s_wr_en <= 1'b0;
|
||||
// Write should win — memory now has CAFECAFE at addr 5
|
||||
// Read back to verify
|
||||
s_rd_en <= 1'b1; s_rd_addr <= 6'd5;
|
||||
@(posedge clk);
|
||||
if (s_rd_data !== 32'hCAFECAFE) begin
|
||||
$display("FAIL: s_bram write-priority (expected CAFECAFE, got 0x%08h)", s_rd_data);
|
||||
fail_count = fail_count + 1;
|
||||
end else begin
|
||||
$display("PASS: s_bram write-priority");
|
||||
pass_count = pass_count + 1;
|
||||
end
|
||||
s_rd_en <= 1'b0;
|
||||
end
|
||||
|
||||
// ── sd_bram: concurrent read-during-write (different addresses) ──
|
||||
begin
|
||||
$display("INFO: sd_bram read-during-write test");
|
||||
// Pre-fill addr 10 with known value
|
||||
sd_wr_en <= 1'b1; sd_wr_addr <= 6'd10; sd_wr_data <= 32'h12345678;
|
||||
@(posedge clk);
|
||||
sd_wr_en <= 1'b0;
|
||||
// Now write addr 20 while reading addr 10 (different addrs)
|
||||
sd_wr_en <= 1'b1; sd_wr_addr <= 6'd20; sd_wr_data <= 32'hFEEDFACE;
|
||||
sd_rd_addr <= 6'd10;
|
||||
@(posedge clk);
|
||||
sd_wr_en <= 1'b0;
|
||||
// rd_data should be OLD value at addr 10 (12345678)
|
||||
if (sd_rd_data !== 32'h12345678) begin
|
||||
$display("FAIL: sd_bram rd-during-wr: expected 0x12345678, got 0x%08h", sd_rd_data);
|
||||
fail_count = fail_count + 1;
|
||||
end else begin
|
||||
$display("PASS: sd_bram read-during-write (old data)");
|
||||
pass_count = pass_count + 1;
|
||||
end
|
||||
// Verify addr 20 got new data
|
||||
sd_rd_addr <= 6'd20;
|
||||
@(posedge clk);
|
||||
if (sd_rd_data !== 32'hFEEDFACE) begin
|
||||
$display("FAIL: sd_bram wr-during-rd: expected 0xFEEDFACE at addr 20, got 0x%08h", sd_rd_data);
|
||||
fail_count = fail_count + 1;
|
||||
end else begin
|
||||
$display("PASS: sd_bram write-during-read (new data)");
|
||||
pass_count = pass_count + 1;
|
||||
end
|
||||
end
|
||||
|
||||
// ── sd_bram: concurrent read-during-write (SAME address) ──
|
||||
begin
|
||||
$display("INFO: sd_bram read-during-write (same address)");
|
||||
sd_wr_en <= 1'b1; sd_wr_addr <= 6'd30; sd_wr_data <= 32'hAAAAAAAA;
|
||||
sd_rd_addr <= 6'd30; // same address
|
||||
@(posedge clk);
|
||||
sd_wr_en <= 1'b0;
|
||||
// On sd_bram, mem write happens at posedge, rd_addr is registered
|
||||
// So rd_data gets OLD mem[30] (before write), not new AAAAAAAA
|
||||
// We just verify the read port didn't get X
|
||||
if (sd_rd_data === 32'hx || sd_rd_data === 32'hz) begin
|
||||
$display("FAIL: sd_bram rd-during-wr same addr: got X/Z");
|
||||
fail_count = fail_count + 1;
|
||||
end else begin
|
||||
$display("PASS: sd_bram read-during-write (same addr, no X)");
|
||||
pass_count = pass_count + 1;
|
||||
end
|
||||
// Now read addr 30 to verify write took effect
|
||||
sd_rd_addr <= 6'd30;
|
||||
@(posedge clk);
|
||||
if (sd_rd_data !== 32'hAAAAAAAA) begin
|
||||
$display("FAIL: sd_bram same-addr write: expected 0xAAAAAAAA, got 0x%08h", sd_rd_data);
|
||||
fail_count = fail_count + 1;
|
||||
end else begin
|
||||
$display("PASS: sd_bram same-addr write verified");
|
||||
pass_count = pass_count + 1;
|
||||
end
|
||||
end
|
||||
|
||||
// ── s_bram: address wrap / all-zeros data ──
|
||||
begin
|
||||
$display("INFO: s_bram address wrap test");
|
||||
// Write to max address (63) and read back
|
||||
s_wr_en <= 1'b1; s_wr_addr <= 6'd63; s_wr_data <= 32'hFFFF0000;
|
||||
@(posedge clk);
|
||||
s_wr_en <= 1'b0;
|
||||
s_rd_en <= 1'b1; s_rd_addr <= 6'd63;
|
||||
@(posedge clk);
|
||||
if (s_rd_data !== 32'hFFFF0000) begin
|
||||
$display("FAIL: s_bram addr 63: expected 0xFFFF0000, got 0x%08h", s_rd_data);
|
||||
fail_count = fail_count + 1;
|
||||
end else begin
|
||||
$display("PASS: s_bram addr 63 (max)");
|
||||
pass_count = pass_count + 1;
|
||||
end
|
||||
s_rd_en <= 1'b0;
|
||||
|
||||
// Write all-zeros to addr 0 and read back
|
||||
s_wr_en <= 1'b1; s_wr_addr <= 6'd0; s_wr_data <= 32'h00000000;
|
||||
@(posedge clk);
|
||||
s_wr_en <= 1'b0;
|
||||
s_rd_en <= 1'b1; s_rd_addr <= 6'd0;
|
||||
@(posedge clk);
|
||||
if (s_rd_data !== 32'h00000000) begin
|
||||
$display("FAIL: s_bram all-zeros: expected 0x00000000, got 0x%08h", s_rd_data);
|
||||
fail_count = fail_count + 1;
|
||||
end else begin
|
||||
$display("PASS: s_bram all-zeros data");
|
||||
pass_count = pass_count + 1;
|
||||
end
|
||||
s_rd_en <= 1'b0;
|
||||
end
|
||||
|
||||
// ============================================================
|
||||
// Summary
|
||||
// ============================================================
|
||||
$fclose(result_fd);
|
||||
|
||||
$display("========================================");
|
||||
$display("STORAGE TEST COMPLETE");
|
||||
$display(" Total vectors: %0d", vec_count);
|
||||
$display(" Edge-case tests: %0d", 7); // hardcoded count above
|
||||
$display(" Passed: %0d", pass_count);
|
||||
$display(" Failed: %0d", fail_count);
|
||||
$display(" Results written to: %s", RESULT_FILE);
|
||||
if (fail_count == 0)
|
||||
$display(" RESULT: ALL TESTS PASSED");
|
||||
else
|
||||
$display(" RESULT: SOME TESTS FAILED");
|
||||
$display("========================================");
|
||||
|
||||
$finish;
|
||||
end
|
||||
|
||||
// ================================================================
|
||||
// Timeout watchdog
|
||||
// ================================================================
|
||||
initial begin
|
||||
#(TIMEOUT_CYCLES * 10 * 100);
|
||||
$display("FATAL: Global simulation timeout reached");
|
||||
$finish;
|
||||
end
|
||||
|
||||
endmodule
|
||||
28
sync_rtl/storage/TB/vectors/storage_input.hex
Normal file
28
sync_rtl/storage/TB/vectors/storage_input.hex
Normal file
@@ -0,0 +1,28 @@
|
||||
0000000000000000
|
||||
0100000011111111
|
||||
0200000022222222
|
||||
0A000000AAAAAAAA
|
||||
14000000CCCCCCCC
|
||||
3F000000FFFFFFFF
|
||||
1E000000DEADBEEF
|
||||
4000000000000000
|
||||
4100000011111111
|
||||
4200000022222222
|
||||
4A000000AAAAAAAA
|
||||
54000000CCCCCCCC
|
||||
7F000000FFFFFFFF
|
||||
5E000000DEADBEEF
|
||||
8000000000000000
|
||||
8100000033333333
|
||||
8200000044444444
|
||||
8A00000055555555
|
||||
BF000000FFFFFFFF
|
||||
8F000000CAFEBABE
|
||||
94000000BEEFCAFE
|
||||
C000000000000000
|
||||
C100000033333333
|
||||
C200000044444444
|
||||
CA00000055555555
|
||||
FF000000FFFFFFFF
|
||||
CF000000CAFEBABE
|
||||
D4000000BEEFCAFE
|
||||
48
sync_rtl/storage/TB/xsim_run.tcl
Normal file
48
sync_rtl/storage/TB/xsim_run.tcl
Normal file
@@ -0,0 +1,48 @@
|
||||
# xsim_run.tcl - Vivado xsim compilation and simulation script
|
||||
#
|
||||
# Compiles s_bram, sd_bram, and tb_storage_xsim testbench.
|
||||
# Run from the project root: ~/Dev/mlkem/
|
||||
#
|
||||
# Prerequisites:
|
||||
# source /opt/Xilinx/Vivado/2019.2/settings64.sh
|
||||
#
|
||||
# Usage:
|
||||
# xsim -runall xsim_run.tcl
|
||||
# vivado -mode batch -source xsim_run.tcl
|
||||
|
||||
# ================================================================
|
||||
# Configuration
|
||||
# ================================================================
|
||||
set SRC_DIR sync_rtl/storage
|
||||
set TB_DIR sync_rtl/storage/TB
|
||||
|
||||
# ================================================================
|
||||
# Step 1: Compile RTL sources (xvlog)
|
||||
# ================================================================
|
||||
puts "=== Compiling RTL sources ==="
|
||||
|
||||
xvlog -sv ${SRC_DIR}/s_bram.v
|
||||
xvlog -sv ${SRC_DIR}/sd_bram.v
|
||||
|
||||
# ================================================================
|
||||
# Step 2: Compile testbench
|
||||
# ================================================================
|
||||
puts "=== Compiling testbench ==="
|
||||
|
||||
xvlog -sv ${TB_DIR}/tb_storage_xsim.v
|
||||
|
||||
# ================================================================
|
||||
# Step 3: Elaborate snapshot (xelab)
|
||||
# ================================================================
|
||||
puts "=== Elaborating snapshot ==="
|
||||
|
||||
xelab tb_storage_xsim -s tb_storage_xsim
|
||||
|
||||
# ================================================================
|
||||
# Step 4: Run simulation
|
||||
# ================================================================
|
||||
puts "=== Running storage test ==="
|
||||
xsim tb_storage_xsim -R
|
||||
|
||||
puts ""
|
||||
puts "=== Storage simulation complete ==="
|
||||
Reference in New Issue
Block a user