vgafb: first attempt at shifter/masker acceleration functionality

This commit is contained in:
slederer 2026-01-26 02:03:28 +01:00
parent d17c4c41fd
commit 248c9ae919
3 changed files with 97 additions and 4 deletions

View file

@ -137,7 +137,7 @@ module top(
assign fb_wr_data = mem_write_data;
vgafb vgafb0(`clock, pixclk, rst,
mem_addr[3:0], fb_rd_data, fb_wr_data,
mem_addr[5:2], fb_rd_data, fb_wr_data,
fb_rd_en, fb_wr_en,
VGA_HS_O, VGA_VS_O, VGA_R, VGA_G, VGA_B);
`endif
@ -247,7 +247,7 @@ module top(
assign tdraudio_wr_data = mem_write_data;
tdraudio tdraudio0(`clock, ~rst,
mem_addr[6:0],
mem_addr[8:2],
tdraudio_rd_data,
tdraudio_wr_data,
tdraudio_rd_en,

View file

@ -1,6 +1,9 @@
`timescale 1ns / 1ps
`default_nettype none
// enable shifter/masker registers
`define ENABLE_FB_ACCEL
// Project F: Display Timings
// (C)2019 Will Green, Open Source Hardware released under the MIT License
// Learn more at https://projectf.io
@ -126,6 +129,14 @@ module vgafb #(VMEM_ADDR_WIDTH = 15, VMEM_DATA_WIDTH = 32) (
localparam REG_PAL_SLOT = 3; localparam REG_PAL_DATA = 4;
localparam REG_CTL = 5;
`ifdef ENABLE_FB_ACCEL
localparam REG_SHIFTER = 6;
localparam REG_SHIFTCOUNT = 7;
localparam REG_SHIFTERM = 9;
localparam REG_SHIFTERSP = 10;
localparam REG_MASKGEN = 11;
`endif
localparam COLOR_WIDTH = 12;
localparam PALETTE_WIDTH = 4;
@ -145,12 +156,30 @@ module vgafb #(VMEM_ADDR_WIDTH = 15, VMEM_DATA_WIDTH = 32) (
wire pix_rd;
wire [VMEM_DATA_WIDTH-1:0] status;
`ifdef ENABLE_FB_ACCEL
reg [VMEM_DATA_WIDTH-1:0] acc_shifter_in;
reg [(VMEM_DATA_WIDTH*2)-1:0] acc_shifter_out;
reg [2: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;
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;
assign vmem_wr_en = (reg_sel == REG_VMEM) && wr_en;
assign rd_data = (reg_sel == REG_VMEM) ? vmem_rd_data :
(reg_sel == REG_RD_ADDR) ? cpu_rd_addr :
(reg_sel == REG_WR_ADDR) ? cpu_wr_addr :
(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_SHIFTERSP) ? acc_shifter_out_l :
(reg_sel == REG_MASKGEN) ? acc_mask_out :
`endif
32'hFFFFFFFF;
wire [VMEM_ADDR_WIDTH-1:0] cpu_addr = vmem_wr_en ? cpu_wr_addr : cpu_rd_addr;
@ -271,6 +300,71 @@ module vgafb #(VMEM_ADDR_WIDTH = 15, VMEM_DATA_WIDTH = 32) (
if(rd_en && reg_sel == REG_VMEM) cpu_rd_addr <= cpu_rd_addr + 1; // auto-increment read addr on read
end
`ifdef ENABLE_FB_ACCEL
//
// shifter/masker registers
//
always @(posedge cpu_clk)
begin
if(wr_en && reg_sel == REG_SHIFTER)
acc_shifter_in <= { wr_data, {32{1'b0}}};
end
always @(posedge cpu_clk)
begin
if(wr_en && reg_sel == REG_SHIFTCOUNT)
begin
acc_shift_count <= wr_data[2:0];
acc_start_shift <= 1;
end
if(acc_start_shift)
acc_start_shift <= 0;
end
always @(posedge cpu_clk)
begin
if (acc_start_shift)
begin
acc_shifter_out <= {acc_shifter_in, {VMEM_DATA_WIDTH{1'b0}}} >> acc_shift_count;
end
end
// mask register
always @(posedge cpu_clk)
begin
if (wr_en && reg_sel == REG_MASKGEN)
begin
acc_mask_in <= wr_data;
end
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]}}}
};
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]}}}
};
`endif
//
// shifting pixels at pixel clock
//
always @(posedge pix_clk)
begin
if(scanline || shift_count == MAX_SHIFT_COUNT) // before start of a line

View file

@ -376,7 +376,7 @@
<Report Name="ROUTE_DESIGN.REPORT_METHODOLOGY" Enabled="1"/>
<RQSFiles/>
</Run>
<Run Id="impl_1" Type="Ft2:EntireDesign" Part="xc7a35ticsg324-1L" ConstrsSet="constrs_1" Description="Default settings for Implementation." AutoIncrementalCheckpoint="false" WriteIncrSynthDcp="false" State="current" Dir="$PRUNDIR/impl_1" SynthRun="synth_1" IncludeInArchive="true" IsChild="false" GenFullBitstream="true" AutoIncrementalDir="$PSRCDIR/utils_1/imports/impl_1" LaunchOptions="-jobs 6 " AutoRQSDir="$PSRCDIR/utils_1/imports/impl_1" ParallelReportGen="true">
<Run Id="impl_1" Type="Ft2:EntireDesign" Part="xc7a35ticsg324-1L" ConstrsSet="constrs_1" Description="Default settings for Implementation." AutoIncrementalCheckpoint="false" WriteIncrSynthDcp="false" State="current" SynthRun="synth_1" IncludeInArchive="true" IsChild="false" GenFullBitstream="true" AutoIncrementalDir="$PSRCDIR/utils_1/imports/impl_1" LaunchOptions="-jobs 6 " AutoRQSDir="$PSRCDIR/utils_1/imports/impl_1" ParallelReportGen="true">
<Strategy Version="1" Minor="2">
<StratHandle Name="Vivado Implementation Defaults" Flow="Vivado Implementation 2024"/>
<Step Id="init_design"/>
@ -389,7 +389,6 @@
<Step Id="post_route_phys_opt_design"/>
<Step Id="write_bitstream"/>
</Strategy>
<GeneratedRun Dir="$PRUNDIR" File="gen_run.xml"/>
<ReportStrategy Name="Vivado Implementation Default Reports" Flow="Vivado Implementation 2024"/>
<Report Name="ROUTE_DESIGN.REPORT_METHODOLOGY" Enabled="1"/>
<RQSFiles/>