1 |
3 |
yannv |
`timescale 1ns / 1ps
|
2 |
|
|
//////////////////////////////////////////////////////////////////////////////////
|
3 |
|
|
// Company:
|
4 |
|
|
// Engineer: Yann Vernier
|
5 |
|
|
//
|
6 |
|
|
// Create Date: 21:37:32 02/19/2011
|
7 |
|
|
// Design Name:
|
8 |
|
|
// Module Name: vector2scanline
|
9 |
|
|
// Project Name: PDP-1
|
10 |
|
|
// Target Devices: Spartan 3A
|
11 |
|
|
// Tool versions:
|
12 |
|
|
// Description: Converts vector data (exposed points) into raster video
|
13 |
|
|
//
|
14 |
|
|
// Dependencies:
|
15 |
|
|
//
|
16 |
|
|
//////////////////////////////////////////////////////////////////////////////////
|
17 |
|
|
|
18 |
|
|
module vector2scanline(
|
19 |
4 |
yannv |
input clk, // clock
|
20 |
3 |
yannv |
|
21 |
4 |
yannv |
input strobe, // new exposed pixel trigger
|
22 |
|
|
input [9:0] x, // column of exposed pixel
|
23 |
|
|
input [9:0] y, // row of exposed pixel
|
24 |
3 |
yannv |
|
25 |
4 |
yannv |
// Video output interface
|
26 |
|
|
input [9:0] xout, // current pixel column
|
27 |
|
|
input [9:0] yout, // current pixel row
|
28 |
|
|
input newline, // line buffer swap signal
|
29 |
|
|
input newframe, // new frame signal
|
30 |
|
|
output [7:0] pixel // output pixel intensity
|
31 |
|
|
);
|
32 |
3 |
yannv |
|
33 |
4 |
yannv |
// TODO: figure out how to apply parameters to the port sizes above
|
34 |
|
|
parameter X_WIDTH = 10; // bit width of column coordinate
|
35 |
|
|
parameter Y_WIDTH = 10; // bit width of row coordinate
|
36 |
|
|
parameter HIST_WIDTH = 10; // log2 of maximum lit pixels (exposure buffer)
|
37 |
|
|
parameter AGE_WIDTH = 8; // width of exposure age counter
|
38 |
3 |
yannv |
|
39 |
4 |
yannv |
// positions and age of lit pixels
|
40 |
|
|
reg [X_WIDTH+Y_WIDTH+AGE_WIDTH-1:0] exposures [(2**HIST_WIDTH)-1:0];
|
41 |
|
|
// output register of exposed pixels buffer
|
42 |
|
|
reg [X_WIDTH+Y_WIDTH+AGE_WIDTH-1:0] expr;
|
43 |
|
|
// data for next pixel to store in exposure buffer
|
44 |
|
|
wire [X_WIDTH-1:0] expx;
|
45 |
|
|
wire [Y_WIDTH-1:0] expy;
|
46 |
|
|
wire [7:0] expi;
|
47 |
|
|
// whether this pixel needs to be stored back in exposure buffer
|
48 |
|
|
wire exposed;
|
49 |
|
|
// addresses for exposure buffer read and write ports
|
50 |
|
|
reg [HIST_WIDTH-1:0] exprptr=0, expwptr=0;
|
51 |
3 |
yannv |
|
52 |
4 |
yannv |
// scanline pixel buffers, store intensity
|
53 |
|
|
// double-buffered; one gets wiped as it is displayed
|
54 |
|
|
// the other gets filled in with current exposures
|
55 |
|
|
reg [AGE_WIDTH-1:0] scanline0 [(2**X_WIDTH)-1:0];
|
56 |
|
|
reg [AGE_WIDTH-1:0] scanline1 [(2**X_WIDTH)-1:0];
|
57 |
|
|
// output intensity for current pixel
|
58 |
|
|
reg [AGE_WIDTH-1:0] pixelout;
|
59 |
|
|
// selection register for which scanline buffer is output/filled in
|
60 |
|
|
reg bufsel = 0;
|
61 |
|
|
// address lines for scanline buffers
|
62 |
|
|
wire [X_WIDTH-1:0] sl0w, sl1w;
|
63 |
3 |
yannv |
|
64 |
4 |
yannv |
// RAM read out of exposure buffer
|
65 |
|
|
always @(posedge clk) begin
|
66 |
|
|
expr<=exposures[exprptr];
|
67 |
|
|
if (!strobe) begin
|
68 |
|
|
// do not skip current read position if strobe inserts a new pixel
|
69 |
|
|
exprptr<=exprptr+1;
|
70 |
|
|
end
|
71 |
|
|
end
|
72 |
3 |
yannv |
|
73 |
4 |
yannv |
// decode and mux: split fields from exposure buffer, or collect new at strobe
|
74 |
|
|
assign expx = strobe?x:expr[X_WIDTH+Y_WIDTH+AGE_WIDTH-1:Y_WIDTH+AGE_WIDTH];
|
75 |
|
|
assign expy = strobe?y:expr[Y_WIDTH+AGE_WIDTH-1:AGE_WIDTH];
|
76 |
|
|
assign expi = strobe?(2**AGE_WIDTH)-1:expr[AGE_WIDTH-1:0];
|
77 |
|
|
// detect whether pixel even needs to be stored back
|
78 |
|
|
assign exposed = expi!=0;
|
79 |
|
|
|
80 |
|
|
always @(posedge clk) begin
|
81 |
|
|
// Feed incoming exposures into exposure buffer
|
82 |
|
|
if (exposed) begin
|
83 |
|
|
exposures[expwptr] <= {expx, expy, expy==yout?expi-1:expi};
|
84 |
|
|
expwptr <= expwptr+1;
|
85 |
|
|
end
|
86 |
|
|
end
|
87 |
3 |
yannv |
|
88 |
4 |
yannv |
// scanline buffers switch output or expose roles based on bufsel
|
89 |
|
|
assign sl0w=bufsel?expx:xout;
|
90 |
|
|
assign sl1w=bufsel?xout:expx;
|
91 |
|
|
always @(posedge clk) begin
|
92 |
|
|
// Read out front buffer
|
93 |
|
|
pixelout <= bufsel?scanline1[sl1w]:scanline0[sl0w];
|
94 |
|
|
// TODO: use a next line input port, this incrementer won't work for
|
95 |
|
|
// line 0 (which is unused in display.vhd) and could be shared.
|
96 |
|
|
if (expy==(y+1)) begin
|
97 |
|
|
// Store exposures for current scanline and wipe front buffer
|
98 |
|
|
scanline0[sl0w] <= bufsel?expi:0;
|
99 |
|
|
scanline1[sl1w] <= bufsel?0:expi;
|
100 |
|
|
end
|
101 |
|
|
// swap buffers when signaled
|
102 |
|
|
if (newline) begin
|
103 |
|
|
bufsel <= ~bufsel;
|
104 |
|
|
end
|
105 |
|
|
end
|
106 |
3 |
yannv |
|
107 |
4 |
yannv |
// output pixel intensity
|
108 |
|
|
assign pixel = pixelout;
|
109 |
|
|
|
110 |
3 |
yannv |
endmodule
|