OpenCores
URL https://opencores.org/ocsvn/orsoc_graphics_accelerator/orsoc_graphics_accelerator/trunk

Subversion Repositories orsoc_graphics_accelerator

[/] [orsoc_graphics_accelerator/] [trunk/] [rtl/] [verilog/] [gfx/] [gfx_transform.v] - Rev 6

Compare with Previous | Blame | View Log

/*
ORSoC GFX accelerator core
Copyright 2012, ORSoC, Per Lenander, Anton Fosselius.
 
TRANSFORMATION PROCESSING MODULE
 
 This file is part of orgfx.
 
 orgfx is free software: you can redistribute it and/or modify
 it under the terms of the GNU Lesser General Public License as published by
 the Free Software Foundation, either version 3 of the License, or
 (at your option) any later version. 
 
 orgfx is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU Lesser General Public License for more details.
 
 You should have received a copy of the GNU Lesser General Public License
 along with orgfx.  If not, see <http://www.gnu.org/licenses/>.
 
*/
 
/*
 
Input matrix M:
    | aa ab ac tx |
M = | ba bb bc ty |
    | ca cb cc tz |
 
Input point X:
    | x |
X = | y |
    | z |
    | 1 |
 
Output point X':
     | x' |        | aa*x + ab*y + ac*z + tx |
X' = | y' | = MX = | ba*x + bb*y + bc*z + ty |
     | z' |        | ca*x + cb*y + cc*z + tz |
 
*/
 
/* Transforms points with a 4x3 matrix */
module gfx_transform(clk_i, rst_i,
// Input point
x_i, y_i, z_i, point_id_i,
// Matrix
aa, ab, ac, tx, ba, bb, bc, ty, ca, cb, cc, tz, // TODO: Make signed
// Output points
p0_x_o, p0_y_o, p0_z_o, p1_x_o, p1_y_o, p1_z_o, p2_x_o, p2_y_o, p2_z_o,
transform_i, forward_i,
ack_o
);
 
input clk_i;
input rst_i;
 
parameter point_width = 16;
parameter subpixel_width = 16;
 
input signed [point_width-1:-subpixel_width] x_i;
input signed [point_width-1:-subpixel_width] y_i;
input signed [point_width-1:-subpixel_width] z_i;
input                                  [1:0] point_id_i; // point 0,1,2
 
input signed [point_width-1:-subpixel_width] aa;
input signed [point_width-1:-subpixel_width] ab;
input signed [point_width-1:-subpixel_width] ac;
input signed [point_width-1:-subpixel_width] tx;
input signed [point_width-1:-subpixel_width] ba;
input signed [point_width-1:-subpixel_width] bb;
input signed [point_width-1:-subpixel_width] bc;
input signed [point_width-1:-subpixel_width] ty;
input signed [point_width-1:-subpixel_width] ca;
input signed [point_width-1:-subpixel_width] cb;
input signed [point_width-1:-subpixel_width] cc;
input signed [point_width-1:-subpixel_width] tz;
 
output reg signed [point_width-1:-subpixel_width] p0_x_o;
output reg signed [point_width-1:-subpixel_width] p0_y_o;
output reg signed               [point_width-1:0] p0_z_o;
output reg signed [point_width-1:-subpixel_width] p1_x_o;
output reg signed [point_width-1:-subpixel_width] p1_y_o;
output reg signed               [point_width-1:0] p1_z_o;
output reg signed [point_width-1:-subpixel_width] p2_x_o;
output reg signed [point_width-1:-subpixel_width] p2_y_o;
output reg signed               [point_width-1:0] p2_z_o;
 
input transform_i, forward_i;
 
output reg ack_o;
 
reg [1:0] state;
parameter wait_state = 2'b00, forward_state = 2'b01, transform_state = 2'b10;
 
reg signed [2*point_width-1:-subpixel_width*2] aax;
reg signed [2*point_width-1:-subpixel_width*2] aby;
reg signed [2*point_width-1:-subpixel_width*2] acz;
reg signed [2*point_width-1:-subpixel_width*2] bax;
reg signed [2*point_width-1:-subpixel_width*2] bby;
reg signed [2*point_width-1:-subpixel_width*2] bcz;
reg signed [2*point_width-1:-subpixel_width*2] cax;
reg signed [2*point_width-1:-subpixel_width*2] cby;
reg signed [2*point_width-1:-subpixel_width*2] ccz;
 
