vgafb: first attempt at shifter/masker acceleration functionality
This commit is contained in:
parent
d17c4c41fd
commit
248c9ae919
3 changed files with 97 additions and 4 deletions
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue