From 6319d7ca852f5922be2231c3ba843d72f87230a5 Mon Sep 17 00:00:00 2001 From: thejayman77 Date: Thu, 23 Jul 2026 10:03:01 -0400 Subject: [PATCH] Ch443d: registered AXI R buffer (texcache fill) + drop fill_data_q reset Closes the last currently-visible EMIF-handshake -> FSM setup family the Ch443c fit exposed (-0.043/-0.022/-0.005 ns), the read-response analogue of the AW/W buffers. - gs_axi_r_regbuf: one-entry FULLY-registered AXI R buffer (the R twin of gs_axi_w_regbuf). Buffers the complete {rdata,rresp,rlast}; u_rready = !full only (NO combinational dependence on the texture FSM's d_rready); captures on u_rvalid && u_rready; d_rvalid = full with the payload held stable until d_rvalid && d_rready; resets only . Inserted between read-arbiter s2 and gs_texture_cache (u_texf_rbuf). The arbiter is unchanged -- it completes its R transaction into the buffer, which then owns delivery to the fill FSM. Cuts EMIF rvalid/rdata -> fst.F_R. - gs_texture_cache: drop the unobservable fill_data_q reset. F_DRAIN (its only reader) is reachable only after F_R loads it, so the reset value is never observed; removing it kills the separate lock_sync|dreg[1] -> fill_data_q[80] setup path (-0.005 ns). - New tb_gs_axi_r_regbuf: exactly-once/in-order, randomized responses + stalls, full backpressure, the full && d_rready no-fall-through case, {rdata,rresp,rlast} stability, reset-while-empty AND reset-while-full. All green: r-buffer TB, texture_cache, texture_psmt8_clut, scanout_lb, scanout_restart, scanout_diag, ps2_hps_bridge, rd_arb, and the complete f52 replay BYTE-IDENTICAL (Z 0/307200, COLOR 0/245760). No Quartus/board/ push from here. Co-Authored-By: Claude Opus 4.8 (1M context) --- rtl/gif_gs/gs_axi_r_regbuf.sv | 78 ++++++++++ rtl/gif_gs/gs_texture_cache.sv | 6 +- rtl/top/de25_nano_psmct32_raster_demo_top.sv | 19 ++- sim/Makefile | 12 +- sim/tb/gif_gs/tb_gs_axi_r_regbuf.sv | 145 ++++++++++++++++++ .../de25_nano_psmct32_raster_demo_top.qsf | 1 + 6 files changed, 256 insertions(+), 5 deletions(-) create mode 100644 rtl/gif_gs/gs_axi_r_regbuf.sv create mode 100644 sim/tb/gif_gs/tb_gs_axi_r_regbuf.sv diff --git a/rtl/gif_gs/gs_axi_r_regbuf.sv b/rtl/gif_gs/gs_axi_r_regbuf.sv new file mode 100644 index 0000000..c64a2e8 --- /dev/null +++ b/rtl/gif_gs/gs_axi_r_regbuf.sv @@ -0,0 +1,78 @@ +// retroDE_ps2 — gs_axi_r_regbuf (Ch443d) +// +// Fully-registered ONE-ENTRY AXI R-channel (read-response) buffer. The R twin of +// gs_axi_w_regbuf / gs_axi_aw_regbuf. Inserted between the read arbiter's s2 R +// OUTPUT and the texture-cache fill FSM's R INPUT to cut the combinational path +// EMIF gen_p2c_ff[*] (rvalid/rdata) -> gs_texture_cache F_R next-state (`fst`) +// + fill_data_q capture — the -0.043 ns / -0.022 ns EMIF setup family. +// +// CONTRACT (per Codex review, identical shape to gs_axi_w_regbuf): +// - FULLY REGISTERED, not a fall-through skid: u_rready depends ONLY on the +// registered occupancy `full`, never on the texture FSM's downstream d_rready. +// EMIF RVALID therefore can never propagate combinationally into the fill FSM. +// (i.e. NOT `u_rready = !full || d_rready`.) +// - Buffers the COMPLETE {RDATA, RRESP, RLAST} payload and holds it stable on the +// downstream side until the texture FSM accepts it. +// - Capture only on u_rvalid && u_rready; exactly-once, in-order (one in flight — +// the texture fill issues single-beat reads, ARLEN=0/RLAST=1, but RRESP/RLAST +// are preserved regardless). +// - Downstream VALID is `full`; payload held stable until d_rvalid && d_rready. +// - Reset only `full`; payload registers deliberately unreset (qualified by full). +// - The arbiter is unchanged: it completes its R transaction when the response is +// accepted into this buffer (s2_rready = u_rready = !full); the buffer then owns +// delivery to the texture FSM. +`timescale 1ns/1ps + +module gs_axi_r_regbuf #( + parameter int RDATA_W = 256, + parameter int RRESP_W = 2 +) ( + input logic clk, + input logic rst_n, + // upstream — from the read arbiter's s2 R output (EMIF read return) + input logic [RDATA_W-1:0] u_rdata, + input logic [RRESP_W-1:0] u_rresp, + input logic u_rlast, + input logic u_rvalid, + output logic u_rready, + // downstream — to the texture-cache fill FSM's R input + output logic [RDATA_W-1:0] d_rdata, + output logic [RRESP_W-1:0] d_rresp, + output logic d_rlast, + output logic d_rvalid, + input logic d_rready +); + logic full; + logic [RDATA_W-1:0] rdata_q; + logic [RRESP_W-1:0] rresp_q; + logic rlast_q; + + // Upstream ready = registered occupancy ONLY (no d_rready term) -> EMIF RVALID + // never reaches the texture fill FSM combinationally. + assign u_rready = !full; + // Downstream presents the held response, stable until the texture FSM accepts it. + assign d_rvalid = full; + assign d_rdata = rdata_q; + assign d_rresp = rresp_q; + assign d_rlast = rlast_q; + + // One-entry register. Accept an offered upstream response only while empty; + // release only when the texture FSM accepts the held response. When full and + // accepted in the same cycle, u_rready is still 0 (full is registered), so the + // next response waits one cycle -> a swap/drop/dup is impossible. Payload + // registers deliberately have no reset (qualified by `full`/d_rvalid). + always_ff @(posedge clk or negedge rst_n) begin + if (!rst_n) begin + full <= 1'b0; + end else if (!full) begin + if (u_rvalid) begin + full <= 1'b1; + rdata_q <= u_rdata; + rresp_q <= u_rresp; + rlast_q <= u_rlast; + end + end else begin + if (d_rready) full <= 1'b0; + end + end +endmodule : gs_axi_r_regbuf diff --git a/rtl/gif_gs/gs_texture_cache.sv b/rtl/gif_gs/gs_texture_cache.sv index c4fa0fa..1717285 100644 --- a/rtl/gif_gs/gs_texture_cache.sv +++ b/rtl/gif_gs/gs_texture_cache.sv @@ -126,7 +126,11 @@ module gs_texture_cache #( if (!axi_rst_n) begin fst <= F_IDLE; araddr <= '0; arvalid <= 1'b0; rready <= 1'b0; beat <= '0; fill_done <= 1'b0; fill_beats <= 32'd0; fill_bytes <= 32'd0; - rd_errs <= 32'd0; fs_sync <= 3'd0; fill_data_q <= '0; + rd_errs <= 32'd0; fs_sync <= 3'd0; + // Ch443d (Codex): fill_data_q is deliberately UNRESET. F_DRAIN (its only reader) + // is reachable only after F_R has loaded it from the buffered read response, so + // its reset value is unobservable. Dropping the reset removes the separate + // lock_sync_inst|dreg[1] -> fill_data_q[80] setup path (-0.005 ns). fill_lane <= 3'd0; fill_word_base <= '0; fill_crc <= 32'd0; end else begin fs_sync <= {fs_sync[1:0], fill_start}; diff --git a/rtl/top/de25_nano_psmct32_raster_demo_top.sv b/rtl/top/de25_nano_psmct32_raster_demo_top.sv index d066db3..c440c2c 100644 --- a/rtl/top/de25_nano_psmct32_raster_demo_top.sv +++ b/rtl/top/de25_nano_psmct32_raster_demo_top.sv @@ -1991,6 +1991,9 @@ module de25_nano_psmct32_raster_demo_top ( wire [29:0] texf_ar_araddr; wire [1:0] texf_ar_arburst; wire [6:0] texf_ar_arid; wire [7:0] texf_ar_arlen; wire [2:0] texf_ar_arsize; wire texf_ar_arvalid, texf_ar_arready; wire [255:0] texf_r_rdata; wire [1:0] texf_r_rresp; wire texf_r_rlast, texf_r_rvalid, texf_r_rready; + // Ch443d — read-arbiter s2 R output feeds a one-entry registered R buffer (texf_ri_* = + // buffer upstream, from the arbiter); the buffer drives texf_r_* into the texture fill FSM. + wire [255:0] texf_ri_rdata; wire [1:0] texf_ri_rresp; wire texf_ri_rlast, texf_ri_rvalid, texf_ri_rready; EMIF_Qsys u_emif_lpddr4b ( .iopll_refclk_clk (CLOCK2_50), @@ -2719,8 +2722,8 @@ module de25_nano_psmct32_raster_demo_top ( .s2_araddr(texf_ar_araddr), .s2_arburst(texf_ar_arburst), .s2_arid(texf_ar_arid), .s2_arlen(texf_ar_arlen), .s2_arsize(texf_ar_arsize), .s2_arvalid(texf_ar_arvalid), .s2_arready(texf_ar_arready), - .s2_rdata(texf_r_rdata), .s2_rresp(texf_r_rresp), .s2_rlast(texf_r_rlast), - .s2_rvalid(texf_r_rvalid), .s2_rready(texf_r_rready), + .s2_rdata(texf_ri_rdata), .s2_rresp(texf_ri_rresp), .s2_rlast(texf_ri_rlast), + .s2_rvalid(texf_ri_rvalid), .s2_rready(texf_ri_rready), .s3_araddr(reload_ar_araddr), .s3_arburst(reload_ar_arburst), .s3_arid(reload_ar_arid), .s3_arlen(reload_ar_arlen), .s3_arsize(reload_ar_arsize), .s3_arvalid(reload_ar_arvalid), .s3_arready(reload_ar_arready), @@ -2740,6 +2743,16 @@ module de25_nano_psmct32_raster_demo_top ( // (one-shot before raster, armed by the bridge); sample side on design_clk, tapping // u_demo's texel-fetch request and returning the texel at the existing 1-cycle latency. `ifdef GS_LPDDR_TEX + // Ch443d — one-entry fully-registered R buffer between read-arbiter s2 and the + // texture fill FSM. Cuts the combinational EMIF RVALID/RDATA -> gs_texture_cache + // F_R next-state (`fst`) path (the -0.043/-0.022 ns EMIF setup family). The arbiter + // completes its R transaction into this buffer (s2_rready = !full); the buffer owns + // delivery to the fill FSM. B/AR/W untouched. + gs_axi_r_regbuf #(.RDATA_W(256), .RRESP_W(2)) u_texf_rbuf ( + .clk(emif_clk), .rst_n(emif_reset_n), + .u_rdata(texf_ri_rdata), .u_rresp(texf_ri_rresp), .u_rlast(texf_ri_rlast), .u_rvalid(texf_ri_rvalid), .u_rready(texf_ri_rready), + .d_rdata(texf_r_rdata), .d_rresp(texf_r_rresp), .d_rlast(texf_r_rlast), .d_rvalid(texf_r_rvalid), .d_rready(texf_r_rready) + ); gs_texture_cache #( .LPDDR_TEX_BASE(TEX_LPDDR_BASE), .TEX_VRAM_BASE(TEXC_VRAM_BASE), .TEX_BYTES(TEXC_BYTES), .N_BEATS(TEXC_NBEATS) ) u_texcache ( @@ -2758,7 +2771,7 @@ module de25_nano_psmct32_raster_demo_top ( // no texture cache — tie read-port-2 inert (arvalid=0, rready=1 drains). assign texf_ar_araddr=30'd0; assign texf_ar_arburst=2'b01; assign texf_ar_arid=7'd4; assign texf_ar_arlen=8'd0; assign texf_ar_arsize=3'b101; assign texf_ar_arvalid=1'b0; - assign texf_r_rready=1'b1; + assign texf_ri_rready=1'b1; // Ch443d — drain the arbiter s2 R directly (no R buffer / texcache in this profile) assign tex_fill_done_w=1'b0; assign tex_fill_beats_w=32'd0; assign tex_fill_bytes_w=32'd0; assign tex_rd_errs_w=32'd0; assign tex_fill_crc_w=32'd0; `ifndef GS_TILE_SPILL diff --git a/sim/Makefile b/sim/Makefile index 2f8af7d..e08ff13 100644 --- a/sim/Makefile +++ b/sim/Makefile @@ -587,6 +587,7 @@ RTL_SRCS := \ $(RTL_ROOT)/gif_gs/gs_lpddr_z_rmw.sv \ $(RTL_ROOT)/gif_gs/gs_axi_w_regbuf.sv \ $(RTL_ROOT)/gif_gs/gs_axi_aw_regbuf.sv \ + $(RTL_ROOT)/gif_gs/gs_axi_r_regbuf.sv \ $(RTL_ROOT)/gif_gs/gs_lpddr_zc_emit.sv \ $(RTL_ROOT)/gif_gs/gs_lpddr_rd_probe.sv \ $(RTL_ROOT)/gif_gs/gs_lpddr_scanout.sv \ @@ -1163,6 +1164,15 @@ tb_gs_axi_aw_regbuf: dirs @echo "=== run tb_gs_axi_aw_regbuf ===" @cd $(TRACE_DIR) && $(VVP) $(BUILD_DIR)/tb_gs_axi_aw_regbuf.vvp +tb_gs_axi_r_regbuf: dirs + @echo "=== build tb_gs_axi_r_regbuf ===" + $(IVERILOG) $(IVERILOG_FLGS) \ + -o $(BUILD_DIR)/tb_gs_axi_r_regbuf.vvp \ + -s tb_gs_axi_r_regbuf \ + $(RTL_SRCS) $(TB_ROOT)/gif_gs/tb_gs_axi_r_regbuf.sv + @echo "=== run tb_gs_axi_r_regbuf ===" + @cd $(TRACE_DIR) && $(VVP) $(BUILD_DIR)/tb_gs_axi_r_regbuf.vvp + tb_gs_grad_divider: dirs @echo "=== build tb_gs_grad_divider ===" $(IVERILOG) $(IVERILOG_FLGS) \ @@ -6301,7 +6311,7 @@ run: tb_top_psmct32_sh3_zs640c12_cap tb_top_psmct32_sh3_zint640c12 run: tb_top_psmct32_sh3_zs640b24_cap tb_top_psmct32_sh3_zint640b24 .PHONY: tb_top_psmct32_sh3_zs640c24c_cap tb_top_psmct32_sh3_zint640c24c sh3_zs640c24c_fixture sh3_zs640motionabc_bootlet -run: tb_top_psmct32_sh3_zs640c24c_cap tb_top_psmct32_sh3_zint640c24c tb_gs_axi_w_regbuf tb_gs_axi_aw_regbuf +run: tb_top_psmct32_sh3_zs640c24c_cap tb_top_psmct32_sh3_zint640c24c tb_gs_axi_w_regbuf tb_gs_axi_aw_regbuf tb_gs_axi_r_regbuf run: tb_ee_fetch tb_gs tb_intc tb_platform_video tb_bgcolor_via_dma tb_sif_mailbox \ tb_sif_command_echo tb_sif_command_echo_rearm tb_sif_negative_path \ diff --git a/sim/tb/gif_gs/tb_gs_axi_r_regbuf.sv b/sim/tb/gif_gs/tb_gs_axi_r_regbuf.sv new file mode 100644 index 0000000..32a3834 --- /dev/null +++ b/sim/tb/gif_gs/tb_gs_axi_r_regbuf.sv @@ -0,0 +1,145 @@ +// retroDE_ps2 — tb_gs_axi_r_regbuf (Ch443d) +// +// Focused scoreboard for the one-entry fully-registered AXI R buffer (the R twin of +// tb_gs_axi_w_regbuf). Verifies: +// (1) EXACTLY-ONCE, IN-ORDER delivery with payload integrity {RDATA,RRESP,RLAST} +// under randomized upstream responses + downstream backpressure (a drop, dup, +// or reorder trips the sequence scoreboard). +// (2) NO-COMBINATIONAL-BYPASS: u_rready === !full every cycle, so a fall-through +// `u_rready = !full || d_rready` (which would leak the texture FSM's downstream +// READY back upstream into EMIF RVALID) is caught. A directed phase forces the +// full && d_rready case. +// (3) Downstream payload held STABLE while d_rvalid && !d_rready. +// (4) Reset while empty AND while full both leave the buffer empty. +`timescale 1ns/1ps + +module tb_gs_axi_r_regbuf; + localparam int RD = 256, RS = 2; + logic clk = 0; always #5 clk = ~clk; // 100 MHz + logic rst_n; + + logic [RD-1:0] u_rdata; logic [RS-1:0] u_rresp; logic u_rlast, u_rvalid, u_rready; + logic [RD-1:0] d_rdata; logic [RS-1:0] d_rresp; logic d_rlast, d_rvalid; logic d_rready; + + gs_axi_r_regbuf #(.RDATA_W(RD), .RRESP_W(RS)) dut ( + .clk(clk), .rst_n(rst_n), + .u_rdata(u_rdata), .u_rresp(u_rresp), .u_rlast(u_rlast), .u_rvalid(u_rvalid), .u_rready(u_rready), + .d_rdata(d_rdata), .d_rresp(d_rresp), .d_rlast(d_rlast), .d_rvalid(d_rvalid), .d_rready(d_rready) + ); + + int errors; initial errors = 0; + + // distinct nonzero payload per sequence value + function automatic logic [RD-1:0] mk(input logic [31:0] s); + mk = {s^32'h1234ABCD, s+32'd7, ~s, s^32'h55AA55AA, s+32'd2, s^32'hF0F0F0F0, s+32'd9, s}; + endfunction + function automatic logic [RS-1:0] mk_resp(input logic [31:0] s); mk_resp = s[1:0]; endfunction // 0..3 incl SLVERR + function automatic logic mk_last(input logic [31:0] s); mk_last = s[2]; endfunction + + // LFSR backpressure both sides + logic [15:0] ul = 16'hACE1, dl = 16'h1357; + always_ff @(posedge clk) begin + ul <= {ul[14:0], ul[15]^ul[13]^ul[12]^ul[10]}; + dl <= {dl[14:0], dl[15]^dl[13]^dl[12]^dl[10]}; + end + logic force_ready, force_stall, prod_freeze; + assign d_rready = force_ready ? 1'b1 : (force_stall ? 1'b0 : (dl[0] | dl[3])); + + // AXI-legal producer: assert u_rvalid with STABLE payload until accepted. + logic [31:0] wr_seq; logic pending; + always_ff @(posedge clk or negedge rst_n) begin + if (!rst_n) begin wr_seq <= 0; pending <= 1'b0; end + else if (u_rvalid && u_rready) begin + wr_seq <= wr_seq + 1; + pending <= (ul[0] | ul[3]) && !prod_freeze; + end + else if (!pending) pending <= (ul[0] | ul[3]) && !prod_freeze; + end + assign u_rvalid = pending; + assign u_rdata = mk(wr_seq); + assign u_rresp = mk_resp(wr_seq); + assign u_rlast = mk_last(wr_seq); + + // (1) downstream scoreboard: exactly-once, in-order, payload-correct + logic [31:0] rd_seq; + always_ff @(posedge clk or negedge rst_n) begin + if (!rst_n) rd_seq <= 0; + else if (d_rvalid && d_rready) begin + if (d_rdata !== mk(rd_seq) || d_rresp !== mk_resp(rd_seq) || d_rlast !== mk_last(rd_seq)) begin + if (errors < 20) $error("[rbuf] drop/dup/reorder/payload at seq %0d: rdata %h resp %h last %b", + rd_seq, d_rdata, d_rresp, d_rlast); + errors++; + end + rd_seq <= rd_seq + 1; + end + end + + // (2) NO combinational downstream-ready bypass: u_rready must equal !full. + always_ff @(posedge clk) if (rst_n) begin + if (u_rready !== !dut.full) begin + if (errors < 20) $error("[rbuf] u_rready(%b) != !full(%b) — combinational bypass?", u_rready, dut.full); + errors++; + end + end + logic saw_full_and_ready; initial saw_full_and_ready = 1'b0; + always_ff @(posedge clk) if (rst_n && dut.full && d_rready) saw_full_and_ready <= 1'b1; + + // (3) while stalled, the SAME beat must still be presented. + logic [RD-1:0] hold_d; logic [RS-1:0] hold_r; logic hold_l, hold_v; + always_ff @(posedge clk or negedge rst_n) begin + if (!rst_n) begin hold_v <= 1'b0; hold_d <= '0; hold_r <= '0; hold_l <= 1'b0; end + else begin + if (hold_v) begin + if (!d_rvalid) begin + if (errors < 20) $error("[rbuf] d_rvalid deasserted while stalled"); errors++; + end else if (d_rdata !== hold_d || d_rresp !== hold_r || d_rlast !== hold_l) begin + if (errors < 20) $error("[rbuf] downstream {rdata,rresp,rlast} changed while stalled"); errors++; + end + end + hold_v <= d_rvalid && !d_rready; + hold_d <= d_rdata; hold_r <= d_rresp; hold_l <= d_rlast; + end + end + + initial begin + rst_n = 0; force_ready = 0; force_stall = 0; prod_freeze = 0; + repeat (6) @(posedge clk); rst_n = 1; + @(posedge clk); + if (d_rvalid !== 1'b0) begin $error("[rbuf] not empty after reset (empty case)"); errors++; end + + // Phase 1: reset while FULL — briefly run, stall to fill, then pulse reset. Done + // EARLY so the later count/coverage checks accumulate after it (reset zeroes wr_seq). + force_stall = 1; repeat (40) @(posedge clk); + if (dut.full !== 1'b1) begin $error("[rbuf] expected full before reset-while-full case"); errors++; end + rst_n = 0; repeat (3) @(posedge clk); rst_n = 1; force_stall = 0; + @(posedge clk); + if (d_rvalid !== 1'b0) begin $error("[rbuf] not empty after reset (full case)"); errors++; end + + // Phase 2: randomized responses + backpressure (accumulate transfers) + repeat (20000) @(posedge clk); + + // Phase 3 (directed): stall downstream so the buffer fills and STAYS full + // (u_rready must read 0 = !full), then hold full while d_rready=1 — the + // distinguishing full && d_rready case a fall-through skid would mishandle. + force_stall = 1; repeat (200) @(posedge clk); + force_stall = 0; force_ready = 1; repeat (200) @(posedge clk); + force_ready = 0; + + // Phase 4: freeze producer, drain fully + prod_freeze = 1; force_ready = 1; + begin int g; g = 0; while ((wr_seq !== rd_seq) && g < 4000) begin @(posedge clk); g++; end end + repeat (10) @(posedge clk); + + if (d_rvalid !== 1'b0) begin $error("[rbuf] not empty after drain (d_rvalid=%b)", d_rvalid); errors++; end + if (wr_seq !== rd_seq) begin $error("[rbuf] count mismatch: in %0d out %0d", wr_seq, rd_seq); errors++; end + if (wr_seq < 32'd2000) begin $error("[rbuf] too few transfers (%0d) — not meaningful", wr_seq); errors++; end + if (!saw_full_and_ready) begin $error("[rbuf] coverage: full && d_rready never observed — no-bypass case unexercised"); errors++; end + + $display("[tb_gs_axi_r_regbuf] in=%0d out=%0d errors=%0d", wr_seq, rd_seq, errors); + if (errors == 0) $display("[tb_gs_axi_r_regbuf] PASS"); + else $display("[tb_gs_axi_r_regbuf] FAIL"); + $finish; + end + + initial begin #2500000; $error("[tb_gs_axi_r_regbuf] TIMEOUT"); $finish; end +endmodule : tb_gs_axi_r_regbuf diff --git a/synth/de25_nano/top_psmct32_raster_demo/de25_nano_psmct32_raster_demo_top.qsf b/synth/de25_nano/top_psmct32_raster_demo/de25_nano_psmct32_raster_demo_top.qsf index 54d3f57..910eb1f 100644 --- a/synth/de25_nano/top_psmct32_raster_demo/de25_nano_psmct32_raster_demo_top.qsf +++ b/synth/de25_nano/top_psmct32_raster_demo/de25_nano_psmct32_raster_demo_top.qsf @@ -1062,6 +1062,7 @@ set_global_assignment -name SYSTEMVERILOG_FILE rtl/gif_gs/gs_lpddr_map_pkg.sv set_global_assignment -name SYSTEMVERILOG_FILE rtl/gif_gs/gs_lpddr_z_rmw.sv set_global_assignment -name SYSTEMVERILOG_FILE rtl/gif_gs/gs_axi_w_regbuf.sv set_global_assignment -name SYSTEMVERILOG_FILE rtl/gif_gs/gs_axi_aw_regbuf.sv +set_global_assignment -name SYSTEMVERILOG_FILE rtl/gif_gs/gs_axi_r_regbuf.sv set_global_assignment -name SYSTEMVERILOG_FILE rtl/gif_gs/gs_lpddr_zc_emit.sv # ---------------------------------------------------------------------------- # Design RTL added during the EE/qbert chapters (Ch287+) that reached the demo