├── SimpleGPUonS7.srcs
├── sources_1
│ ├── new
│ │ ├── testMatrixData.mem
│ │ ├── sram_tte_example.v
│ │ ├── staticRam.v
│ │ ├── spi_slave.v
│ │ ├── dualPortRam.v
│ │ ├── ViewToScreenConverter.v
│ │ ├── FiFO.v
│ │ ├── vgaSignalGenerator.v
│ │ ├── vert_projector.v
│ │ ├── matrix4x4x1.v
│ │ └── top.v
│ └── imports
│ │ └── Desktop
│ │ ├── qadd.v
│ │ ├── qmult.v
│ │ ├── qmults.v
│ │ └── qdiv.v
├── sim_1
│ └── new
│ │ ├── FIFO_Test.v
│ │ ├── test_matrixMult.v
│ │ └── test_vert_projector.v
└── constrs_1
│ └── new
│ └── s7.xdc
├── docs
├── output.jpg
├── setup.png
└── gpusimple-2.png
├── waveforms
└── debugging counter.dwf3work
├── SimpleGPUonS7.ip_user_files
└── README.txt
├── README.md
├── SimpleGPUonS7.sim
└── sim_1
│ └── behav
│ └── xsim
│ └── glbl.v
├── .gitignore
├── SimpleGPUonS7.xpr
└── LICENSE
/SimpleGPUonS7.srcs/sources_1/new/testMatrixData.mem:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/docs/output.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mjkkirschner/simpleGPUCore/HEAD/docs/output.jpg
--------------------------------------------------------------------------------
/docs/setup.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mjkkirschner/simpleGPUCore/HEAD/docs/setup.png
--------------------------------------------------------------------------------
/docs/gpusimple-2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mjkkirschner/simpleGPUCore/HEAD/docs/gpusimple-2.png
--------------------------------------------------------------------------------
/waveforms/debugging counter.dwf3work:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mjkkirschner/simpleGPUCore/HEAD/waveforms/debugging counter.dwf3work
--------------------------------------------------------------------------------
/SimpleGPUonS7.ip_user_files/README.txt:
--------------------------------------------------------------------------------
1 | The files in this directory structure are automatically generated and managed by Vivado. Editing these files is not recommended.
2 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # simpleGPUCore
2 | verilog/FPGA hardware description for very simple GPU
3 |
4 | diagram:
5 | 
6 | sample output:
7 | 
8 |
9 | references:
10 |
11 | * vga: https://github.com/WillGreen/timetoexplore
12 | * fixedpoint math: https://opencores.org/projects/verilog_fixed_point_math_library
13 | * spi: https://www.fpga4fun.com/SPI2.html
14 |
--------------------------------------------------------------------------------
/SimpleGPUonS7.srcs/sources_1/new/sram_tte_example.v:
--------------------------------------------------------------------------------
1 | module sram #(parameter ADDR_WIDTH=8, DATA_WIDTH=8, DEPTH=256, MEMFILE="") (
2 | input wire i_clk,
3 | input wire [ADDR_WIDTH-1:0] i_addr,
4 | input wire i_write,
5 | input wire [DATA_WIDTH-1:0] i_data,
6 | output reg [DATA_WIDTH-1:0] o_data
7 | );
8 |
9 | reg [DATA_WIDTH-1:0] memory_array [0:DEPTH-1];
10 |
11 | initial begin
12 | if (MEMFILE > 0)
13 | begin
14 | $display("Loading memory init file '" + MEMFILE + "' into array.");
15 | $readmemh(MEMFILE, memory_array);
16 | end
17 | end
18 |
19 | always @ (posedge i_clk)
20 | begin
21 | if(i_write) begin
22 | memory_array[i_addr] <= i_data;
23 | end
24 | else begin
25 | o_data <= memory_array[i_addr];
26 | end
27 | end
28 | endmodule
29 |
--------------------------------------------------------------------------------
/SimpleGPUonS7.srcs/sources_1/new/staticRam.v:
--------------------------------------------------------------------------------
1 | (* DONT_TOUCH = "yes" *)
2 | //-----------------------------------------------------
3 | module staticRamDiscretePorts (
4 | address , // Address Input
5 | data , // Data input
6 | we_,
7 | clock,
8 | Q //output
9 | );
10 | parameter ROMFILE = "noFile";
11 | parameter DATA_WIDTH = 8 ;
12 | parameter ADDR_WIDTH = 8 ;
13 | parameter RAM_DEPTH = 1 << ADDR_WIDTH;
14 |
15 |
16 | //--------------Input Ports-----------------------
17 | input [ADDR_WIDTH-1:0] address ;
18 | input [DATA_WIDTH-1:0] data;
19 | input we_;
20 | input clock;
21 |
22 | //--------------Output Ports-----------------------
23 | output reg [DATA_WIDTH-1:0] Q;
24 | integer i;
25 | //--------------Internal variables----------------
26 | reg [DATA_WIDTH-1:0] mem [RAM_DEPTH-1:0];
27 |
28 | //--------------Code Starts Here------------------
29 | initial begin
30 | $readmemb(ROMFILE, mem);
31 | for (i = 0; i < RAM_DEPTH; i = i + 1) begin
32 | //#1 $display("%d",mem[i]);
33 | end
34 | end
35 |
36 | always @(posedge clock)
37 | begin
38 | if (!we_) begin
39 | mem[address] <= data;
40 | end
41 | else begin
42 | Q <= mem[address];
43 | end
44 | end
45 |
46 | endmodule
47 |
--------------------------------------------------------------------------------
/SimpleGPUonS7.sim/sim_1/behav/xsim/glbl.v:
--------------------------------------------------------------------------------
1 | // $Header: /devl/xcs/repo/env/Databases/CAEInterfaces/verunilibs/data/glbl.v,v 1.14 2010/10/28 20:44:00 fphillip Exp $
2 | `ifndef GLBL
3 | `define GLBL
4 | `timescale 1 ps / 1 ps
5 |
6 | module glbl ();
7 |
8 | parameter ROC_WIDTH = 100000;
9 | parameter TOC_WIDTH = 0;
10 |
11 | //-------- STARTUP Globals --------------
12 | wire GSR;
13 | wire GTS;
14 | wire GWE;
15 | wire PRLD;
16 | tri1 p_up_tmp;
17 | tri (weak1, strong0) PLL_LOCKG = p_up_tmp;
18 |
19 | wire PROGB_GLBL;
20 | wire CCLKO_GLBL;
21 | wire FCSBO_GLBL;
22 | wire [3:0] DO_GLBL;
23 | wire [3:0] DI_GLBL;
24 |
25 | reg GSR_int;
26 | reg GTS_int;
27 | reg PRLD_int;
28 |
29 | //-------- JTAG Globals --------------
30 | wire JTAG_TDO_GLBL;
31 | wire JTAG_TCK_GLBL;
32 | wire JTAG_TDI_GLBL;
33 | wire JTAG_TMS_GLBL;
34 | wire JTAG_TRST_GLBL;
35 |
36 | reg JTAG_CAPTURE_GLBL;
37 | reg JTAG_RESET_GLBL;
38 | reg JTAG_SHIFT_GLBL;
39 | reg JTAG_UPDATE_GLBL;
40 | reg JTAG_RUNTEST_GLBL;
41 |
42 | reg JTAG_SEL1_GLBL = 0;
43 | reg JTAG_SEL2_GLBL = 0 ;
44 | reg JTAG_SEL3_GLBL = 0;
45 | reg JTAG_SEL4_GLBL = 0;
46 |
47 | reg JTAG_USER_TDO1_GLBL = 1'bz;
48 | reg JTAG_USER_TDO2_GLBL = 1'bz;
49 | reg JTAG_USER_TDO3_GLBL = 1'bz;
50 | reg JTAG_USER_TDO4_GLBL = 1'bz;
51 |
52 | assign (strong1, weak0) GSR = GSR_int;
53 | assign (strong1, weak0) GTS = GTS_int;
54 | assign (weak1, weak0) PRLD = PRLD_int;
55 |
56 | initial begin
57 | GSR_int = 1'b1;
58 | PRLD_int = 1'b1;
59 | #(ROC_WIDTH)
60 | GSR_int = 1'b0;
61 | PRLD_int = 1'b0;
62 | end
63 |
64 | initial begin
65 | GTS_int = 1'b1;
66 | #(TOC_WIDTH)
67 | GTS_int = 1'b0;
68 | end
69 |
70 | endmodule
71 | `endif
72 |
--------------------------------------------------------------------------------
/SimpleGPUonS7.srcs/sources_1/new/spi_slave.v:
--------------------------------------------------------------------------------
1 | `timescale 1ns / 1ps
2 |
3 | //inspired by https://www.fpga4fun.com/SPI2.html
4 |
5 | module SPI_slave(i_base_clock, i_SCK, i_MOSI, i_EN, o_WORDVALID,o_DATA,o_COUNTER);
6 |
7 |
8 | input i_base_clock;
9 | input i_SCK, i_EN,i_MOSI;
10 | parameter n = 32;
11 |
12 | output reg o_WORDVALID;
13 | output wire [n-1:0] o_DATA;
14 | output [7:0] o_COUNTER;
15 |
16 | assign o_COUNTER = counter;
17 |
18 | reg[2:0] sck_samples = 0;
19 | reg[2:0] en_samples = 0;
20 | reg[1:0] mosi_samples = 0;
21 |
22 | wire validInputData = mosi_samples[1];
23 | wire enableActive = ~en_samples[1]; //active low
24 |
25 | always @(posedge i_base_clock) begin
26 |
27 | sck_samples <= {sck_samples[1:0],i_SCK};
28 | en_samples <= {en_samples[1:0],i_EN};
29 | mosi_samples <= {mosi_samples[0],i_MOSI};
30 |
31 | end
32 |
33 | //recieve data from avr
34 | //parameterize this better...
35 | reg [7:0] counter = 0;
36 | reg [n-1:0] dataInputRegister = 0;
37 | assign o_DATA = dataInputRegister;
38 |
39 |
40 | always@(posedge i_base_clock) begin
41 | //if enable is true, and serial clock is rising
42 | //read data
43 | if(enableActive && sck_samples[2:1] == 2'b01) begin
44 | counter <= counter +1;
45 | //read a bit of the data into the register
46 | dataInputRegister <= {dataInputRegister[n-2:0],validInputData};
47 | end //if
48 | else
49 | if (enableActive == 0) begin
50 | counter <= 0;
51 | end
52 |
53 | end
54 |
55 | //TODO does this need more constraints?
56 | always@(posedge i_base_clock) begin
57 | if( (counter == n-1) && enableActive && (sck_samples[2:1] == 2'b01) ) begin
58 | o_WORDVALID <= 1;
59 | end
60 | else begin
61 | o_WORDVALID <= 0;
62 | end
63 | end
64 |
65 | endmodule
--------------------------------------------------------------------------------
/SimpleGPUonS7.srcs/sources_1/new/dualPortRam.v:
--------------------------------------------------------------------------------
1 | (* DONT_TOUCH = "yes" *)
2 | //-----------------------------------------------------
3 | module dualPortStaticRam (
4 | address_1 , // Address Input
5 | address_2 , // Address Input
6 | data , // Data input
7 | we_,
8 | clock,
9 | clock2,
10 | Q_1, //output
11 | Q_2 //output
12 | );
13 | parameter ROMFILE = "noFile";
14 | parameter DATA_WIDTH = 8 ;
15 | parameter ADDR_WIDTH = 8 ;
16 | parameter RAM_DEPTH = 1 << ADDR_WIDTH;
17 |
18 |
19 | //--------------Input Ports-----------------------
20 | input [ADDR_WIDTH-1:0] address_1 ;
21 | input [ADDR_WIDTH-1:0] address_2 ;
22 | input [DATA_WIDTH-1:0] data;
23 | input we_;
24 | input clock;
25 | input clock2;
26 |
27 | //--------------Output Ports-----------------------
28 | output reg [DATA_WIDTH-1:0] Q_1;
29 | output reg [DATA_WIDTH-1:0] Q_2;
30 | integer i;
31 | //--------------Internal variables----------------
32 | reg [DATA_WIDTH-1:0] mem [RAM_DEPTH-1:0];
33 |
34 | //--------------Code Starts Here------------------
35 | initial begin
36 | $readmemb(ROMFILE, mem);
37 | for (i = 0; i < RAM_DEPTH; i = i + 1) begin
38 | //#1 $display("%d: %d ",i,mem[i]);
39 | end
40 | end
41 |
42 | always @(posedge clock)
43 | begin
44 | if (!we_) begin
45 | mem[address_1] = data;
46 | end
47 | else begin
48 | Q_1 <= mem[address_1];
49 | end
50 | end
51 |
52 | always@(posedge clock2) begin
53 | Q_2 = mem[address_2];
54 | end
55 |
56 | endmodule
--------------------------------------------------------------------------------
/SimpleGPUonS7.srcs/sim_1/new/FIFO_Test.v:
--------------------------------------------------------------------------------
1 | `timescale 1ns / 1ps
2 |
3 | module FIFO_Test;
4 |
5 | //inputs
6 | reg [15:0] inputData = 0;
7 | wire [15:0] outputData;
8 |
9 | reg clock = 0;
10 | wire reset = 0;
11 | reg readVertex = 0;
12 | reg writeVertex = 0;
13 | wire empty;
14 | wire full;
15 |
16 | FIFO#(.DATA_WIDTH(16),.RAM_DEPTH(3))
17 |
18 | uut (
19 | .clk_i(clock),
20 | .reset_i(reset),
21 | .data_i(inputData),
22 | .r_en_i(readVertex),
23 | .w_en_i(writeVertex),
24 | .data_o(outputData),
25 | .empty_o(empty),
26 | .full_o(full));
27 |
28 | initial begin
29 | $monitor ("input: %b, output: %b, empty %b, full %b", inputData, outputData, empty, full); //Monitor the stuff we care about
30 |
31 | //first input data word
32 | #10 inputData = 16'b0000000000000001;
33 |
34 | //assert write
35 | #10 writeVertex = 1;
36 |
37 | //change data
38 | #10 inputData = 16'b0000000000000010;
39 |
40 | //change data
41 | #10 inputData = 16'b0000000000000011;
42 |
43 | //assert write off
44 | #10 writeVertex = 0;
45 | #100 readVertex = 1;
46 |
47 | end
48 |
49 |
50 | always begin
51 | #5 clock = ! clock;
52 | end
53 |
54 | endmodule
55 |
--------------------------------------------------------------------------------
/SimpleGPUonS7.srcs/sim_1/new/test_matrixMult.v:
--------------------------------------------------------------------------------
1 | `timescale 1ns / 1ps
2 | //////////////////////////////////////////////////////////////////////////////////
3 | // Company:
4 | // Engineer:
5 | //
6 | // Create Date: 12/23/2018 06:51:22 PM
7 | // Design Name:
8 | // Module Name: test_matrixMult
9 | // Project Name:
10 | // Target Devices:
11 | // Tool Versions:
12 | // Description:
13 | //
14 | // Dependencies:
15 | //
16 | // Revision:
17 | // Revision 0.01 - File Created
18 | // Additional Comments:
19 | //
20 | //////////////////////////////////////////////////////////////////////////////////
21 |
22 |
23 | module test_matrixMult;
24 |
25 | //inputs
26 | reg [255:0] mvp_in;
27 | reg [63:0] vertex_in;
28 |
29 | //outputs
30 | wire [63:0] result;
31 |
32 | matrix4x4x1
33 | #(
34 | .Q(4),
35 | .N(16))
36 |
37 | uut(.mvp_in( mvp_in),
38 | .vertex_in(vertex_in),
39 | .result( result)
40 | );
41 |
42 | initial begin
43 | $monitor ("%b,%b,%b", mvp_in, vertex_in, result); // Monitor the stuff we care about
44 |
45 | //ident matrix
46 | #10 mvp_in = {{16'b0000000000010000},{16'b0000000000000000},{16'b0000000000000000},{16'b0000000000000000},
47 | {16'b0000000000000000},{16'b0000000000010000},{16'b0000000000000000},{16'b0000000000000000},
48 | {16'b0000000000000000},{16'b0000000000000000},{16'b0000000000010000},{16'b0000000000000000},
49 | {16'b0000000000000000},{16'b0000000000000000},{16'b0000000000000000},{16'b0000000000010000}
50 | };
51 |
52 | #10 vertex_in = {{16'd0},{16'd0},{16'd0},{16'd0}};
53 | end
54 |
55 | always begin
56 | #10 vertex_in = {{16'b0000000001010000},{16'b0000000001010000},{16'b0000000001010000},{16'b0000000001010000}};
57 | end
58 | endmodule
59 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | #########################################################################################################
2 | ## This is an example .gitignore file for Vivado, please treat it as an example as
3 | ## it might not be complete. In addition, XAPP 1165 should be followed.
4 | #########################################################################################################
5 | #########
6 | #Exclude all
7 | #########
8 | *
9 | !*/
10 | !.gitignore
11 | ###########################################################################
12 | ## VIVADO
13 | ###########################################################################
14 | #########
15 | #Source files:
16 | #########
17 | #Do NOT ignore VHDL, Verilog, block diagrams or EDIF files.
18 | !*.vhd
19 | !*.v
20 | !*.bd
21 | !*.edif
22 | #########
23 | #IP files
24 | #########
25 | #.xci: synthesis and implemented not possible - you need to return back to the previous version to generate output products
26 | #.xci + .dcp: implementation possible but not re-synthesis
27 | #*.xci(www.spiritconsortium.org)
28 | !*.xci
29 | #*.dcp(checkpoint files)
30 | !*.dcp
31 | !*.vds
32 | !*.pb
33 | #All bd comments and layout coordinates are stored within .ui
34 | !*.ui
35 | !*.ooc
36 | #########
37 | #System Generator
38 | #########
39 | !*.mdl
40 | !*.slx
41 | !*.bxml
42 | #########
43 | #Simulation logic analyzer
44 | #########
45 | !*.wcfg
46 | !*.coe
47 | #########
48 | #MIG
49 | #########
50 | !*.prj
51 | !*.mem
52 | #########
53 | #Project files
54 | #########
55 | #XPR + *.XML ? XPR (Files are merged into a single XPR file for 2014.1 version)
56 | #Do NOT ignore *.xpr files
57 | !*.xpr
58 | #Include *.xml files for 2013.4 or earlier version
59 | !*.xml
60 | #########
61 | #Constraint files
62 | #########
63 | #Do NOT ignore *.xdc files
64 | !*.xdc
65 | #########
66 | #TCL - files
67 | #########
68 | !*.tcl
69 | #########
70 | #Journal - files
71 | #########
72 | !*.jou
73 | #########
74 | #Reports
75 | #########
76 | !*.rpt
77 | !*.txt
78 | !*.vdi
79 | #########
80 | #C-files
81 | #########
82 | !*.c
83 | !*.h
84 | !*.elf
85 | !*.bmm
86 | !*.xmp
--------------------------------------------------------------------------------
/SimpleGPUonS7.srcs/sim_1/new/test_vert_projector.v:
--------------------------------------------------------------------------------
1 | `timescale 1ns / 1ps
2 |
3 | module test_vert_projector(
4 |
5 | );
6 | //inputs
7 | reg clk, inStart;
8 | reg [255:0] mvp_in;
9 | reg [63:0] vertex_in;
10 |
11 | //outputs
12 | wire [47:0] projected_vector;
13 | wire out_done;
14 |
15 | vert_projector #(.Q(4),.N(16))
16 | uut(.i_clk(clk),
17 | .in_start(inStart),
18 | .mvp_in( mvp_in),
19 | .vertex_in(vertex_in),
20 | .out_vector( projected_vector),
21 | .out_done(out_done)
22 | );
23 |
24 |
25 | initial
26 | begin
27 | $monitor ("matrix: %b \n, vertex: %b \n ,projectedVert: %b \n ,start: %b \n, done: %b \n", mvp_in, vertex_in, projected_vector, inStart , out_done); // Monitor the stuff we care about
28 | clk = 0;
29 | inStart = 0;
30 | mvp_in = {{16'b0000000000010000},{16'b0000000000000000},{16'b0000000000000000},{16'b0000000000000000},
31 | {16'b0000000000000000},{16'b0000000000010000},{16'b0000000000000000},{16'b0000000000000000},
32 | {16'b0000000000000000},{16'b0000000000000000},{16'b0000000000010000},{16'b0000000000000000},
33 | {16'b0000000000000000},{16'b0000000000000000},{16'b0000000000000000},{16'b0000000000010000}
34 | };
35 | vertex_in = {{16'b0000000001010000},{16'b0000000001010000},{16'b0000000001010000},{16'b0000000000010000}};
36 |
37 | #100 inStart <= 1;
38 |
39 |
40 | end
41 |
42 | always
43 | #5 clk = ! clk;
44 |
45 |
46 | endmodule
47 |
--------------------------------------------------------------------------------
/SimpleGPUonS7.srcs/sources_1/new/ViewToScreenConverter.v:
--------------------------------------------------------------------------------
1 | `timescale 1ns / 1ps
2 | module ViewToScreenConverter(
3 |
4 |
5 | input [11:0] width_in,
6 | input [11:0] height_in,
7 | //vector format(x,y,z) each component is [1signbit,N-1databits,Qbits]
8 | input [(N*3)-1:0] vector_in,
9 |
10 | //the final pixels - these should be unsigned integers I think...?
11 | output [11:0] xpix_out,
12 | output [11:0] ypix_out,
13 | output on_screen_out
14 |
15 | );
16 |
17 | parameter Q = 8;
18 | parameter N = 16;
19 |
20 | wire [N-1:0] xResult1;
21 | wire [N-1:0] yResult1;
22 | wire [N-1:0] xResult2;
23 | wire [N-1:0] yResult2;
24 |
25 | wire [N-1:0] xInteger;
26 | wire [N-1:0] yInteger;
27 |
28 | wire [11:0] halfWidth = width_in >> 1;
29 | wire [11:0] halfHeight = height_in >> 1;
30 |
31 | // drop upper Q bits (max width is 2048... 2^11) not a problem for 640x480 vga output
32 | //TODO do we need to concat extra 0's in front here?
33 | wire [N-1:0] fixedPointHalfWidth = {{4{1'b0}},halfWidth, {Q{1'b0}}};
34 | wire [N-1:0] fixedPointHalfHeight = {{4{1'b0}},halfHeight, {Q{1'b0}}};
35 |
36 |
37 | qadd #(
38 | .Q(Q),
39 | .N(N)) addXandWidth(xInteger,fixedPointHalfWidth,xResult2);
40 |
41 | qadd #(
42 | .Q(Q),
43 | .N(N)) addYandHeight(yInteger,fixedPointHalfHeight,yResult2);
44 |
45 | // multiply x cord
46 | qmult #(
47 | .Q(Q),
48 | .N(N)) mult1x(fixedPointHalfWidth,vector_in[(N*3)-1:(N*2)],xResult1);
49 | //multiply by neg y coord to get correct scaling. (non mirrored)
50 | qmult #(
51 | .Q(Q),
52 | .N(N)) mult1y({1'b1,fixedPointHalfHeight[N-2:0]},vector_in[(N*2)-1:(N*1)],yResult1);
53 |
54 |
55 | //this converts the resulting normalized value to the screen integer as a Q number.
56 | assign xInteger = {xResult1[N-1:Q],{Q{1'b0}}};
57 | assign yInteger = {yResult1[N-1:Q],{Q{1'b0}}};
58 | // this converts the resulting Q addition to an unsigned integer, shifting down by Q bits
59 | assign xpix_out = xResult2[N-1:Q];
60 | assign ypix_out = yResult2[N-1:Q];
61 |
62 | //on_screen is high only when x and y values are between 0 and width/height.
63 | assign on_screen_out = (xpix_out < width_in) && (xpix_out >=0) && (ypix_out < height_in) && (ypix_out >= 0);
64 |
65 |
66 | endmodule
67 |
--------------------------------------------------------------------------------
/SimpleGPUonS7.srcs/sources_1/imports/Desktop/qadd.v:
--------------------------------------------------------------------------------
1 | `timescale 1ns / 1ps
2 | //////////////////////////////////////////////////////////////////////////////////
3 | // Company:
4 | // Engineer:
5 | //
6 | // Create Date: 09:28:18 08/24/2011
7 | // Design Name:
8 | // Module Name: q15_add
9 | // Project Name:
10 | // Target Devices:
11 | // Tool versions:
12 | // Description:
13 | //
14 | // Dependencies:
15 | //
16 | // Revision:
17 | // Revision 0.01 - File Created
18 | // Additional Comments:
19 | //
20 | //////////////////////////////////////////////////////////////////////////////////
21 | module qadd #(
22 | //Parameterized values
23 | parameter Q = 15,
24 | parameter N = 32
25 | )
26 | (
27 | input [N-1:0] a,
28 | input [N-1:0] b,
29 | output [N-1:0] c
30 | );
31 |
32 | reg [N-1:0] res;
33 |
34 | assign c = res;
35 |
36 | always @(a,b) begin
37 | // both negative or both positive
38 | if(a[N-1] == b[N-1]) begin // Since they have the same sign, absolute magnitude increases
39 | res[N-2:0] = a[N-2:0] + b[N-2:0]; // So we just add the two numbers
40 | res[N-1] = a[N-1]; // and set the sign appropriately... Doesn't matter which one we use,
41 | // they both have the same sign
42 | // Do the sign last, on the off-chance there was an overflow...
43 | end // Not doing any error checking on this...
44 | // one of them is negative...
45 | else if(a[N-1] == 0 && b[N-1] == 1) begin // subtract a-b
46 | if( a[N-2:0] > b[N-2:0] ) begin // if a is greater than b,
47 | res[N-2:0] = a[N-2:0] - b[N-2:0]; // then just subtract b from a
48 | res[N-1] = 0; // and manually set the sign to positive
49 | end
50 | else begin // if a is less than b,
51 | res[N-2:0] = b[N-2:0] - a[N-2:0]; // we'll actually subtract a from b to avoid a 2's complement answer
52 | if (res[N-2:0] == 0)
53 | res[N-1] = 0; // I don't like negative zero....
54 | else
55 | res[N-1] = 1; // and manually set the sign to negative
56 | end
57 | end
58 | else begin // subtract b-a (a negative, b positive)
59 | if( a[N-2:0] > b[N-2:0] ) begin // if a is greater than b,
60 | res[N-2:0] = a[N-2:0] - b[N-2:0]; // we'll actually subtract b from a to avoid a 2's complement answer
61 | if (res[N-2:0] == 0)
62 | res[N-1] = 0; // I don't like negative zero....
63 | else
64 | res[N-1] = 1; // and manually set the sign to negative
65 | end
66 | else begin // if a is less than b,
67 | res[N-2:0] = b[N-2:0] - a[N-2:0]; // then just subtract a from b
68 | res[N-1] = 0; // and manually set the sign to positive
69 | end
70 | end
71 | end
72 | endmodule
73 |
--------------------------------------------------------------------------------
/SimpleGPUonS7.srcs/sources_1/imports/Desktop/qmult.v:
--------------------------------------------------------------------------------
1 | `timescale 1ns / 1ps
2 | //////////////////////////////////////////////////////////////////////////////////
3 | // Company:
4 | // Engineer:
5 | //
6 | // Create Date: 11:21:14 08/24/2011
7 | // Design Name:
8 | // Module Name: q15_mult
9 | // Project Name:
10 | // Target Devices:
11 | // Tool versions:
12 | // Description:
13 | //
14 | // Dependencies:
15 | //
16 | // Revision:
17 | // Revision 0.01 - File Created
18 | // Additional Comments:
19 | //
20 | //////////////////////////////////////////////////////////////////////////////////
21 | module qmult #(
22 | //Parameterized values
23 | parameter Q = 15,
24 | parameter N = 32
25 | )
26 | (
27 | input [N-1:0] i_multiplicand,
28 | input [N-1:0] i_multiplier,
29 | output [N-1:0] o_result,
30 | output reg ovr
31 | );
32 |
33 | // The underlying assumption, here, is that both fixed-point values are of the same length (N,Q)
34 | // Because of this, the results will be of length N+N = 2N bits....
35 | // This also simplifies the hand-back of results, as the binimal point
36 | // will always be in the same location...
37 |
38 | reg [2*N-1:0] r_result; // Multiplication by 2 values of N bits requires a
39 | // register that is N+N = 2N deep...
40 | reg [N-1:0] r_RetVal;
41 |
42 | //--------------------------------------------------------------------------------
43 | assign o_result = r_RetVal; // Only handing back the same number of bits as we received...
44 | // with fixed point in same location...
45 |
46 | //---------------------------------------------------------------------------------
47 | always @(i_multiplicand, i_multiplier) begin // Do the multiply any time the inputs change
48 | r_result <= i_multiplicand[N-2:0] * i_multiplier[N-2:0]; // Removing the sign bits from the multiply - that
49 | //#100 $display("multiplying %b, and %b, %b",i_multiplicand,i_multiplier, r_result); // would introduce *big* errors
50 | ovr <= 1'b0; // reset overflow flag to zero
51 | end
52 |
53 | // This always block will throw a warning, as it uses a & b, but only acts on changes in result...
54 | always @(r_result) begin // Any time the result changes, we need to recompute the sign bit,
55 | r_RetVal[N-1] <= i_multiplicand[N-1] ^ i_multiplier[N-1]; // which is the XOR of the input sign bits... (you do the truth table...)
56 | r_RetVal[N-2:0] <= r_result[N-2+Q:Q]; // And we also need to push the proper N bits of result up to
57 | //#100 $display("multiplying %b, and %b, %b",i_multiplicand,i_multiplier, r_RetVal); // the calling entity...
58 | if (r_result[2*N-2:N-1+Q] > 0) // And finally, we need to check for an overflow
59 | ovr <= 1'b1;
60 | end
61 |
62 | endmodule
63 |
--------------------------------------------------------------------------------
/SimpleGPUonS7.srcs/sources_1/new/FiFO.v:
--------------------------------------------------------------------------------
1 | `timescale 1ns / 1ps
2 |
3 | module FIFO(clk_i, data_i, reset_i, r_en_i, w_en_i, data_o, empty_o, full_o, count_o );
4 | input clk_i;
5 | input reset_i;
6 | input [DATA_WIDTH-1:0]data_i;
7 | input r_en_i;
8 | input w_en_i;
9 |
10 | output reg [DATA_WIDTH-1:0]data_o;
11 | output empty_o;
12 | output full_o;
13 | output count_o;
14 |
15 | parameter DATA_WIDTH = 8;
16 | parameter RAM_DEPTH = 8;
17 |
18 | reg [RAM_DEPTH:0]count;
19 | reg [DATA_WIDTH-1:0]memory[RAM_DEPTH-1:0];
20 | reg [2:0]wr_pointer, rd_pointer;
21 | reg full, empty;
22 | reg [DATA_WIDTH-1:0]dataout;
23 |
24 | // reading data out from the FIFO
25 | always @( posedge clk_i or posedge reset_i)
26 | begin
27 | if( reset_i )
28 | begin
29 | dataout <= 0;
30 | //memory <= {RAM_DEPTH{DATA_WIDTH{1'b0}}};
31 | end
32 | else
33 | begin
34 | if( r_en_i && !empty_o )
35 | dataout <= memory[rd_pointer];
36 |
37 | else
38 | dataout <= dataout;
39 |
40 | end
41 | end
42 |
43 | //writing data in the FIFO
44 | always @(posedge clk_i)
45 | begin
46 | if( w_en_i && !full_o )
47 | memory[wr_pointer] <= data_i;
48 |
49 | else
50 | memory[wr_pointer] <= memory[wr_pointer];
51 | end
52 |
53 |
54 |
55 | //pointer increment system
56 | always @ (posedge clk_i or posedge reset_i)
57 | begin
58 | if(reset_i)
59 | begin
60 | //reset pointers
61 | wr_pointer <= 0;
62 | rd_pointer <= 0;
63 | end
64 | else
65 | begin
66 | //write data increment pointer
67 | if(!full_o && w_en_i)
68 | wr_pointer <= wr_pointer+1;
69 | //do nothing
70 | else
71 | wr_pointer <= wr_pointer;
72 | //read data, increment pointer
73 | if(!empty_o && r_en_i)
74 | rd_pointer <= rd_pointer+1;
75 | //do nothing
76 | else
77 | rd_pointer <= rd_pointer;
78 | end
79 | end
80 |
81 | //set states of full,empty flags
82 | always @(posedge clk_i or posedge reset_i)
83 | begin
84 | if( reset_i )
85 | count <= 0;
86 |
87 | // trying to both read and write while fifo is in good state
88 | // count stays the same. - This is valid because there is only
89 | // one clock for this fifo.
90 | else if( (!full_o && w_en_i) && ( !empty_o && r_en_i ) )
91 | count <= count;
92 | // writing not full, increment
93 | else if( !full_o && w_en_i )
94 | count <= count + 1;
95 | //reading and not empty, decrement
96 | else if( !empty_o && r_en_i )
97 | count <= count - 1;
98 | else
99 | count <= count;
100 | end
101 |
102 | //for full and empty
103 | //use blocking assigns for combinatoral logic
104 | always @(count)
105 | begin
106 | if(count==0)
107 | empty = 1 ;
108 | else
109 | empty = 0;
110 |
111 | if(count==RAM_DEPTH)
112 | full = 1;
113 | else
114 | full = 0;
115 | end
116 |
117 | endmodule
118 |
--------------------------------------------------------------------------------
/SimpleGPUonS7.srcs/sources_1/new/vgaSignalGenerator.v:
--------------------------------------------------------------------------------
1 | (* DONT_TOUCH = "yes" *)
2 | module vgaSignalGenerator(
3 | input wire i_clk, // base clock
4 | input wire i_pix_stb, // pixel clock strobe
5 | output wire o_hs, // horizontal sync
6 | output wire o_vs, // vertical sync
7 | output wire o_blanking, // high during blanking interval
8 | output wire o_active, // high during active pixel drawing
9 | output wire o_screenend, // high for one tick at the end of screen
10 | output wire o_animate, // high for one tick at end of active drawing
11 | output wire [9:0] o_x, // current pixel x position
12 | output wire [8:0] o_y // current pixel y position
13 | );
14 |
15 | // VGA timings https://timetoexplore.net/blog/video-timings-vga-720p-1080p
16 | localparam HS_STA = 16; // horizontal sync start
17 | localparam HS_END = 16 + 96; // horizontal sync end
18 | localparam HA_STA = 16 + 96 + 48; // horizontal active pixel start
19 | localparam VS_STA = 480 + 11; // vertical sync start
20 | localparam VS_END = 480 + 11 + 2; // vertical sync end
21 | localparam VA_END = 480; // vertical active pixel end
22 | localparam LINE = 800; // complete line (pixels)
23 | localparam SCREEN = 524; // complete screen (lines)
24 |
25 | reg [9:0] h_count = 0; // line position
26 | reg [9:0] v_count = 0; // screen position
27 |
28 | // generate sync signals (active low for 640x480)
29 | assign o_hs = ~((h_count >= HS_STA) & (h_count < HS_END));
30 | assign o_vs = ~((v_count >= VS_STA) & (v_count < VS_END));
31 |
32 | // keep x and y bound within the active pixels
33 | assign o_x = (h_count < HA_STA) ? 0 : (h_count - HA_STA);
34 | assign o_y = (v_count >= VA_END) ? (VA_END - 1) : (v_count);
35 |
36 | // blanking: high within the blanking period
37 | assign o_blanking = ((h_count < HA_STA) | (v_count > VA_END - 1));
38 |
39 | // active: high during active pixel drawing
40 | assign o_active = ~((h_count < HA_STA) | (v_count > VA_END - 1));
41 |
42 | // screenend: high for one tick at the end of the screen
43 | assign o_screenend = ((v_count == SCREEN - 1) & (h_count == LINE));
44 |
45 | // animate: high for one tick at the end of the final active pixel line
46 | assign o_animate = ((v_count == VA_END - 1) & (h_count == LINE));
47 |
48 | always @ (posedge i_clk)
49 | begin
50 | if (i_pix_stb) // once per pixel
51 | begin
52 | if (h_count == LINE) // end of line
53 | begin
54 | h_count <= 0;
55 | v_count <= v_count + 1;
56 | end
57 | else
58 | h_count <= h_count + 1;
59 |
60 | if (v_count == SCREEN) // end of screen
61 | begin
62 | v_count <= 0;
63 | end
64 | end
65 | end
66 | endmodule
67 |
--------------------------------------------------------------------------------
/SimpleGPUonS7.srcs/sources_1/imports/Desktop/qmults.v:
--------------------------------------------------------------------------------
1 | `timescale 1ns / 1ps
2 | //////////////////////////////////////////////////////////////////////////////////
3 | // Company:
4 | // Engineer:
5 | //
6 | // Create Date: 13:33:36 01/02/2014
7 | // Design Name:
8 | // Module Name: qmults
9 | // Project Name:
10 | // Target Devices:
11 | // Tool versions:
12 | // Description:
13 | //
14 | // Dependencies:
15 | //
16 | // Revision:
17 | // Revision 0.01 - File Created
18 | // Additional Comments:
19 | //
20 | //////////////////////////////////////////////////////////////////////////////////
21 | module qmults#(
22 | //Parameterized values
23 | parameter Q = 15,
24 | parameter N = 32
25 | )
26 | (
27 | input [N-1:0] i_multiplicand,
28 | input [N-1:0] i_multiplier,
29 | input i_start,
30 | input i_clk,
31 | output [N-1:0] o_result_out,
32 | output o_complete,
33 | output o_overflow
34 | );
35 |
36 | reg [2*N-2:0] reg_working_result; // a place to accumulate our result
37 | reg [2*N-2:0] reg_multiplier_temp; // a working copy of the multiplier
38 | reg [N-1:0] reg_multiplicand_temp; // a working copy of the umultiplicand
39 |
40 | reg [N-1:0] reg_count; // This is obviously a lot bigger than it needs to be, as we only need
41 | // count to N, but computing that number of bits requires a
42 | // logarithm (base 2), and I don't know how to do that in a
43 | // way that will work for every possibility
44 |
45 | reg reg_done; // Computation completed flag
46 | reg reg_sign; // The result's sign bit
47 | reg reg_overflow; // Overflow flag
48 |
49 | initial reg_done = 1'b1; // Initial state is to not be doing anything
50 | initial reg_overflow = 1'b0; // And there should be no woverflow present
51 | initial reg_sign = 1'b0; // And the sign should be positive
52 |
53 | assign o_result_out[N-2:0] = reg_working_result[N-2+Q:Q]; // The multiplication results
54 | assign o_result_out[N-1] = reg_sign; // The sign of the result
55 | assign o_complete = reg_done; // "Done" flag
56 | assign o_overflow = reg_overflow; // Overflow flag
57 |
58 | always @( posedge i_clk ) begin
59 | if( reg_done && i_start ) begin // This is our startup condition
60 | reg_done <= 1'b0; // We're not done
61 | reg_count <= 0; // Reset the count
62 | reg_working_result <= 0; // Clear out the result register
63 | reg_multiplier_temp <= 0; // Clear out the multiplier register
64 | reg_multiplicand_temp <= 0; // Clear out the multiplicand register
65 | reg_overflow <= 1'b0; // Clear the overflow register
66 |
67 | reg_multiplicand_temp <= i_multiplicand[N-2:0]; // Load the multiplicand in its working register and lose the sign bit
68 | reg_multiplier_temp <= i_multiplier[N-2:0]; // Load the multiplier into its working register and lose the sign bit
69 |
70 | reg_sign <= i_multiplicand[N-1] ^ i_multiplier[N-1]; // Set the sign bit
71 | end
72 |
73 | else if (!reg_done) begin
74 | if (reg_multiplicand_temp[reg_count] == 1'b1) // if the appropriate multiplicand bit is 1
75 | reg_working_result <= reg_working_result + reg_multiplier_temp; // then add the temp multiplier
76 |
77 | reg_multiplier_temp <= reg_multiplier_temp << 1; // Do a left-shift on the multiplier
78 | reg_count <= reg_count + 1; // Increment the count
79 |
80 | //stop condition
81 | if(reg_count == N) begin
82 | reg_done <= 1'b1; // If we're done, it's time to tell the calling process
83 | if (reg_working_result[2*N-2:N-1+Q] > 0) // Check for an overflow
84 | reg_overflow <= 1'b1;
85 | // else
86 | // reg_count <= reg_count + 1; // Increment the count
87 | end
88 | end
89 | end
90 | endmodule
91 |
--------------------------------------------------------------------------------
/SimpleGPUonS7.srcs/sources_1/imports/Desktop/qdiv.v:
--------------------------------------------------------------------------------
1 | `timescale 1ns / 1ps
2 | //////////////////////////////////////////////////////////////////////////////////
3 | // Company: Burke
4 | // Engineer: Tom Burke
5 | //
6 | // Create Date: 19:39:14 08/24/2011
7 | // Design Name:
8 | // Module Name: qdiv.v
9 | // Project Name: Fixed-point Math Library (Verilog)
10 | // Target Devices:
11 | // Tool versions: Xilinx ISE WebPack v14.7
12 | // Description: Fixed-point division in (Q,N) format
13 | //
14 | // Dependencies:
15 | //
16 | // Revision:
17 | // Revision 0.01 - File Created
18 | // Revision 0.02 - 25 May 2014
19 | // Updated to fix an error
20 | //
21 | // Additional Comments: Based on my description on youtube:
22 | // http://youtu.be/TEnaPMYiuR8
23 | //
24 | //////////////////////////////////////////////////////////////////////////////////
25 |
26 | module qdiv #(
27 | //Parameterized values
28 | parameter Q = 15,
29 | parameter N = 32
30 | )
31 | (
32 | input [N-1:0] i_dividend,
33 | input [N-1:0] i_divisor,
34 | input i_start,
35 | input i_clk,
36 | output [N-1:0] o_quotient_out,
37 | output o_complete,
38 | output o_overflow
39 | );
40 |
41 | reg [2*N+Q-3:0] reg_working_quotient; // Our working copy of the quotient
42 | reg [N-1:0] reg_quotient; // Final quotient
43 | reg [N-2+Q:0] reg_working_dividend; // Working copy of the dividend
44 | reg [2*N+Q-3:0] reg_working_divisor; // Working copy of the divisor
45 |
46 | reg [N-1:0] reg_count; // This is obviously a lot bigger than it needs to be, as we only need
47 | // count to N-1+Q but, computing that number of bits requires a
48 | // logarithm (base 2), and I don't know how to do that in a
49 | // way that will work for everyone
50 |
51 | reg reg_done; // Computation completed flag
52 | reg reg_sign; // The quotient's sign bit
53 | reg reg_overflow; // Overflow flag
54 |
55 | initial reg_done = 1'b1; // Initial state is to not be doing anything
56 | initial reg_overflow = 1'b0; // And there should be no woverflow present
57 | initial reg_sign = 1'b0; // And the sign should be positive
58 |
59 | initial reg_working_quotient = 0;
60 | initial reg_quotient = 0;
61 | initial reg_working_dividend = 0;
62 | initial reg_working_divisor = 0;
63 | initial reg_count = 0;
64 |
65 |
66 | assign o_quotient_out[N-2:0] = reg_quotient[N-2:0]; // The division results
67 | assign o_quotient_out[N-1] = reg_sign; // The sign of the quotient
68 | assign o_complete = reg_done;
69 | assign o_overflow = reg_overflow;
70 |
71 | always @( posedge i_clk ) begin
72 | if( reg_done && i_start ) begin // This is our startup condition
73 | // Need to check for a divide by zero right here, I think....
74 | reg_done <= 1'b0; // We're not done
75 | reg_count <= N+Q-1; // Set the count
76 | reg_working_quotient <= 0; // Clear out the quotient register
77 | reg_working_dividend <= 0; // Clear out the dividend register
78 | reg_working_divisor <= 0; // Clear out the divisor register
79 | reg_overflow <= 1'b0; // Clear the overflow register
80 |
81 | reg_working_dividend[N+Q-2:Q] <= i_dividend[N-2:0]; // Left-align the dividend in its working register
82 | reg_working_divisor[2*N+Q-3:N+Q-1] <= i_divisor[N-2:0]; // Left-align the divisor into its working register
83 |
84 | reg_sign <= i_dividend[N-1] ^ i_divisor[N-1]; // Set the sign bit
85 | end
86 | else if(!reg_done) begin
87 | reg_working_divisor <= reg_working_divisor >> 1; // Right shift the divisor (that is, divide it by two - aka reduce the divisor)
88 | reg_count <= reg_count - 1; // Decrement the count
89 |
90 | // If the dividend is greater than the divisor
91 | if(reg_working_dividend >= reg_working_divisor) begin
92 | reg_working_quotient[reg_count] <= 1'b1; // Set the quotient bit
93 | reg_working_dividend <= reg_working_dividend - reg_working_divisor; // and subtract the divisor from the dividend
94 | end
95 |
96 | //stop condition
97 | if(reg_count == 0) begin
98 | reg_done <= 1'b1; // If we're done, it's time to tell the calling process
99 | reg_quotient <= reg_working_quotient; // Move in our working copy to the outside world
100 | //#5 $display("divisionDone %b, and %b, %b",i_dividend,i_divisor, reg_working_quotient);
101 | if (reg_working_quotient[2*N+Q-3:N]>0)
102 | reg_overflow <= 1'b1;
103 | end
104 | else
105 | reg_count <= reg_count - 1;
106 | end
107 | end
108 | endmodule
--------------------------------------------------------------------------------
/SimpleGPUonS7.srcs/sources_1/new/vert_projector.v:
--------------------------------------------------------------------------------
1 | `timescale 1ns / 1ps
2 |
3 | module vert_projector(
4 | input i_clk,
5 | input in_start,
6 | input [(N*16)-1:0] mvp_in,
7 | input [(N*4)-1:0] vertex_in,
8 | output out_done,
9 | output [(N*3)-1:0] out_vector
10 | );
11 |
12 | parameter Q = 8;
13 | parameter N = 16;
14 |
15 | wire [(N*4)-1:0] result;
16 | reg in_start_1;
17 |
18 | wire x_division_done;
19 | wire y_division_done;
20 | wire z_division_done;
21 |
22 | reg inProgress = 0;
23 | reg [8:0] counter = 0;
24 | reg divide_start = 0;
25 | wire [N-1:0] xResult;
26 | wire [N-1:0] yResult;
27 | wire[N-1:0] zResult;
28 |
29 | reg out_done_reg = 0;
30 | reg [(N*3)-1:0] out_vector_reg = 0;
31 | reg internal_done = 0;
32 |
33 | wire [N-1:0] xcomp = vertex_in[(N*4)-1:(N*3)];
34 | wire [N-1:0] ycomp = vertex_in[(N*3)-1:(N*2)];
35 | wire [N-1:0] zcomp= vertex_in[(N*2)-1:(N*1)];
36 | wire [N-1:0] wcomp = vertex_in[(N*1)-1:(N*0)];
37 |
38 | assign out_done = out_done_reg;
39 | assign out_vector = out_vector_reg;
40 |
41 | localparam WAIT = 33;
42 |
43 |
44 | matrix4x4x1#(
45 | .Q(Q),
46 | .N(N)
47 | ) vertexMultipler
48 | (
49 | .mvp_in( mvp_in),
50 | .vertex_in(vertex_in),
51 | .result( result)
52 | );
53 |
54 |
55 | // we should instantiate 3 dividers -
56 | // one for each vector component.
57 | // we somehow need to wait to start dividing until the
58 | // result is valid...
59 |
60 | qdiv#(
61 | .Q(Q),
62 | .N(N))
63 | xDivider(
64 | .i_dividend(result[(N*4)-1:(N*3)]),
65 | .i_divisor(result[N-1:0]),
66 | .i_start(divide_start),
67 | .i_clk(i_clk),
68 | .o_quotient_out(xResult),
69 | .o_complete(x_division_done)
70 | );
71 |
72 | qdiv#(
73 | .Q(Q),
74 | .N(N))
75 | yDivider(
76 | .i_dividend(result[(N*3)-1:(N*2)]),
77 | .i_divisor(result[N-1:0]),
78 | .i_start(divide_start),
79 | .i_clk(i_clk),
80 | .o_quotient_out(yResult),
81 | .o_complete(y_division_done)
82 | );
83 |
84 | qdiv#(
85 | .Q(Q),
86 | .N(N))
87 | zDivider(
88 | .i_dividend(result[(N*2)-1:(N*1)]),
89 | .i_divisor(result[N-1:0]),
90 | .i_start(divide_start),
91 | .i_clk(i_clk),
92 | .o_quotient_out(zResult),
93 | .o_complete(z_division_done)
94 | );
95 |
96 |
97 | always@(posedge i_clk) begin
98 |
99 | if (inProgress == 1) begin
100 | //if we're in progress, we are not done.
101 | internal_done <= 0;
102 | //lets wait x count before starting division.
103 | counter <= counter + 1;
104 | if (counter > WAIT) begin
105 | // start dividing - then wait another 17 clocks to be safe.
106 | // or wait until the complete signal is raised.
107 | divide_start <= 1;
108 | if(z_division_done == 1 && counter > WAIT * 2) begin
109 | // we're done dividing
110 | internal_done <= 1;
111 | counter <= 0;
112 | divide_start <= 0;
113 | out_vector_reg <= {xResult,yResult,zResult};
114 | #1 $display("x %b ,y %b ,z %b" , xResult,yResult,zResult);
115 | #1 $display("x %d,%f",xResult[N-2:Q],$itor(xResult[Q:0])*2.0**-16.0);
116 | #1 $display("y %d,%f",yResult[N-2:Q],$itor(yResult[Q:0])*2.0**-16.0);
117 | #1 $display("z %d,%f",zResult[N-2:Q],$itor(zResult[Q:0])*2.0**-16.0);
118 | end // if
119 | end // if
120 | end //start if
121 | end //end always
122 |
123 | //we need N clocks before the division result is ready.
124 | always @(posedge i_clk) begin
125 | in_start_1 <= in_start;
126 | //only do anything if we detect a start pulse.
127 | if(in_start && ~in_start_1) begin
128 | #1 $display("The original vertex");
129 | #1 $display("x %b ,y %b ,z %b , w%b" , xcomp,ycomp,zcomp,wcomp);
130 | #1 $display("x %d,%f",xcomp[N-2:Q],$itor(xcomp[Q:0])*2.0**-16.0);
131 | #1 $display("y %d,%f",ycomp[N-2:Q],$itor(ycomp[Q:0])*2.0**-16.0);
132 | #1 $display("z %d,%f",zcomp[N-2:Q],$itor(zcomp[Q:0])*2.0**-16.0);
133 | #1 $display("w %d,%f",wcomp[N-2:Q],$itor(wcomp[Q:0])*2.0**-16.0);
134 |
135 | //we saw the pulse so we're now doing our work:
136 | inProgress <= 1;
137 | //reset the done flag.
138 | out_done_reg <= 0;
139 | end
140 | if(internal_done == 1) begin
141 | inProgress <= 0;
142 | out_done_reg =1;
143 | end
144 | end // always
145 |
146 | endmodule
147 |
--------------------------------------------------------------------------------
/SimpleGPUonS7.srcs/sources_1/new/matrix4x4x1.v:
--------------------------------------------------------------------------------
1 | `timescale 1ns / 1ps
2 | //////////////////////////////////////////////////////////////////////////////////
3 | // Company:
4 | // Engineer:
5 | //
6 | // Create Date: 12/16/2018 12:29:25 PM
7 | // Design Name:
8 | // Module Name: matrix4x4x1
9 | // Project Name:
10 | // Target Devices:
11 | // Tool Versions:
12 | // Description:
13 | //
14 | // Dependencies:
15 | //
16 | // Revision:
17 | // Revision 0.01 - File Created
18 | // Additional Comments:
19 | //
20 | //////////////////////////////////////////////////////////////////////////////////
21 |
22 |
23 | module matrix4x4x1(
24 | input [(N*16)-1:0] mvp_in,
25 | input [(N*4)-1:0] vertex_in,
26 | output [(N*4)-1:0] result
27 | );
28 |
29 | parameter Q = 8;
30 | parameter N = 16;
31 |
32 | //internal variables
33 | reg [N-1:0] mvp_inTemp[0:3][0:3];
34 | reg [N-1:0] vertex_inTemp[0:3];
35 | wire [N-1:0] res_TempOut [0:3];
36 | wire [N-1:0] res_TempIntermediate [0:7];
37 |
38 | reg [(N*4)-1:0] out_reg_result = 0;
39 |
40 | wire [N-1:0] tempx1;
41 | wire [N-1:0] tempx2;
42 | wire [N-1:0] tempx3;
43 | wire [N-1:0] tempx4;
44 |
45 | wire [N-1:0] tempy1;
46 | wire [N-1:0] tempy2;
47 | wire [N-1:0] tempy3;
48 | wire [N-1:0] tempy4;
49 |
50 | wire [N-1:0] tempz1;
51 | wire [N-1:0] tempz2;
52 | wire [N-1:0] tempz3;
53 | wire [N-1:0] tempz4;
54 |
55 | wire [N-1:0] tempw1;
56 | wire [N-1:0] tempw2;
57 | wire [N-1:0] tempw3;
58 | wire [N-1:0] tempw4;
59 |
60 | integer i,j = 0;
61 |
62 |
63 | assign result = out_reg_result;
64 |
65 | //TODO I think matrix[row][col] is correct.
66 |
67 | //calculate x component of result vector
68 | qmult #(
69 | .Q(Q),
70 | .N(N)) mult1x(mvp_inTemp[0][0],vertex_inTemp[0],tempx1);
71 |
72 | qmult #(
73 | .Q(Q),
74 | .N(N)) mult12x(mvp_inTemp[0][1],vertex_inTemp[1],tempx2);
75 |
76 | qadd #(
77 | .Q(Q),
78 | .N(N)) add2x(tempx2,tempx1,res_TempIntermediate[0]);
79 |
80 | qmult #(
81 | .Q(Q),
82 | .N(N)) mult3x(mvp_inTemp[0][2],vertex_inTemp[2],tempx3);
83 |
84 | qadd #(
85 | .Q(Q),
86 | .N(N)) add3x(res_TempIntermediate[0],tempx3,res_TempIntermediate[1]);
87 |
88 | qmult #(
89 | .Q(Q),
90 | .N(N)) mult4x(mvp_inTemp[0][3],vertex_inTemp[3],tempx4);
91 |
92 | qadd #(
93 | .Q(Q),
94 | .N(N)) add4x(res_TempIntermediate[1],tempx4,res_TempOut[0]);
95 |
96 |
97 | //calculate y component of result vector
98 | qmult #(
99 | .Q(Q),
100 | .N(N)) mult1y(mvp_inTemp[1][0],vertex_inTemp[0],tempy1);
101 |
102 | qmult #(
103 | .Q(Q),
104 | .N(N)) mult12y(mvp_inTemp[1][1],vertex_inTemp[1],tempy2);
105 |
106 | qadd #(
107 | .Q(Q),
108 | .N(N)) add2y(tempy2,tempy1,res_TempIntermediate[2]);
109 |
110 | qmult #(
111 | .Q(Q),
112 | .N(N)) mult3y(mvp_inTemp[1][2],vertex_inTemp[2],tempy3);
113 |
114 | qadd #(
115 | .Q(Q),
116 | .N(N)) add3y(res_TempIntermediate[2],tempy3,res_TempIntermediate[3]);
117 |
118 | qmult #(
119 | .Q(Q),
120 | .N(N)) mult4y(mvp_inTemp[1][3],vertex_inTemp[3],tempy4);
121 |
122 | qadd #(
123 | .Q(Q),
124 | .N(N)) add4y(res_TempIntermediate[3],tempy4,res_TempOut[1]);
125 |
126 |
127 | //calculate z component of result vector
128 | qmult #(
129 | .Q(Q),
130 | .N(N)) mult1z(mvp_inTemp[2][0],vertex_inTemp[0],tempz1);
131 |
132 | qmult #(
133 | .Q(Q),
134 | .N(N)) mult12z(mvp_inTemp[2][1],vertex_inTemp[1],tempz2);
135 |
136 | qadd #(
137 | .Q(Q),
138 | .N(N)) add2z(tempz2,tempz1,res_TempIntermediate[4]);
139 |
140 | qmult #(
141 | .Q(Q),
142 | .N(N)) mult3z(mvp_inTemp[2][2],vertex_inTemp[2],tempz3);
143 |
144 | qadd #(
145 | .Q(Q),
146 | .N(N)) add3z(res_TempIntermediate[4],tempz3,res_TempIntermediate[5]);
147 |
148 | qmult #(
149 | .Q(Q),
150 | .N(N)) mult4z(mvp_inTemp[2][3],vertex_inTemp[3],tempz4);
151 |
152 | qadd #(
153 | .Q(Q),
154 | .N(N)) add4z(res_TempIntermediate[5],tempz4,res_TempOut[2]);
155 |
156 |
157 | //calculate w component of result vector
158 | qmult #(
159 | .Q(Q),
160 | .N(N)) mult1w(mvp_inTemp[3][0],vertex_inTemp[0],tempw1);
161 |
162 | qmult #(
163 | .Q(Q),
164 | .N(N)) mult12w(mvp_inTemp[3][1],vertex_inTemp[1],tempw2);
165 |
166 | qadd #(
167 | .Q(Q),
168 | .N(N)) add2w(tempw2,tempw1,res_TempIntermediate[6]);
169 |
170 | qmult #(
171 | .Q(Q),
172 | .N(N)) mult3w(mvp_inTemp[3][2],vertex_inTemp[2],tempw3);
173 |
174 | qadd #(
175 | .Q(Q),
176 | .N(N)) add3w(res_TempIntermediate[6],tempw3,res_TempIntermediate[7]);
177 |
178 | qmult #(
179 | .Q(Q),
180 | .N(N)) mult4w(mvp_inTemp[3][3],vertex_inTemp[3],tempw4);
181 |
182 | qadd #(
183 | .Q(Q),
184 | .N(N)) add4w(res_TempIntermediate[7],tempw4,res_TempOut[3]);
185 |
186 |
187 |
188 |
189 | always@(mvp_in,vertex_in,res_TempOut) begin
190 | //convert 1d to 3d
191 | //TODO consider row v col.
192 |
193 | //(matrix[row][col]
194 | { mvp_inTemp[0][0],mvp_inTemp[0][1],mvp_inTemp[0][2],mvp_inTemp[0][3],
195 | mvp_inTemp[1][0],mvp_inTemp[1][1],mvp_inTemp[1][2],mvp_inTemp[1][3],
196 | mvp_inTemp[2][0],mvp_inTemp[2][1],mvp_inTemp[2][2],mvp_inTemp[2][3],
197 | mvp_inTemp[3][0],mvp_inTemp[3][1],mvp_inTemp[3][2],mvp_inTemp[3][3] } = mvp_in;
198 |
199 | {vertex_inTemp[0],vertex_inTemp[1],vertex_inTemp[2],vertex_inTemp[3]} = vertex_in;
200 |
201 |
202 |
203 |
204 | //TODO(could use a generate loop)
205 | //makes assumption i iterates column, j iterates rows
206 | // for(i = 0; i<4; i= i + 1)
207 | // for(j=0;j <4; j = j +1)
208 | ///
209 | //
210 | //
211 | // res_Temp[i] = res_Temp[i] + mvp_inTemp[i][j] * vertex_inTemp[j];
212 |
213 | //flatten result back to 1d vector (4 * 16 bits)
214 | out_reg_result = {res_TempOut[0],res_TempOut[1],res_TempOut[2],res_TempOut[3]};
215 | end
216 |
217 |
218 | endmodule
219 |
--------------------------------------------------------------------------------
/SimpleGPUonS7.srcs/sources_1/new/top.v:
--------------------------------------------------------------------------------
1 | `timescale 1ns / 1ps
2 |
3 | module top(
4 |
5 | input [2:0] MODE_I, //(000) = vertexWriteMode
6 | input CLK100MHZ,
7 | input WRITE_IN,
8 | input MOSI,SERIALCLOCK,ENABLE,
9 |
10 | output VGA_HS_O,
11 | output VGA_VS_O,
12 | output VGA_R,
13 | output VGA_G,
14 | output VGA_B,
15 | output led,
16 | output VALIDWORD,
17 | output READVERTEX,
18 | output WRITEVERTEX,
19 | output CLOCK25,
20 | output FULL,
21 | output [4:0] COUNTER
22 | );
23 |
24 | wire i_clk = CLK100MHZ;
25 |
26 | reg we_ = 1;
27 |
28 | reg [13:0] romAddressLines = 0;
29 |
30 | reg [Nbit-1:0] romDataLines = 0;
31 |
32 | wire [Nbit-1:0] vertDataOut;
33 | //single buffer xyz
34 | reg [(Nbit*3)-1:0] vertexBuffer = 0;
35 | reg[(Nbit*4)-1:0] vertex = 0;
36 |
37 | //TODO - maybe remove after vert data comes from external source
38 | reg [32:0] iterationCounter = 0;
39 | reg [15:0] vertCounter = 0;
40 | reg [8:0] stateCounter = 0;
41 |
42 | reg vertexReady = 0;
43 | //TODO this will be ready when matrix buffer is full.
44 | reg matrixReady = 1;
45 |
46 | //projection regs
47 | reg startProjection = 0;
48 | //16 x 16 matrix
49 | reg [(Nbit*16)-1:0] mvp_in = 512'b00000000000000001011010100000100000000000000000000000000000000001000000000000000101101010000010000000000000000000000000000000000100000000000000010001011010110010000000000000001000101101011001010000000000000001000101101011001000000000000000000000000000000001000000000000000101110001100000010000000000000001011100011000000100000000000000010111000110000000000000000001000010100110100100010000000000000001001001111001101100000000000000010010011110011011000000000000000100100111100110100000000000010001010100100000110;
50 | wire [(Nbit*3)-1:0] projected_vector;
51 | wire projection_done;
52 |
53 | //viewToScreen regs
54 | localparam SCREEN_WIDTH = 640;
55 | localparam Qbit = 16;
56 | localparam Nbit = 32;
57 | reg [11:0 ]width = 640;
58 | reg [11:0 ]height = 480;
59 |
60 | wire [11:0] xpixel;
61 | wire [11:0] ypixel;
62 | wire pixelOnScreen;
63 |
64 | //framebuffer regs
65 | reg [18:0] frameBufferAddressLines1 = 0;
66 | reg [18:0] frameBufferAddressLines2 = 0;
67 | reg frameBufferData = 1;
68 | reg frameBuffer_we_ = 1;
69 | wire frameBufferDataOut1;
70 | wire frameBufferDataOut2;
71 |
72 | //memory address regs
73 | reg [19:0] memoryAddress = 0;
74 |
75 | //vga data
76 | wire hs;
77 | wire vs;
78 | wire [9:0] xvga;
79 | wire [8:0] yvga;
80 | reg [15:0] cnt = 0;
81 | reg pix_stb = 0;
82 | assign CLOCK25 = cnt[15];
83 |
84 | reg outputColorReg = 0;
85 |
86 | //fifo data
87 | wire reset_fifos;
88 | reg readVertexFromFifo = 0;
89 | reg writeVertexToFifo = 0;
90 | wire empty;
91 | wire full;
92 |
93 | assign reset_fifos = 0;
94 |
95 |
96 | //spi data
97 | wire [Nbit-1:0] serialData;
98 | wire validSerialData;
99 | assign led = validSerialData;
100 | assign VALIDWORD = validSerialData;
101 |
102 |
103 |
104 | //DEBUG
105 |
106 | assign READVERTEX = readVertexFromFifo;
107 | assign WRITEVERTEX = writeVertexToFifo;
108 | assign FULL = full;
109 |
110 |
111 |
112 |
113 | always@(posedge CLK100MHZ) begin
114 | if(pix_stb) begin
115 | if(MODE_I == 3'b000 && validSerialData) begin
116 | writeVertexToFifo <= 1;
117 | end
118 | else begin
119 | writeVertexToFifo <= 0;
120 | end
121 | end
122 | end
123 |
124 |
125 | wire [7:0] debugCounter;
126 |
127 | SPI_slave#(.n(Nbit))
128 | serialInput (.i_base_clock(cnt[15]),
129 | .i_SCK(SERIALCLOCK),
130 | .i_MOSI(MOSI),
131 | .i_EN(ENABLE),
132 | .o_WORDVALID(validSerialData),
133 | .o_DATA(serialData),
134 | .o_COUNTER(debugCounter)
135 | );
136 |
137 | assign COUNTER = debugCounter[4:0];
138 |
139 | //FIFO for reading vertex data from external source
140 | FIFO#(.DATA_WIDTH(Nbit),.RAM_DEPTH(3))
141 |
142 | vertexFifo (.clk_i(cnt[15]),
143 | .reset_i(reset_fifos),
144 | .data_i(serialData),
145 | .r_en_i(readVertexFromFifo),
146 | .w_en_i(writeVertexToFifo),
147 | .data_o(vertDataOut),
148 | .empty_o(empty),
149 | .full_o(full));
150 |
151 | dualPortStaticRam #(.ROMFILE("framebuffer.mem"),.DATA_WIDTH(1),.ADDR_WIDTH(19)) frameBuffer (
152 | .address_1(frameBufferAddressLines1),
153 | .address_2(frameBufferAddressLines2),
154 | .data(frameBufferData),
155 | .we_(frameBuffer_we_),
156 | .clock(i_clk),
157 | .clock2(i_clk),
158 | .Q_1(frameBufferDataOut1),
159 | .Q_2(frameBufferDataOut2));
160 |
161 |
162 |
163 | vert_projector #(.Q(Qbit),.N(Nbit))
164 | projector(.i_clk(i_clk),
165 | .in_start(startProjection),
166 | .mvp_in( mvp_in),
167 | .vertex_in(vertex),
168 | .out_vector( projected_vector),
169 | .out_done(projection_done)
170 | );
171 |
172 | ViewToScreenConverter#(.Q(Qbit),.N(Nbit))
173 | viewToScreen(.width_in(width),
174 | .height_in(height),
175 | .vector_in(projected_vector),
176 | .xpix_out(xpixel),
177 | .ypix_out(ypixel),
178 | .on_screen_out(pixelOnScreen));
179 |
180 | vgaSignalGenerator vgaPart (
181 | .i_clk(i_clk),
182 | .i_pix_stb(pix_stb),
183 | .o_hs(hs),
184 | .o_vs(vs),
185 | .o_x(xvga),
186 | .o_y(yvga)
187 | );
188 |
189 | assign VGA_HS_O = hs;
190 | assign VGA_VS_O = vs;
191 | assign VGA_R = outputColorReg;
192 | assign VGA_G = outputColorReg;
193 | assign VGA_B = outputColorReg;
194 |
195 |
196 | //on each clock - increment the counter and grab more data from ram.
197 | //TODO a state machine would work well for this...
198 | always@(posedge i_clk) begin
199 |
200 | {pix_stb, cnt} <= cnt + 16'h4000; // divide by 4: (2^16)/4 = 0x4000
201 | iterationCounter <= iterationCounter + 1;
202 | frameBufferAddressLines2 <= (yvga * SCREEN_WIDTH) + xvga;
203 | outputColorReg <= frameBufferDataOut2;
204 |
205 |
206 | //~3mhz
207 | if(pix_stb) begin
208 |
209 | // Based on MODE - jump to various states...
210 | //mode control
211 | /// 000_ vertex write
212 | /// 001
213 | /// 010
214 | /// 011_blank frame buffer
215 |
216 | // if mode is set to write vertex, and we're outside of write vertex states
217 | // then start write vertex flow over from 0.
218 | if(MODE_I == 3'b000 && stateCounter >= 200 ) begin
219 | stateCounter <= 0;
220 | end
221 |
222 | if(MODE_I == 3'b011) begin
223 | // jump to state 200 - where we will blank the framebuffer
224 | // by incrementing address and writing over and over.
225 | // until we leave this mode.
226 | stateCounter <= 200;
227 | end
228 |
229 |
230 | // wait until the FIFO is full, (3) numbers-
231 | // then grab all three, do the projection
232 | // then return to a waiting state.
233 |
234 | //wait for FIFO state
235 | if(stateCounter == 0) begin
236 | //reset some values for writing pixels
237 | frameBufferData <= 1;
238 | frameBuffer_we_ <= 1;
239 |
240 | if(full == 1) begin
241 | stateCounter <= 1;
242 | end
243 |
244 | end
245 |
246 | // start read from FIFO state
247 | if(stateCounter == 1) begin
248 | readVertexFromFifo <= 1;
249 | stateCounter <= 2;
250 | end
251 | //build up the vertex buffer
252 | //GET X
253 | if(stateCounter == 2) begin
254 | //save data from FIFO shifted into the buffer.
255 | vertexBuffer <= {vertexBuffer[(Nbit*2)-1:0],vertDataOut};
256 | stateCounter <= stateCounter + 1;
257 | end
258 |
259 | //GET Y
260 | if(stateCounter == 3) begin
261 | //save data from ram shifted into the buffer.
262 | vertexBuffer <= {vertexBuffer[(Nbit*2)-1:0],vertDataOut};
263 | stateCounter <= stateCounter + 1;
264 | end
265 |
266 | //GET Z
267 | if(stateCounter == 4) begin
268 | //save data from ram shifted into the buffer.
269 | vertexBuffer <= {vertexBuffer[(Nbit*2)-1:0],vertDataOut};
270 | readVertexFromFifo <= 0;
271 | stateCounter <= stateCounter + 1;
272 | end
273 |
274 | if(stateCounter == 5) begin
275 | stateCounter <= stateCounter + 1;
276 | end
277 |
278 | // append W - and set the states.
279 | if (stateCounter == 6) begin
280 | vertCounter <= vertCounter + 1;
281 | vertex <= {vertexBuffer,{Qbit-1{1'b0}},1'b1,{Qbit{1'b0}}};
282 | vertexReady <= 1;
283 | stateCounter <= 7;
284 | end
285 |
286 | // in state 4 - we are done buffering and are starting to project.
287 | if(stateCounter ==7 && vertexReady ==1 && matrixReady == 1) begin
288 | startProjection <= 1;
289 | stateCounter <= 8;
290 | end
291 |
292 | // projection just finished, reset some state and
293 | // draw the vertex.
294 | if(stateCounter >7 && stateCounter <100 && projection_done == 1) begin
295 | //lets wait here for another 15 cycles
296 | //TODO make this more easily adjustable.
297 | stateCounter <= stateCounter+1;
298 | end
299 |
300 | //TODO lets assume pixel calculations are done
301 | //so now map to memory and write to the framebuffer.
302 | //
303 | if(stateCounter == 100) begin
304 | #5 $display("vertexcount %d, should display at coord x %d, y %d ",vertCounter,xpixel,ypixel );
305 | memoryAddress <= xpixel + (ypixel * SCREEN_WIDTH);
306 | frameBufferAddressLines1 <= memoryAddress;
307 | stateCounter <= 101;
308 | end
309 |
310 | // actually write a one into memory if the pixel is
311 | // visible - else give do nothing.
312 | if(stateCounter == 101) begin
313 | //assert the write bit for a clock.
314 | if(pixelOnScreen ==1) begin
315 | frameBuffer_we_ = 0;
316 | end
317 | stateCounter <= 102;
318 |
319 | end
320 |
321 | //we're done - reset all state
322 | if(stateCounter == 102) begin
323 | frameBuffer_we_ <= 1;
324 | stateCounter <= 0;
325 | vertexReady <= 0;
326 | startProjection <= 0;
327 |
328 | end
329 |
330 | if(stateCounter == 200) begin
331 | //should not be projecting during screen blank.
332 | vertexReady <= 0;
333 | startProjection <= 0;
334 |
335 | //we want to write black pixels
336 | frameBufferData <= 0;
337 | // this will overflow and loop.
338 | memoryAddress <= memoryAddress +1;
339 | frameBufferAddressLines1 <= memoryAddress;
340 | //write 0 to framebuffer
341 | frameBuffer_we_ <= 0;
342 |
343 | end
344 |
345 | end
346 | end
347 |
348 | endmodule
349 |
--------------------------------------------------------------------------------
/SimpleGPUonS7.xpr:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
114 |
115 |
116 |
117 |
118 |
119 |
120 |
121 |
122 |
123 |
124 |
125 |
126 |
127 |
128 |
129 |
130 |
131 |
132 |
133 |
134 |
135 |
136 |
137 |
138 |
139 |
140 |
141 |
142 |
143 |
144 |
145 |
146 |
147 |
148 |
149 |
150 |
151 |
152 |
153 |
154 |
155 |
156 |
157 |
158 |
159 |
160 |
161 |
162 |
163 |
164 |
165 |
166 |
167 |
168 |
169 |
170 |
171 |
172 |
173 |
174 |
175 |
176 |
177 |
178 |
179 |
180 |
181 |
182 |
183 |
184 |
185 |
186 |
187 |
188 |
189 |
190 |
191 |
192 |
193 |
194 |
195 |
196 |
197 |
198 |
199 |
200 |
201 |
202 |
203 |
204 |
205 |
206 |
207 |
208 |
209 |
210 |
211 |
212 |
213 |
214 |
215 |
216 |
217 |
218 |
219 |
220 |
221 |
222 |
223 |
224 |
225 |
226 |
227 |
228 |
229 |
230 |
231 |
232 |
233 |
234 |
235 |
236 |
237 |
238 |
239 |
240 |
241 |
242 |
243 |
244 |
245 |
246 |
247 |
248 |
249 |
250 |
251 |
252 |
253 |
254 |
255 |
256 |
257 |
258 |
259 |
260 |
261 |
262 |
263 |
264 |
265 |
266 |
267 |
268 |
269 |
270 |
271 |
272 |
273 |
274 |
275 |
276 |
277 |
278 |
279 |
280 |
281 |
282 |
283 |
284 |
285 |
286 |
287 |
288 |
289 |
290 |
291 |
292 |
293 |
294 |
295 |
296 |
297 |
298 |
299 |
300 |
301 |
302 |
303 |
304 |
305 |
306 |
307 |
308 |
309 |
310 |
311 |
312 |
313 |
314 |
315 |
316 |
317 |
318 |
319 |
320 |
321 |
322 |
323 |
324 |
--------------------------------------------------------------------------------
/SimpleGPUonS7.srcs/constrs_1/new/s7.xdc:
--------------------------------------------------------------------------------
1 | ## This file is a general .xdc for the Arty S7-50 Rev. E
2 | ## To use it in a project:
3 | ## - uncomment the lines corresponding to used pins
4 | ## - rename the used ports (in each line, after get_ports) according to the top level signal names in the project
5 |
6 | ## Clock Signals
7 | #set_property -dict { PACKAGE_PIN F14 IOSTANDARD LVCMOS33 } [get_ports { CLK12MHZ }]; #IO_L13P_T2_MRCC_15 Sch=uclk
8 | #create_clock -add -name sys_clk_pin -period 83.333 -waveform {0 41.667} [get_ports { CLK12MHZ }];
9 | set_property -dict { PACKAGE_PIN R2 IOSTANDARD SSTL135 } [get_ports { CLK100MHZ }]; #IO_L12P_T1_MRCC_34 Sch=ddr3_clk[200]
10 | create_clock -add -name sys_clk_pin -period 10.000 -waveform {0 5.000} [get_ports { CLK100MHZ }];
11 |
12 | ## Switches
13 | #set_property -dict { PACKAGE_PIN H14 IOSTANDARD LVCMOS33 } [get_ports { sw[0] }]; #IO_L20N_T3_A19_15 Sch=sw[0]
14 | #set_property -dict { PACKAGE_PIN H18 IOSTANDARD LVCMOS33 } [get_ports { sw[1] }]; #IO_L21P_T3_DQS_15 Sch=sw[1]
15 | #set_property -dict { PACKAGE_PIN G18 IOSTANDARD LVCMOS33 } [get_ports { sw[2] }]; #IO_L21N_T3_DQS_A18_15 Sch=sw[2]
16 | #set_property -dict { PACKAGE_PIN M5 IOSTANDARD SSTL135 } [get_ports { sw[3] }]; #IO_L6N_T0_VREF_34 Sch=sw[3]
17 |
18 | ## RGB LEDs
19 | #set_property -dict { PACKAGE_PIN J15 IOSTANDARD LVCMOS33 } [get_ports { led0_r }]; #IO_L23N_T3_FWE_B_15 Sch=led0_r
20 | #set_property -dict { PACKAGE_PIN G17 IOSTANDARD LVCMOS33 } [get_ports { led0_g }]; #IO_L14N_T2_SRCC_15 Sch=led0_g
21 | #set_property -dict { PACKAGE_PIN F15 IOSTANDARD LVCMOS33 } [get_ports { led0_b }]; #IO_L13N_T2_MRCC_15 Sch=led0_b
22 | #set_property -dict { PACKAGE_PIN E15 IOSTANDARD LVCMOS33 } [get_ports { led1_r }]; #IO_L15N_T2_DQS_ADV_B_15 Sch=led1_r
23 | #set_property -dict { PACKAGE_PIN F18 IOSTANDARD LVCMOS33 } [get_ports { led1_g }]; #IO_L16P_T2_A28_15 Sch=led1_g
24 | #set_property -dict { PACKAGE_PIN E14 IOSTANDARD LVCMOS33 } [get_ports { led1_b }]; #IO_L15P_T2_DQS_15 Sch=led1_b
25 |
26 | ## LEDs
27 | set_property -dict { PACKAGE_PIN E18 IOSTANDARD LVCMOS33 } [get_ports { led }]; #IO_L16N_T2_A27_15 Sch=led[2]
28 | #set_property -dict { PACKAGE_PIN F13 IOSTANDARD LVCMOS33 } [get_ports { led[1] }]; #IO_L17P_T2_A26_15 Sch=led[3]
29 | #set_property -dict { PACKAGE_PIN E13 IOSTANDARD LVCMOS33 } [get_ports { led[2] }]; #IO_L17N_T2_A25_15 Sch=led[4]
30 | #set_property -dict { PACKAGE_PIN H15 IOSTANDARD LVCMOS33 } [get_ports { led[3] }]; #IO_L18P_T2_A24_15 Sch=led[5]
31 |
32 | ## Buttons
33 | #set_property -dict { PACKAGE_PIN G15 IOSTANDARD LVCMOS33 } [get_ports { btn[0] }]; #IO_L18N_T2_A23_15 Sch=btn[0]
34 | #set_property -dict { PACKAGE_PIN K16 IOSTANDARD LVCMOS33 } [get_ports { btn[1] }]; #IO_L19P_T3_A22_15 Sch=btn[1]
35 | #set_property -dict { PACKAGE_PIN J16 IOSTANDARD LVCMOS33 } [get_ports { btn[2] }]; #IO_L19N_T3_A21_VREF_15 Sch=btn[2]
36 | #set_property -dict { PACKAGE_PIN H13 IOSTANDARD LVCMOS33 } [get_ports { btn[3] }]; #IO_L20P_T3_A20_15 Sch=btn[3]
37 |
38 | ## Pmod Header JA
39 | set_property -dict { PACKAGE_PIN L17 IOSTANDARD LVCMOS33 } [get_ports { COUNTER[0] }]; #IO_L4P_T0_D04_14 Sch=ja_p[1]
40 | set_property -dict { PACKAGE_PIN L18 IOSTANDARD LVCMOS33 } [get_ports { COUNTER[1] }]; #IO_L4N_T0_D05_14 Sch=ja_n[1]
41 | set_property -dict { PACKAGE_PIN M14 IOSTANDARD LVCMOS33 } [get_ports { COUNTER[2] }]; #IO_L5P_T0_D06_14 Sch=ja_p[2]
42 | set_property -dict { PACKAGE_PIN N14 IOSTANDARD LVCMOS33 } [get_ports { COUNTER[3] }]; #IO_L5N_T0_D07_14 Sch=ja_n[2]
43 | set_property -dict { PACKAGE_PIN M16 IOSTANDARD LVCMOS33 } [get_ports { COUNTER[4] }]; #IO_L7P_T1_D09_14 Sch=ja_p[3]
44 | #set_property -dict { PACKAGE_PIN M17 IOSTANDARD LVCMOS33 } [get_ports { INPUTDATA[5] }]; #IO_L7N_T1_D10_14 Sch=ja_n[3]
45 | #set_property -dict { PACKAGE_PIN M18 IOSTANDARD LVCMOS33 } [get_ports { INPUTDATA[6] }]; #IO_L8P_T1_D11_14 Sch=ja_p[4]
46 | #set_property -dict { PACKAGE_PIN N18 IOSTANDARD LVCMOS33 } [get_ports { INPUTDATA[7] }]; #IO_L8N_T1_D12_14 Sch=ja_n[4]
47 |
48 | ## Pmod Header JB
49 | #set_property -dict { PACKAGE_PIN P17 IOSTANDARD LVCMOS33 } [get_ports { INPUTDATA[8] }]; #IO_L9P_T1_DQS_14 Sch=jb_p[1]
50 | #set_property -dict { PACKAGE_PIN P18 IOSTANDARD LVCMOS33 } [get_ports { INPUTDATA[9] }]; #IO_L9N_T1_DQS_D13_14 Sch=jb_n[1]
51 | #set_property -dict { PACKAGE_PIN R18 IOSTANDARD LVCMOS33 } [get_ports { INPUTDATA[10] }]; #IO_L10P_T1_D14_14 Sch=jb_p[2]
52 | #set_property -dict { PACKAGE_PIN T18 IOSTANDARD LVCMOS33 } [get_ports { INPUTDATA[11] }]; #IO_L10N_T1_D15_14 Sch=jb_n[2]
53 | #set_property -dict { PACKAGE_PIN P14 IOSTANDARD LVCMOS33 } [get_ports { INPUTDATA[12] }]; #IO_L11P_T1_SRCC_14 Sch=jb_p[3]
54 | #set_property -dict { PACKAGE_PIN P15 IOSTANDARD LVCMOS33 } [get_ports { INPUTDATA[13] }]; #IO_L11N_T1_SRCC_14 Sch=jb_n[3]
55 | #set_property -dict { PACKAGE_PIN N15 IOSTANDARD LVCMOS33 } [get_ports { INPUTDATA[14] }]; #IO_L12P_T1_MRCC_14 Sch=jb_p[4]
56 | #set_property -dict { PACKAGE_PIN P16 IOSTANDARD LVCMOS33 } [get_ports { INPUTDATA[15] }]; #IO_L12N_T1_MRCC_14 Sch=jb_n[4]
57 |
58 | ## Pmod Header JC
59 | #set_property -dict { PACKAGE_PIN U15 IOSTANDARD LVCMOS33 } [get_ports { INPUTDATA[16] }]; #IO_L18P_T2_A12_D28_14 Sch=jc1/ck_io[41]
60 | #set_property -dict { PACKAGE_PIN V16 IOSTANDARD LVCMOS33 } [get_ports { INPUTDATA[17] }]; #IO_L18N_T2_A11_D27_14 Sch=jc2/ck_io[40]
61 | #set_property -dict { PACKAGE_PIN U17 IOSTANDARD LVCMOS33 } [get_ports { INPUTDATA[18] }]; #IO_L15P_T2_DQS_RDWR_B_14 Sch=jc3/ck_io[39]
62 | #set_property -dict { PACKAGE_PIN U18 IOSTANDARD LVCMOS33 } [get_ports { INPUTDATA[19] }]; #IO_L15N_T2_DQS_DOUT_CSO_B_14 Sch=jc4/ck_io[38]
63 | #set_property -dict { PACKAGE_PIN U16 IOSTANDARD LVCMOS33 } [get_ports { INPUTDATA[20] }]; #IO_L16P_T2_CSI_B_14 Sch=jc7/ck_io[37]
64 | #set_property -dict { PACKAGE_PIN P13 IOSTANDARD LVCMOS33 } [get_ports { INPUTDATA[21] }]; #IO_L19P_T3_A10_D26_14 Sch=jc8/ck_io[36]
65 | #set_property -dict { PACKAGE_PIN R13 IOSTANDARD LVCMOS33 } [get_ports { INPUTDATA[22] }]; #IO_L19N_T3_A09_D25_VREF_14 Sch=jc9/ck_io[35]
66 | #set_property -dict { PACKAGE_PIN V14 IOSTANDARD LVCMOS33 } [get_ports { INPUTDATA[23] }]; #IO_L20P_T3_A08_D24_14 Sch=jc10/ck_io[34]
67 |
68 | ## Pmod Header JD
69 | set_property -dict { PACKAGE_PIN V15 IOSTANDARD LVCMOS33 } [get_ports { ENABLE }]; #IO_L20N_T3_A07_D23_14 Sch=jd1/ck_io[33]
70 | set_property -dict { PACKAGE_PIN U12 IOSTANDARD LVCMOS33 } [get_ports { SERIALCLOCK }]; #IO_L21P_T3_DQS_14 Sch=jd2/ck_io[32]
71 | set_property -dict { PACKAGE_PIN V13 IOSTANDARD LVCMOS33 } [get_ports { MOSI }]; #IO_L21N_T3_DQS_A06_D22_14 Sch=jd3/ck_io[31]
72 | set_property -dict { PACKAGE_PIN T12 IOSTANDARD LVCMOS33 } [get_ports { WRITE_IN }]; #IO_L22P_T3_A05_D21_14 Sch=jd4/ck_io[30]
73 | set_property -dict { PACKAGE_PIN T13 IOSTANDARD LVCMOS33 } [get_ports { MODE_I[2] }]; #IO_L22N_T3_A04_D20_14 Sch=jd7/ck_io[29]
74 | set_property -dict { PACKAGE_PIN R11 IOSTANDARD LVCMOS33 } [get_ports { MODE_I[1] }]; #IO_L23P_T3_A03_D19_14 Sch=jd8/ck_io[28]
75 | set_property -dict { PACKAGE_PIN T11 IOSTANDARD LVCMOS33 } [get_ports { MODE_I[0] }]; #IO_L23N_T3_A02_D18_14 Sch=jd9/ck_io[27]
76 | #set_property -dict { PACKAGE_PIN U11 IOSTANDARD LVCMOS33 } [get_ports { }]; #IO_L24P_T3_A01_D17_14 Sch=jd10/ck_io[26]
77 |
78 | ## USB-UART Interface
79 | #set_property -dict { PACKAGE_PIN R12 IOSTANDARD LVCMOS33 } [get_ports { uart_rxd_out }]; #IO_25_14 Sch=uart_rxd_out
80 | #set_property -dict { PACKAGE_PIN V12 IOSTANDARD LVCMOS33 } [get_ports { uart_txd_in }]; #IO_L24N_T3_A00_D16_14 Sch=uart_txd_in
81 |
82 | ## ChipKit Outer Digital Header
83 | set_property -dict { PACKAGE_PIN L13 IOSTANDARD LVCMOS33 } [get_ports { VGA_HS_O }]; #IO_0_14 Sch=ck_io[0]
84 | set_property -dict { PACKAGE_PIN N13 IOSTANDARD LVCMOS33 } [get_ports { VGA_VS_O }]; #IO_L6N_T0_D08_VREF_14 Sch=ck_io[1]
85 | set_property -dict { PACKAGE_PIN L16 IOSTANDARD LVCMOS33 } [get_ports { VGA_R }]; #IO_L3N_T0_DQS_EMCCLK_14 Sch=ck_io[2]
86 | set_property -dict { PACKAGE_PIN R14 IOSTANDARD LVCMOS33 } [get_ports { VGA_G }]; #IO_L13P_T2_MRCC_14 Sch=ck_io[3]
87 | set_property -dict { PACKAGE_PIN T14 IOSTANDARD LVCMOS33 } [get_ports { VGA_B }]; #IO_L13N_T2_MRCC_14 Sch=ck_io[4]
88 | set_property -dict { PACKAGE_PIN R16 IOSTANDARD LVCMOS33 } [get_ports { VALIDWORD }]; #IO_L14P_T2_SRCC_14 Sch=ck_io[5]
89 | set_property -dict { PACKAGE_PIN R17 IOSTANDARD LVCMOS33 } [get_ports { CLOCK25 }]; #IO_L14N_T2_SRCC_14 Sch=ck_io[6]
90 | set_property -dict { PACKAGE_PIN V17 IOSTANDARD LVCMOS33 } [get_ports { READVERTEX }]; #IO_L16N_T2_A15_D31_14 Sch=ck_io[7]
91 | set_property -dict { PACKAGE_PIN R15 IOSTANDARD LVCMOS33 } [get_ports { WRITEVERTEX }]; #IO_L17P_T2_A14_D30_14 Sch=ck_io[8]
92 | set_property -dict { PACKAGE_PIN T15 IOSTANDARD LVCMOS33 } [get_ports { FULL }]; #IO_L17N_T2_A13_D29_14 Sch=ck_io[9]
93 |
94 | ## ChipKit SPI Header
95 | ## NOTE: The ChipKit SPI header ports can also be used as digital I/O and share FPGA pins with ck_io10-13. Do not use both at the same time.
96 | #set_property -dict { PACKAGE_PIN H16 IOSTANDARD LVCMOS33 } [get_ports { ck_io10_ss }]; #IO_L22P_T3_A17_15 Sch=ck_io10_ss
97 | #set_property -dict { PACKAGE_PIN H17 IOSTANDARD LVCMOS33 } [get_ports { ck_io11_mosi }]; #IO_L22N_T3_A16_15 Sch=ck_io11_mosi
98 | #set_property -dict { PACKAGE_PIN K14 IOSTANDARD LVCMOS33 } [get_ports { ck_io12_miso }]; #IO_L23P_T3_FOE_B_15 Sch=ck_io12_miso
99 | #set_property -dict { PACKAGE_PIN G16 IOSTANDARD LVCMOS33 } [get_ports { ck_io13_sck }]; #IO_L14P_T2_SRCC_15 Sch=ck_io13_sck
100 |
101 | ## ChipKit Inner Digital Header
102 | ## Note: these pins are shared with PMOD Headers JC and JD and cannot be used at the same time as the applicable PMOD interface(s)
103 | #set_property -dict { PACKAGE_PIN U11 IOSTANDARD LVCMOS33 } [get_ports { ck_io26 }]; #IO_L24P_T3_A01_D17_14 Sch=jd10/ck_io[26]
104 | #set_property -dict { PACKAGE_PIN T11 IOSTANDARD LVCMOS33 } [get_ports { ck_io27 }]; #IO_L23N_T3_A02_D18_14 Sch=jd9/ck_io[27]
105 | #set_property -dict { PACKAGE_PIN R11 IOSTANDARD LVCMOS33 } [get_ports { ck_io28 }]; #IO_L23P_T3_A03_D19_14 Sch=jd8/ck_io[28]
106 | #set_property -dict { PACKAGE_PIN T13 IOSTANDARD LVCMOS33 } [get_ports { ck_io29 }]; #IO_L22N_T3_A04_D20_14 Sch=jd7/ck_io[29]
107 | #set_property -dict { PACKAGE_PIN T12 IOSTANDARD LVCMOS33 } [get_ports { ck_io30 }]; #IO_L22P_T3_A05_D21_14 Sch=jd4/ck_io[30]
108 | #set_property -dict { PACKAGE_PIN V13 IOSTANDARD LVCMOS33 } [get_ports { ck_io31 }]; #IO_L21N_T3_DQS_A06_D22_14 Sch=jd3/ck_io[31]
109 | #set_property -dict { PACKAGE_PIN U12 IOSTANDARD LVCMOS33 } [get_ports { ck_io32 }]; #IO_L21P_T3_DQS_14 Sch=jd2/ck_io[32]
110 | #set_property -dict { PACKAGE_PIN V15 IOSTANDARD LVCMOS33 } [get_ports { ck_io33 }]; #IO_L20N_T3_A07_D23_14 Sch=jd1/ck_io[33]
111 | #set_property -dict { PACKAGE_PIN V14 IOSTANDARD LVCMOS33 } [get_ports { ck_io34 }]; #IO_L20P_T3_A08_D24_14 Sch=jc10/ck_io[34]
112 | #set_property -dict { PACKAGE_PIN R13 IOSTANDARD LVCMOS33 } [get_ports { ck_io35 }]; #IO_L19N_T3_A09_D25_VREF_14 Sch=jc9/ck_io[35]
113 | #set_property -dict { PACKAGE_PIN P13 IOSTANDARD LVCMOS33 } [get_ports { ck_io36 }]; #IO_L19P_T3_A10_D26_14 Sch=jc8/ck_io[36]
114 | #set_property -dict { PACKAGE_PIN U16 IOSTANDARD LVCMOS33 } [get_ports { ck_io37 }]; #IO_L16P_T2_CSI_B_14 Sch=jc7/ck_io[37]
115 | #set_property -dict { PACKAGE_PIN U18 IOSTANDARD LVCMOS33 } [get_ports { ck_io38 }]; #IO_L15N_T2_DQS_DOUT_CSO_B_14 Sch=jc4/ck_io[38]
116 | #set_property -dict { PACKAGE_PIN U17 IOSTANDARD LVCMOS33 } [get_ports { ck_io39 }]; #IO_L15P_T2_DQS_RDWR_B_14 Sch=jc3/ck_io[39]
117 | #set_property -dict { PACKAGE_PIN V16 IOSTANDARD LVCMOS33 } [get_ports { ck_io40 }]; #IO_L18N_T2_A11_D27_14 Sch=jc2/ck_io[40]
118 | #set_property -dict { PACKAGE_PIN U15 IOSTANDARD LVCMOS33 } [get_ports { ck_io41 }]; #IO_L18P_T2_A12_D28_14 Sch=jc1/ck_io[41]
119 |
120 | ## Dedicated Analog Inputs
121 | #set_property -dict { PACKAGE_PIN J10 } [get_ports { vp_in }]; #IO_L1P_T0_AD4P_35 Sch=v_p
122 | #set_property -dict { PACKAGE_PIN K9 } [get_ports { vn_in }]; #IO_L1N_T0_AD4N_35 Sch=v_n
123 |
124 | ## ChipKit Outer Analog Header - as Single-Ended Analog Inputs
125 | ## NOTE: These ports can be used as single-ended analog inputs with voltages from 0-3.3V (ChipKit analog pins A0-A5) or as digital I/O.
126 | ## WARNING: Do not use both sets of constraints at the same time!
127 | ## NOTE: The following constraints should be used with the XADC IP core when using these ports as analog inputs.
128 | #set_property -dict { PACKAGE_PIN B13 IOSTANDARD LVCMOS33 } [get_ports { vaux0_p }]; #IO_L1P_T0_AD0P_15 Sch=ck_an_p[0] ChipKit pin=A0
129 | #set_property -dict { PACKAGE_PIN A13 IOSTANDARD LVCMOS33 } [get_ports { vaux0_n }]; #IO_L1N_T0_AD0N_15 Sch=ck_an_n[0] ChipKit pin=A0
130 | #set_property -dict { PACKAGE_PIN B15 IOSTANDARD LVCMOS33 } [get_ports { vaux1_p }]; #IO_L3P_T0_DQS_AD1P_15 Sch=ck_an_p[1] ChipKit pin=A1
131 | #set_property -dict { PACKAGE_PIN A15 IOSTANDARD LVCMOS33 } [get_ports { vaux1_n }]; #IO_L3N_T0_DQS_AD1N_15 Sch=ck_an_n[1] ChipKit pin=A1
132 | #set_property -dict { PACKAGE_PIN E12 IOSTANDARD LVCMOS33 } [get_ports { vaux9_p }]; #IO_L5P_T0_AD9P_15 Sch=ck_an_p[2] ChipKit pin=A2
133 | #set_property -dict { PACKAGE_PIN D12 IOSTANDARD LVCMOS33 } [get_ports { vaux9_n }]; #IO_L5N_T0_AD9N_15 Sch=ck_an_n[2] ChipKit pin=A2
134 | #set_property -dict { PACKAGE_PIN B17 IOSTANDARD LVCMOS33 } [get_ports { vaux2_p }]; #IO_L7P_T1_AD2P_15 Sch=ck_an_p[3] ChipKit pin=A3
135 | #set_property -dict { PACKAGE_PIN A17 IOSTANDARD LVCMOS33 } [get_ports { vaux2_n }]; #IO_L7N_T1_AD2N_15 Sch=ck_an_n[3] ChipKit pin=A3
136 | #set_property -dict { PACKAGE_PIN C17 IOSTANDARD LVCMOS33 } [get_ports { vaux10_p }]; #IO_L8P_T1_AD10P_15 Sch=ck_an_p[4] ChipKit pin=A4
137 | #set_property -dict { PACKAGE_PIN B18 IOSTANDARD LVCMOS33 } [get_ports { vaux10_n }]; #IO_L8N_T1_AD10N_15 Sch=ck_an_n[4] ChipKit pin=A4
138 | #set_property -dict { PACKAGE_PIN E16 IOSTANDARD LVCMOS33 } [get_ports { vaux11_p }]; #IO_L10P_T1_AD11P_15 Sch=ck_an_p[5] ChipKit pin=A5
139 | #set_property -dict { PACKAGE_PIN E17 IOSTANDARD LVCMOS33 } [get_ports { vaux11_n }]; #IO_L10N_T1_AD11N_15 Sch=ck_an_n[5] ChipKit pin=A5
140 | ## ChipKit Outer Analog Header - as Digital I/O
141 | ## NOTE: The following constraints should be used when using these ports as digital I/O.
142 | #set_property -dict { PACKAGE_PIN G13 IOSTANDARD LVCMOS33 } [get_ports { ck_a0 }]; #IO_0_15 Sch=ck_a[0]
143 | #set_property -dict { PACKAGE_PIN B16 IOSTANDARD LVCMOS33 } [get_ports { ck_a1 }]; #IO_L4P_T0_15 Sch=ck_a[1]
144 | #set_property -dict { PACKAGE_PIN A16 IOSTANDARD LVCMOS33 } [get_ports { ck_a2 }]; #IO_L4N_T0_15 Sch=ck_a[2]
145 | #set_property -dict { PACKAGE_PIN C13 IOSTANDARD LVCMOS33 } [get_ports { ck_a3 }]; #IO_L6P_T0_15 Sch=ck_a[3]
146 | #set_property -dict { PACKAGE_PIN C14 IOSTANDARD LVCMOS33 } [get_ports { ck_a4 }]; #IO_L6N_T0_VREF_15 Sch=ck_a[4]
147 | #set_property -dict { PACKAGE_PIN D18 IOSTANDARD LVCMOS33 } [get_ports { ck_a5 }]; #IO_L11P_T1_SRCC_15 Sch=ck_a[5]
148 |
149 | ## ChipKit Inner Analog Header - as Differential Analog Inputs
150 | ## NOTE: These ports can be used as differential analog inputs with voltages from 0-1.0V (ChipKit analog pins A6-A11) or as digital I/O.
151 | ## WARNING: Do not use both sets of constraints at the same time!
152 | ## NOTE: The following constraints should be used with the XADC core when using these ports as analog inputs.
153 | #set_property -dict { PACKAGE_PIN B14 IOSTANDARD LVCMOS33 } [get_ports { vaux8_p }]; #IO_L2P_T0_AD8P_15 Sch=ad_p[8] ChipKit pin=A6
154 | #set_property -dict { PACKAGE_PIN A14 IOSTANDARD LVCMOS33 } [get_ports { vaux8_n }]; #IO_L2N_T0_AD8N_15 Sch=ad_n[8] ChipKit pin=A7
155 | #set_property -dict { PACKAGE_PIN D16 IOSTANDARD LVCMOS33 } [get_ports { vaux3_p }]; #IO_L9P_T1_DQS_AD3P_15 Sch=ad_p[3] ChipKit pin=A8
156 | #set_property -dict { PACKAGE_PIN D17 IOSTANDARD LVCMOS33 } [get_ports { vaux3_n }]; #IO_L9N_T1_DQS_AD3N_15 Sch=ad_n[3] ChipKit pin=A9
157 | ## ChipKit Inner Analog Header - as Digital I/O
158 | ## NOTE: The following constraints should be used when using the inner analog header ports as digital I/O.
159 | #set_property -dict { PACKAGE_PIN B14 IOSTANDARD LVCMOS33 } [get_ports { ck_a6 }]; #IO_L2P_T0_AD8P_15 Sch=ad_p[8]
160 | #set_property -dict { PACKAGE_PIN A14 IOSTANDARD LVCMOS33 } [get_ports { ck_a7 }]; #IO_L2N_T0_AD8N_15 Sch=ad_n[8]
161 | #set_property -dict { PACKAGE_PIN D16 IOSTANDARD LVCMOS33 } [get_ports { ck_a8 }]; #IO_L9P_T1_DQS_AD3P_15 Sch=ad_p[3]
162 | #set_property -dict { PACKAGE_PIN D17 IOSTANDARD LVCMOS33 } [get_ports { ck_a9 }]; #IO_L9N_T1_DQS_AD3N_15 Sch=ad_n[3]
163 | #set_property -dict { PACKAGE_PIN D14 IOSTANDARD LVCMOS33 } [get_ports { ck_a10 }]; #IO_L12P_T1_MRCC_15 Sch=ck_a10_r (Cannot be used as an analog input)
164 | #set_property -dict { PACKAGE_PIN D15 IOSTANDARD LVCMOS33 } [get_ports { ck_a11 }]; #IO_L12N_T1_MRCC_15 Sch=ck_a11_r (Cannot be used as an analog input)
165 |
166 | ## ChipKit I2C
167 | #set_property -dict { PACKAGE_PIN J14 IOSTANDARD LVCMOS33 } [get_ports { ck_scl }]; #IO_L24N_T3_RS0_15 Sch=ck_scl
168 | #set_property -dict { PACKAGE_PIN J13 IOSTANDARD LVCMOS33 } [get_ports { ck_sda }]; #IO_L24P_T3_RS1_15 Sch=ck_sda
169 |
170 | ## Misc. ChipKit Ports
171 | #set_property -dict { PACKAGE_PIN K13 IOSTANDARD LVCMOS33 } [get_ports { ck_ioa }]; #IO_25_15 Sch=ck_ioa
172 | #set_property -dict { PACKAGE_PIN C18 IOSTANDARD LVCMOS33 } [get_ports { ck_rst }]; #IO_L11N_T1_SRCC_15
173 |
174 | ## Quad SPI Flash
175 | ## Note: the SCK clock signal can be driven using the STARTUPE2 primitive
176 | #set_property -dict { PACKAGE_PIN M13 IOSTANDARD LVCMOS33 } [get_ports { qspi_cs }]; #IO_L6P_T0_FCS_B_14 Sch=qspi_cs
177 | #set_property -dict { PACKAGE_PIN K17 IOSTANDARD LVCMOS33 } [get_ports { qspi_dq[0] }]; #IO_L1P_T0_D00_MOSI_14 Sch=qspi_dq[0]
178 | #set_property -dict { PACKAGE_PIN K18 IOSTANDARD LVCMOS33 } [get_ports { qspi_dq[1] }]; #IO_L1N_T0_D01_DIN_14 Sch=qspi_dq[1]
179 | #set_property -dict { PACKAGE_PIN L14 IOSTANDARD LVCMOS33 } [get_ports { qspi_dq[2] }]; #IO_L2P_T0_D02_14 Sch=qspi_dq[2]
180 | #set_property -dict { PACKAGE_PIN M15 IOSTANDARD LVCMOS33 } [get_ports { qspi_dq[3] }]; #IO_L2N_T0_D03_14 Sch=qspi_dq[3]
181 |
182 | ## Configuration options, can be used for all designs
183 | set_property BITSTREAM.CONFIG.CONFIGRATE 50 [current_design]
184 | set_property CONFIG_VOLTAGE 3.3 [current_design]
185 | set_property CFGBVS VCCO [current_design]
186 | set_property BITSTREAM.CONFIG.SPI_BUSWIDTH 4 [current_design]
187 | set_property CONFIG_MODE SPIx4 [current_design]
188 |
189 | ## SW3 is assigned to a pin M5 in the 1.35v bank. This pin can also be used as
190 | ## the VREF for BANK 34. To ensure that SW3 does not define the reference voltage
191 | ## and to be able to use this pin as an ordinary I/O the following property must
192 | ## be set to enable an internal VREF for BANK 34. Since a 1.35v supply is being
193 | ## used the internal reference is set to half that value (i.e. 0.675v). Note that
194 | ## this property must be set even if SW3 is not used in the design.
195 | set_property INTERNAL_VREF 0.675 [get_iobanks 34]
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | GNU LESSER GENERAL PUBLIC LICENSE
2 | Version 2.1, February 1999
3 |
4 | Copyright (C) 1991, 1999 Free Software Foundation, Inc.
5 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
6 | Everyone is permitted to copy and distribute verbatim copies
7 | of this license document, but changing it is not allowed.
8 |
9 | [This is the first released version of the Lesser GPL. It also counts
10 | as the successor of the GNU Library Public License, version 2, hence
11 | the version number 2.1.]
12 |
13 | Preamble
14 |
15 | The licenses for most software are designed to take away your
16 | freedom to share and change it. By contrast, the GNU General Public
17 | Licenses are intended to guarantee your freedom to share and change
18 | free software--to make sure the software is free for all its users.
19 |
20 | This license, the Lesser General Public License, applies to some
21 | specially designated software packages--typically libraries--of the
22 | Free Software Foundation and other authors who decide to use it. You
23 | can use it too, but we suggest you first think carefully about whether
24 | this license or the ordinary General Public License is the better
25 | strategy to use in any particular case, based on the explanations below.
26 |
27 | When we speak of free software, we are referring to freedom of use,
28 | not price. Our General Public Licenses are designed to make sure that
29 | you have the freedom to distribute copies of free software (and charge
30 | for this service if you wish); that you receive source code or can get
31 | it if you want it; that you can change the software and use pieces of
32 | it in new free programs; and that you are informed that you can do
33 | these things.
34 |
35 | To protect your rights, we need to make restrictions that forbid
36 | distributors to deny you these rights or to ask you to surrender these
37 | rights. These restrictions translate to certain responsibilities for
38 | you if you distribute copies of the library or if you modify it.
39 |
40 | For example, if you distribute copies of the library, whether gratis
41 | or for a fee, you must give the recipients all the rights that we gave
42 | you. You must make sure that they, too, receive or can get the source
43 | code. If you link other code with the library, you must provide
44 | complete object files to the recipients, so that they can relink them
45 | with the library after making changes to the library and recompiling
46 | it. And you must show them these terms so they know their rights.
47 |
48 | We protect your rights with a two-step method: (1) we copyright the
49 | library, and (2) we offer you this license, which gives you legal
50 | permission to copy, distribute and/or modify the library.
51 |
52 | To protect each distributor, we want to make it very clear that
53 | there is no warranty for the free library. Also, if the library is
54 | modified by someone else and passed on, the recipients should know
55 | that what they have is not the original version, so that the original
56 | author's reputation will not be affected by problems that might be
57 | introduced by others.
58 |
59 | Finally, software patents pose a constant threat to the existence of
60 | any free program. We wish to make sure that a company cannot
61 | effectively restrict the users of a free program by obtaining a
62 | restrictive license from a patent holder. Therefore, we insist that
63 | any patent license obtained for a version of the library must be
64 | consistent with the full freedom of use specified in this license.
65 |
66 | Most GNU software, including some libraries, is covered by the
67 | ordinary GNU General Public License. This license, the GNU Lesser
68 | General Public License, applies to certain designated libraries, and
69 | is quite different from the ordinary General Public License. We use
70 | this license for certain libraries in order to permit linking those
71 | libraries into non-free programs.
72 |
73 | When a program is linked with a library, whether statically or using
74 | a shared library, the combination of the two is legally speaking a
75 | combined work, a derivative of the original library. The ordinary
76 | General Public License therefore permits such linking only if the
77 | entire combination fits its criteria of freedom. The Lesser General
78 | Public License permits more lax criteria for linking other code with
79 | the library.
80 |
81 | We call this license the "Lesser" General Public License because it
82 | does Less to protect the user's freedom than the ordinary General
83 | Public License. It also provides other free software developers Less
84 | of an advantage over competing non-free programs. These disadvantages
85 | are the reason we use the ordinary General Public License for many
86 | libraries. However, the Lesser license provides advantages in certain
87 | special circumstances.
88 |
89 | For example, on rare occasions, there may be a special need to
90 | encourage the widest possible use of a certain library, so that it becomes
91 | a de-facto standard. To achieve this, non-free programs must be
92 | allowed to use the library. A more frequent case is that a free
93 | library does the same job as widely used non-free libraries. In this
94 | case, there is little to gain by limiting the free library to free
95 | software only, so we use the Lesser General Public License.
96 |
97 | In other cases, permission to use a particular library in non-free
98 | programs enables a greater number of people to use a large body of
99 | free software. For example, permission to use the GNU C Library in
100 | non-free programs enables many more people to use the whole GNU
101 | operating system, as well as its variant, the GNU/Linux operating
102 | system.
103 |
104 | Although the Lesser General Public License is Less protective of the
105 | users' freedom, it does ensure that the user of a program that is
106 | linked with the Library has the freedom and the wherewithal to run
107 | that program using a modified version of the Library.
108 |
109 | The precise terms and conditions for copying, distribution and
110 | modification follow. Pay close attention to the difference between a
111 | "work based on the library" and a "work that uses the library". The
112 | former contains code derived from the library, whereas the latter must
113 | be combined with the library in order to run.
114 |
115 | GNU LESSER GENERAL PUBLIC LICENSE
116 | TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
117 |
118 | 0. This License Agreement applies to any software library or other
119 | program which contains a notice placed by the copyright holder or
120 | other authorized party saying it may be distributed under the terms of
121 | this Lesser General Public License (also called "this License").
122 | Each licensee is addressed as "you".
123 |
124 | A "library" means a collection of software functions and/or data
125 | prepared so as to be conveniently linked with application programs
126 | (which use some of those functions and data) to form executables.
127 |
128 | The "Library", below, refers to any such software library or work
129 | which has been distributed under these terms. A "work based on the
130 | Library" means either the Library or any derivative work under
131 | copyright law: that is to say, a work containing the Library or a
132 | portion of it, either verbatim or with modifications and/or translated
133 | straightforwardly into another language. (Hereinafter, translation is
134 | included without limitation in the term "modification".)
135 |
136 | "Source code" for a work means the preferred form of the work for
137 | making modifications to it. For a library, complete source code means
138 | all the source code for all modules it contains, plus any associated
139 | interface definition files, plus the scripts used to control compilation
140 | and installation of the library.
141 |
142 | Activities other than copying, distribution and modification are not
143 | covered by this License; they are outside its scope. The act of
144 | running a program using the Library is not restricted, and output from
145 | such a program is covered only if its contents constitute a work based
146 | on the Library (independent of the use of the Library in a tool for
147 | writing it). Whether that is true depends on what the Library does
148 | and what the program that uses the Library does.
149 |
150 | 1. You may copy and distribute verbatim copies of the Library's
151 | complete source code as you receive it, in any medium, provided that
152 | you conspicuously and appropriately publish on each copy an
153 | appropriate copyright notice and disclaimer of warranty; keep intact
154 | all the notices that refer to this License and to the absence of any
155 | warranty; and distribute a copy of this License along with the
156 | Library.
157 |
158 | You may charge a fee for the physical act of transferring a copy,
159 | and you may at your option offer warranty protection in exchange for a
160 | fee.
161 |
162 | 2. You may modify your copy or copies of the Library or any portion
163 | of it, thus forming a work based on the Library, and copy and
164 | distribute such modifications or work under the terms of Section 1
165 | above, provided that you also meet all of these conditions:
166 |
167 | a) The modified work must itself be a software library.
168 |
169 | b) You must cause the files modified to carry prominent notices
170 | stating that you changed the files and the date of any change.
171 |
172 | c) You must cause the whole of the work to be licensed at no
173 | charge to all third parties under the terms of this License.
174 |
175 | d) If a facility in the modified Library refers to a function or a
176 | table of data to be supplied by an application program that uses
177 | the facility, other than as an argument passed when the facility
178 | is invoked, then you must make a good faith effort to ensure that,
179 | in the event an application does not supply such function or
180 | table, the facility still operates, and performs whatever part of
181 | its purpose remains meaningful.
182 |
183 | (For example, a function in a library to compute square roots has
184 | a purpose that is entirely well-defined independent of the
185 | application. Therefore, Subsection 2d requires that any
186 | application-supplied function or table used by this function must
187 | be optional: if the application does not supply it, the square
188 | root function must still compute square roots.)
189 |
190 | These requirements apply to the modified work as a whole. If
191 | identifiable sections of that work are not derived from the Library,
192 | and can be reasonably considered independent and separate works in
193 | themselves, then this License, and its terms, do not apply to those
194 | sections when you distribute them as separate works. But when you
195 | distribute the same sections as part of a whole which is a work based
196 | on the Library, the distribution of the whole must be on the terms of
197 | this License, whose permissions for other licensees extend to the
198 | entire whole, and thus to each and every part regardless of who wrote
199 | it.
200 |
201 | Thus, it is not the intent of this section to claim rights or contest
202 | your rights to work written entirely by you; rather, the intent is to
203 | exercise the right to control the distribution of derivative or
204 | collective works based on the Library.
205 |
206 | In addition, mere aggregation of another work not based on the Library
207 | with the Library (or with a work based on the Library) on a volume of
208 | a storage or distribution medium does not bring the other work under
209 | the scope of this License.
210 |
211 | 3. You may opt to apply the terms of the ordinary GNU General Public
212 | License instead of this License to a given copy of the Library. To do
213 | this, you must alter all the notices that refer to this License, so
214 | that they refer to the ordinary GNU General Public License, version 2,
215 | instead of to this License. (If a newer version than version 2 of the
216 | ordinary GNU General Public License has appeared, then you can specify
217 | that version instead if you wish.) Do not make any other change in
218 | these notices.
219 |
220 | Once this change is made in a given copy, it is irreversible for
221 | that copy, so the ordinary GNU General Public License applies to all
222 | subsequent copies and derivative works made from that copy.
223 |
224 | This option is useful when you wish to copy part of the code of
225 | the Library into a program that is not a library.
226 |
227 | 4. You may copy and distribute the Library (or a portion or
228 | derivative of it, under Section 2) in object code or executable form
229 | under the terms of Sections 1 and 2 above provided that you accompany
230 | it with the complete corresponding machine-readable source code, which
231 | must be distributed under the terms of Sections 1 and 2 above on a
232 | medium customarily used for software interchange.
233 |
234 | If distribution of object code is made by offering access to copy
235 | from a designated place, then offering equivalent access to copy the
236 | source code from the same place satisfies the requirement to
237 | distribute the source code, even though third parties are not
238 | compelled to copy the source along with the object code.
239 |
240 | 5. A program that contains no derivative of any portion of the
241 | Library, but is designed to work with the Library by being compiled or
242 | linked with it, is called a "work that uses the Library". Such a
243 | work, in isolation, is not a derivative work of the Library, and
244 | therefore falls outside the scope of this License.
245 |
246 | However, linking a "work that uses the Library" with the Library
247 | creates an executable that is a derivative of the Library (because it
248 | contains portions of the Library), rather than a "work that uses the
249 | library". The executable is therefore covered by this License.
250 | Section 6 states terms for distribution of such executables.
251 |
252 | When a "work that uses the Library" uses material from a header file
253 | that is part of the Library, the object code for the work may be a
254 | derivative work of the Library even though the source code is not.
255 | Whether this is true is especially significant if the work can be
256 | linked without the Library, or if the work is itself a library. The
257 | threshold for this to be true is not precisely defined by law.
258 |
259 | If such an object file uses only numerical parameters, data
260 | structure layouts and accessors, and small macros and small inline
261 | functions (ten lines or less in length), then the use of the object
262 | file is unrestricted, regardless of whether it is legally a derivative
263 | work. (Executables containing this object code plus portions of the
264 | Library will still fall under Section 6.)
265 |
266 | Otherwise, if the work is a derivative of the Library, you may
267 | distribute the object code for the work under the terms of Section 6.
268 | Any executables containing that work also fall under Section 6,
269 | whether or not they are linked directly with the Library itself.
270 |
271 | 6. As an exception to the Sections above, you may also combine or
272 | link a "work that uses the Library" with the Library to produce a
273 | work containing portions of the Library, and distribute that work
274 | under terms of your choice, provided that the terms permit
275 | modification of the work for the customer's own use and reverse
276 | engineering for debugging such modifications.
277 |
278 | You must give prominent notice with each copy of the work that the
279 | Library is used in it and that the Library and its use are covered by
280 | this License. You must supply a copy of this License. If the work
281 | during execution displays copyright notices, you must include the
282 | copyright notice for the Library among them, as well as a reference
283 | directing the user to the copy of this License. Also, you must do one
284 | of these things:
285 |
286 | a) Accompany the work with the complete corresponding
287 | machine-readable source code for the Library including whatever
288 | changes were used in the work (which must be distributed under
289 | Sections 1 and 2 above); and, if the work is an executable linked
290 | with the Library, with the complete machine-readable "work that
291 | uses the Library", as object code and/or source code, so that the
292 | user can modify the Library and then relink to produce a modified
293 | executable containing the modified Library. (It is understood
294 | that the user who changes the contents of definitions files in the
295 | Library will not necessarily be able to recompile the application
296 | to use the modified definitions.)
297 |
298 | b) Use a suitable shared library mechanism for linking with the
299 | Library. A suitable mechanism is one that (1) uses at run time a
300 | copy of the library already present on the user's computer system,
301 | rather than copying library functions into the executable, and (2)
302 | will operate properly with a modified version of the library, if
303 | the user installs one, as long as the modified version is
304 | interface-compatible with the version that the work was made with.
305 |
306 | c) Accompany the work with a written offer, valid for at
307 | least three years, to give the same user the materials
308 | specified in Subsection 6a, above, for a charge no more
309 | than the cost of performing this distribution.
310 |
311 | d) If distribution of the work is made by offering access to copy
312 | from a designated place, offer equivalent access to copy the above
313 | specified materials from the same place.
314 |
315 | e) Verify that the user has already received a copy of these
316 | materials or that you have already sent this user a copy.
317 |
318 | For an executable, the required form of the "work that uses the
319 | Library" must include any data and utility programs needed for
320 | reproducing the executable from it. However, as a special exception,
321 | the materials to be distributed need not include anything that is
322 | normally distributed (in either source or binary form) with the major
323 | components (compiler, kernel, and so on) of the operating system on
324 | which the executable runs, unless that component itself accompanies
325 | the executable.
326 |
327 | It may happen that this requirement contradicts the license
328 | restrictions of other proprietary libraries that do not normally
329 | accompany the operating system. Such a contradiction means you cannot
330 | use both them and the Library together in an executable that you
331 | distribute.
332 |
333 | 7. You may place library facilities that are a work based on the
334 | Library side-by-side in a single library together with other library
335 | facilities not covered by this License, and distribute such a combined
336 | library, provided that the separate distribution of the work based on
337 | the Library and of the other library facilities is otherwise
338 | permitted, and provided that you do these two things:
339 |
340 | a) Accompany the combined library with a copy of the same work
341 | based on the Library, uncombined with any other library
342 | facilities. This must be distributed under the terms of the
343 | Sections above.
344 |
345 | b) Give prominent notice with the combined library of the fact
346 | that part of it is a work based on the Library, and explaining
347 | where to find the accompanying uncombined form of the same work.
348 |
349 | 8. You may not copy, modify, sublicense, link with, or distribute
350 | the Library except as expressly provided under this License. Any
351 | attempt otherwise to copy, modify, sublicense, link with, or
352 | distribute the Library is void, and will automatically terminate your
353 | rights under this License. However, parties who have received copies,
354 | or rights, from you under this License will not have their licenses
355 | terminated so long as such parties remain in full compliance.
356 |
357 | 9. You are not required to accept this License, since you have not
358 | signed it. However, nothing else grants you permission to modify or
359 | distribute the Library or its derivative works. These actions are
360 | prohibited by law if you do not accept this License. Therefore, by
361 | modifying or distributing the Library (or any work based on the
362 | Library), you indicate your acceptance of this License to do so, and
363 | all its terms and conditions for copying, distributing or modifying
364 | the Library or works based on it.
365 |
366 | 10. Each time you redistribute the Library (or any work based on the
367 | Library), the recipient automatically receives a license from the
368 | original licensor to copy, distribute, link with or modify the Library
369 | subject to these terms and conditions. You may not impose any further
370 | restrictions on the recipients' exercise of the rights granted herein.
371 | You are not responsible for enforcing compliance by third parties with
372 | this License.
373 |
374 | 11. If, as a consequence of a court judgment or allegation of patent
375 | infringement or for any other reason (not limited to patent issues),
376 | conditions are imposed on you (whether by court order, agreement or
377 | otherwise) that contradict the conditions of this License, they do not
378 | excuse you from the conditions of this License. If you cannot
379 | distribute so as to satisfy simultaneously your obligations under this
380 | License and any other pertinent obligations, then as a consequence you
381 | may not distribute the Library at all. For example, if a patent
382 | license would not permit royalty-free redistribution of the Library by
383 | all those who receive copies directly or indirectly through you, then
384 | the only way you could satisfy both it and this License would be to
385 | refrain entirely from distribution of the Library.
386 |
387 | If any portion of this section is held invalid or unenforceable under any
388 | particular circumstance, the balance of the section is intended to apply,
389 | and the section as a whole is intended to apply in other circumstances.
390 |
391 | It is not the purpose of this section to induce you to infringe any
392 | patents or other property right claims or to contest validity of any
393 | such claims; this section has the sole purpose of protecting the
394 | integrity of the free software distribution system which is
395 | implemented by public license practices. Many people have made
396 | generous contributions to the wide range of software distributed
397 | through that system in reliance on consistent application of that
398 | system; it is up to the author/donor to decide if he or she is willing
399 | to distribute software through any other system and a licensee cannot
400 | impose that choice.
401 |
402 | This section is intended to make thoroughly clear what is believed to
403 | be a consequence of the rest of this License.
404 |
405 | 12. If the distribution and/or use of the Library is restricted in
406 | certain countries either by patents or by copyrighted interfaces, the
407 | original copyright holder who places the Library under this License may add
408 | an explicit geographical distribution limitation excluding those countries,
409 | so that distribution is permitted only in or among countries not thus
410 | excluded. In such case, this License incorporates the limitation as if
411 | written in the body of this License.
412 |
413 | 13. The Free Software Foundation may publish revised and/or new
414 | versions of the Lesser General Public License from time to time.
415 | Such new versions will be similar in spirit to the present version,
416 | but may differ in detail to address new problems or concerns.
417 |
418 | Each version is given a distinguishing version number. If the Library
419 | specifies a version number of this License which applies to it and
420 | "any later version", you have the option of following the terms and
421 | conditions either of that version or of any later version published by
422 | the Free Software Foundation. If the Library does not specify a
423 | license version number, you may choose any version ever published by
424 | the Free Software Foundation.
425 |
426 | 14. If you wish to incorporate parts of the Library into other free
427 | programs whose distribution conditions are incompatible with these,
428 | write to the author to ask for permission. For software which is
429 | copyrighted by the Free Software Foundation, write to the Free
430 | Software Foundation; we sometimes make exceptions for this. Our
431 | decision will be guided by the two goals of preserving the free status
432 | of all derivatives of our free software and of promoting the sharing
433 | and reuse of software generally.
434 |
435 | NO WARRANTY
436 |
437 | 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
438 | WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
439 | EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
440 | OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
441 | KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
442 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
443 | PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
444 | LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
445 | THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
446 |
447 | 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
448 | WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
449 | AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
450 | FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
451 | CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
452 | LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
453 | RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
454 | FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
455 | SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
456 | DAMAGES.
457 |
458 | END OF TERMS AND CONDITIONS
459 |
460 | How to Apply These Terms to Your New Libraries
461 |
462 | If you develop a new library, and you want it to be of the greatest
463 | possible use to the public, we recommend making it free software that
464 | everyone can redistribute and change. You can do so by permitting
465 | redistribution under these terms (or, alternatively, under the terms of the
466 | ordinary General Public License).
467 |
468 | To apply these terms, attach the following notices to the library. It is
469 | safest to attach them to the start of each source file to most effectively
470 | convey the exclusion of warranty; and each file should have at least the
471 | "copyright" line and a pointer to where the full notice is found.
472 |
473 |
474 | Copyright (C)
475 |
476 | This library is free software; you can redistribute it and/or
477 | modify it under the terms of the GNU Lesser General Public
478 | License as published by the Free Software Foundation; either
479 | version 2.1 of the License, or (at your option) any later version.
480 |
481 | This library is distributed in the hope that it will be useful,
482 | but WITHOUT ANY WARRANTY; without even the implied warranty of
483 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
484 | Lesser General Public License for more details.
485 |
486 | You should have received a copy of the GNU Lesser General Public
487 | License along with this library; if not, write to the Free Software
488 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
489 | USA
490 |
491 | Also add information on how to contact you by electronic and paper mail.
492 |
493 | You should also get your employer (if you work as a programmer) or your
494 | school, if any, to sign a "copyright disclaimer" for the library, if
495 | necessary. Here is a sample; alter the names:
496 |
497 | Yoyodyne, Inc., hereby disclaims all copyright interest in the
498 | library `Frob' (a library for tweaking knobs) written by James Random
499 | Hacker.
500 |
501 | , 1 April 1990
502 | Ty Coon, President of Vice
503 |
504 | That's all there is to it!
505 |
--------------------------------------------------------------------------------