From 1e56251fc1417ff53f2444c578e4a3323400c0c9 Mon Sep 17 00:00:00 2001 From: slederer Date: Sat, 31 Jan 2026 17:24:36 +0100 Subject: [PATCH] vgafb: buffer maskgen outputs to avoid timing problems --- lib/corelib.s | 5 ++- tridoracpu/tridoracpu.srcs/vgafb.v | 57 +++++++++++++++++------------- tridoracpu/tridoracpu.xpr | 8 ++--- 3 files changed, 37 insertions(+), 33 deletions(-) diff --git a/lib/corelib.s b/lib/corelib.s index b228d20..93dc81f 100644 --- a/lib/corelib.s +++ b/lib/corelib.s @@ -756,10 +756,9 @@ PUTPIXEL_4BPP: ; create pixel data from color value in ; leftmost pixel data bits (31-28) + LOADC 0 LOAD PUTPIXEL_COLOR - BROT - BROT - BROT + BPLC SHL 2 SHL 2 STORE.B FB_SHIFTER ; store pixel into shifter diff --git a/tridoracpu/tridoracpu.srcs/vgafb.v b/tridoracpu/tridoracpu.srcs/vgafb.v index 411e956..fd42627 100644 --- a/tridoracpu/tridoracpu.srcs/vgafb.v +++ b/tridoracpu/tridoracpu.srcs/vgafb.v @@ -162,10 +162,12 @@ module vgafb #(VMEM_ADDR_WIDTH = 15, VMEM_DATA_WIDTH = 32) ( reg [4:0] acc_shift_count; reg acc_start_shift; reg [VMEM_DATA_WIDTH-1:0] acc_mask_in; - wire [VMEM_DATA_WIDTH-1:0] acc_mask_out; - wire [VMEM_DATA_WIDTH-1:0] acc_shifter_mask; + reg [VMEM_DATA_WIDTH-1:0] acc_mask_buf; + reg [VMEM_DATA_WIDTH-1:0] acc_shiftmask_buf; + wire [VMEM_DATA_WIDTH-1:0] acc_shifter_mask = acc_shiftmask_buf; wire [VMEM_DATA_WIDTH-1:0] acc_shifter_out_h = acc_shifter_out[(VMEM_DATA_WIDTH*2)-1:VMEM_DATA_WIDTH]; wire [VMEM_DATA_WIDTH-1:0] acc_shifter_out_l = acc_shifter_out[VMEM_DATA_WIDTH-1:0]; + `endif assign vmem_rd_en = rd_en; @@ -176,9 +178,9 @@ module vgafb #(VMEM_ADDR_WIDTH = 15, VMEM_DATA_WIDTH = 32) ( (reg_sel == REG_CTL) ? status : `ifdef ENABLE_FB_ACCEL (reg_sel == REG_SHIFTER) ? acc_shifter_out_h: - (reg_sel == REG_SHIFTERM) ? acc_shifter_mask : + (reg_sel == REG_SHIFTERM) ? acc_shiftmask_buf : (reg_sel == REG_SHIFTERSP) ? acc_shifter_out_l : - (reg_sel == REG_MASKGEN) ? acc_mask_out : + (reg_sel == REG_MASKGEN) ? acc_mask_buf : `endif 32'hFFFFFFFF; @@ -335,27 +337,34 @@ module vgafb #(VMEM_ADDR_WIDTH = 15, VMEM_DATA_WIDTH = 32) ( acc_mask_in <= wr_data; end - assign acc_mask_out = { - {4{|{acc_mask_in[31:28]}}}, - {4{|{acc_mask_in[27:24]}}}, - {4{|{acc_mask_in[23:20]}}}, - {4{|{acc_mask_in[19:16]}}}, - {4{|{acc_mask_in[15:12]}}}, - {4{|{acc_mask_in[11:8]}}}, - {4{|{acc_mask_in[7:4]}}}, - {4{|{acc_mask_in[3:0]}}} - }; + // mask output is buffered to avoid timing problems + always @(posedge cpu_clk) + begin + acc_mask_buf <= { + {4{~|{acc_mask_in[31:28]}}}, + {4{~|{acc_mask_in[27:24]}}}, + {4{~|{acc_mask_in[23:20]}}}, + {4{~|{acc_mask_in[19:16]}}}, + {4{~|{acc_mask_in[15:12]}}}, + {4{~|{acc_mask_in[11:8]}}}, + {4{~|{acc_mask_in[7:4]}}}, + {4{~|{acc_mask_in[3:0]}}} + }; + end - assign acc_shifter_mask = { - {4{|{acc_shifter_out_h[31:28]}}}, - {4{|{acc_shifter_out_h[27:24]}}}, - {4{|{acc_shifter_out_h[23:20]}}}, - {4{|{acc_shifter_out_h[19:16]}}}, - {4{|{acc_shifter_out_h[15:12]}}}, - {4{|{acc_shifter_out_h[11:8]}}}, - {4{|{acc_shifter_out_h[7:4]}}}, - {4{|{acc_shifter_out_h[3:0]}}} - }; + always @(posedge cpu_clk) + begin + acc_shiftmask_buf = { + {4{~|{acc_shifter_out_h[31:28]}}}, + {4{~|{acc_shifter_out_h[27:24]}}}, + {4{~|{acc_shifter_out_h[23:20]}}}, + {4{~|{acc_shifter_out_h[19:16]}}}, + {4{~|{acc_shifter_out_h[15:12]}}}, + {4{~|{acc_shifter_out_h[11:8]}}}, + {4{~|{acc_shifter_out_h[7:4]}}}, + {4{~|{acc_shifter_out_h[3:0]}}} + }; + end `endif // diff --git a/tridoracpu/tridoracpu.xpr b/tridoracpu/tridoracpu.xpr index 4d21f83..a088319 100644 --- a/tridoracpu/tridoracpu.xpr +++ b/tridoracpu/tridoracpu.xpr @@ -358,9 +358,7 @@ - - Performs optimizations which creates alternative logic technology mapping, including disabling LUT combining, forcing F7/F8/F9 to logic, increasing the threshold of shift register inference. - + @@ -384,9 +382,7 @@ - - Best predicted directive for place_design. - +