always @(posedge clk_i or posedge rst_i)
if(rst_i)
begin
  // Initialize registers
  ack_o             <= 1'b0;
  p0_x_o            <= 1'b0;
  p0_y_o            <= 1'b0;
  p0_z_o            <= 1'b0;
  p1_x_o            <= 1'b0;
  p1_y_o            <= 1'b0;
  p1_z_o            <= 1'b0;
  p2_x_o            <= 1'b0;
  p2_y_o            <= 1'b0;
  p2_z_o            <= 1'b0;
 
  aax               <= 1'b0;
  aby               <= 1'b0;
  acz               <= 1'b0;
  bax               <= 1'b0;
  bby               <= 1'b0;
  bcz               <= 1'b0;
  cax               <= 1'b0;
  cby               <= 1'b0;
  ccz               <= 1'b0;
end
else
  case(state)
    wait_state:
    begin
      ack_o <= 1'b0;
 
      // Begin transformation
      if(transform_i)
      begin
        aax <= aa * x_i;
        aby <= ab * y_i;
        acz <= ac * z_i;
        bax <= ba * x_i;
        bby <= bb * y_i;
        bcz <= bc * z_i;
        cax <= ca * x_i;
        cby <= cb * y_i;
        ccz <= cc * z_i;
      end
      // Forward the point
      else if(forward_i)
      begin
        if(point_id_i == 2'b00)
        begin
          p0_x_o <= x_i;
          p0_y_o <= y_i;
          p0_z_o <= z_i[point_width-1:0];
        end
        else if(point_id_i == 2'b01)
        begin
          p1_x_o <= x_i;
          p1_y_o <= y_i;
          p1_z_o <= z_i[point_width-1:0];
        end
        else if(point_id_i == 2'b10)
        begin
          p2_x_o <= x_i;
          p2_y_o <= y_i;
          p2_z_o <= z_i[point_width-1:0];
        end
      end
    end
 
    forward_state:
      ack_o <= 1'b1;
 
    transform_state:
    begin
      ack_o <= 1'b1;
 
      if(point_id_i == 2'b00)
        begin
          p0_x_o <= x_prime_trunc;
          p0_y_o <= y_prime_trunc;
          p0_z_o <= z_prime_trunc[point_width-1:0];
        end
        else if(point_id_i == 2'b01)
        begin
          p1_x_o <= x_prime_trunc;
          p1_y_o <= y_prime_trunc;
          p1_z_o <= z_prime_trunc[point_width-1:0];
        end
        else if(point_id_i == 2'b10)
        begin
          p2_x_o <= x_prime_trunc;
          p2_y_o <= y_prime_trunc;
          p2_z_o <= z_prime_trunc[point_width-1:0];
        end
    end
  endcase
 
wire [subpixel_width-1:0] zeroes = 1'b0;
 
wire signed [2*point_width-1:-subpixel_width*2] x_prime = aax + aby + acz + {tx,zeroes};
wire signed [2*point_width-1:-subpixel_width*2] y_prime = bax + bby + bcz + {ty,zeroes};
wire signed [2*point_width-1:-subpixel_width*2] z_prime = cax + cby + ccz + {tz,zeroes};
 
wire signed [point_width-1:-subpixel_width] x_prime_trunc = x_prime[point_width-1:-subpixel_width];
wire signed [point_width-1:-subpixel_width] y_prime_trunc = y_prime[point_width-1:-subpixel_width];
wire signed [point_width-1:-subpixel_width] z_prime_trunc = z_prime[point_width-1:-subpixel_width];
 
// State machine
always @(posedge clk_i or posedge rst_i)
if(rst_i)
  state <= wait_state;
else
  case(state)
    wait_state:
      if(transform_i)
        state <= transform_state;
      else if(forward_i)
        state <= forward_state;
 
    forward_state:
      state <= wait_state;
 
    transform_state:
      state <= wait_state;
  endcase
 
endmodule
 
 

Compare with Previous | Blame | View Log

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.