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

Subversion Repositories pdp1

[/] [pdp1/] [trunk/] [rtl/] [verilog/] [vector2scanline.v] - Blame information for rev 6

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 3 yannv
`timescale 1ns / 1ps
2
//////////////////////////////////////////////////////////////////////////////////
3
// Engineer: Yann Vernier
4
// 
5
// Create Date:    21:37:32 02/19/2011 
6
// Design Name: 
7
// Module Name:    vector2scanline 
8
// Project Name: PDP-1
9
// Target Devices: Spartan 3A
10
// Tool versions: 
11
// Description: Converts vector data (exposed points) into raster video
12
//
13
// Dependencies: 
14
//
15 5 yannv
// Revision: $Id$
16
// $Log$
17
// Additional Comments: 
18
//
19 3 yannv
//////////////////////////////////////////////////////////////////////////////////
20
 
21 6 yannv
/*
22
 * Design: Two interfaces are provided, each with their own clock.
23
 *         The first is an XY plotting interface, where each new point
24
 *         is indicated by a rising edge on strobe_i.
25
 *         The second is the scanline/raster video port, where a pixel
26
 *         clock reads out a single scanline, and rising edges on
27
 *         newline_i and newframe_i indicate when a new or first line
28
 *         should start.
29
 *
30
 * The target design runs a pixel clock of 193MHz and plotting clock
31
 * of 50MHz, ensuring that no plotted point is missed.
32
 * A register to store the plotted point could be added instead, but
33
 * currently hold times are guaranteed to work (changes only occur on
34
 * a 200kHz cycle). Expect timing warnings, however.
35
 *
36
 * Internal structure: One ring buffer FIFO stores plotted points and their
37
 * respective age. Age is decremented only when the points are copied into
38
 * the scanline buffer (once per frame).
39
 * A dual-port scanline buffer is filled in with plotted points in a back-
40
 * buffer while the forward buffer is read out to video and subsequently
41
 * wiped.
42
 *
43
 * The FIFO could be factored out and converted to LFSR counting.
44
 *
45
 * TODO: Make the scanning stop once it has reached the edges.
46
 *       Connect to main design. Add next scanline ports, so double
47
 *       buffers do not delay everything one line.
48
 *
49
 */
50
 
51 3 yannv
module vector2scanline(
52 6 yannv
                       clk_xy_i,          // clock
53 5 yannv
                       strobe_i,      // new exposed pixel trigger
54
                       x_i,          // column of exposed pixel
55
                       y_i,          // row of exposed pixel
56 3 yannv
 
57 6 yannv
                       clk_fifo_i,
58
 
59 4 yannv
                       // Video output interface
60 6 yannv
                       clk_video_i,    // pixel clock
61
                       xout_i,         // current pixel column
62
                       yout_i,         // current pixel row
63 5 yannv
                       newline_i,      // line buffer swap signal
64
                       newframe_i,     // new frame signal
65 6 yannv
                       pixel_o,  // output pixel intensity, unregistered
66
                       /*AUTOARG*/
67
   // Inputs
68
   wipe_i
69
   );
70 3 yannv
 
71 5 yannv
 
72 4 yannv
   parameter X_WIDTH = 10;     // bit width of column coordinate
73
   parameter Y_WIDTH = 10;     // bit width of row coordinate
74
   parameter HIST_WIDTH = 10;  // log2 of maximum lit pixels (exposure buffer)
75
   parameter AGE_WIDTH = 8;    // width of exposure age counter
76 5 yannv
 
77 6 yannv
   input clk_xy_i;
78 5 yannv
   input strobe_i;
79
   input [X_WIDTH-1:0] x_i;
80
   input [Y_WIDTH-1:0] y_i;
81 3 yannv
 
82 6 yannv
   input               clk_fifo_i;
83
   input [AGE_WIDTH-1:0] wipe_i;
84
 
85
   input               clk_video_i;
86 5 yannv
   input [X_WIDTH-1:0] xout_i;
87
   input [Y_WIDTH-1:0] yout_i;
88
   input               newline_i, newframe_i;
89
   output [AGE_WIDTH-1:0] pixel_o;
90 6 yannv
   reg                    pixel_o;
91 5 yannv
 
92 6 yannv
   // Used for edge detection on strobe signals
93
   reg prev_strobe_i, prev_newline_i, prev_newframe_i;
94
   // Result of edge detectors
95
   wire strobe, newline, newframe;
96
 
97 4 yannv
   // positions and age of lit pixels
98
   reg [X_WIDTH+Y_WIDTH+AGE_WIDTH-1:0] exposures [(2**HIST_WIDTH)-1:0];
99
   // output register of exposed pixels buffer
100
   reg [X_WIDTH+Y_WIDTH+AGE_WIDTH-1:0] expr;
101
   // data for next pixel to store in exposure buffer
102
   wire [X_WIDTH-1:0]                   expx;
103
   wire [Y_WIDTH-1:0]                   expy;
104 5 yannv
   wire [AGE_WIDTH-1:0]         expi;
105 4 yannv
   // whether this pixel needs to be stored back in exposure buffer
106
   wire                                exposed;
107 5 yannv
   // whether this pixel belongs to the next (backbuffer) scanline
108
   wire                                rowmatch;
109 4 yannv
   // addresses for exposure buffer read and write ports
110
   reg [HIST_WIDTH-1:0]         exprptr=0, expwptr=0;
111 5 yannv
 
112 6 yannv
   // dual port scanline pixel buffer, stores intensity
113 4 yannv
   // double-buffered; one gets wiped as it is displayed
114
   // the other gets filled in with current exposures
115 6 yannv
   reg [AGE_WIDTH-1:0]                  scanlines [(2**X_WIDTH):0];
116 4 yannv
   // selection register for which scanline buffer is output/filled in
117
   reg                                 bufsel = 0;
118 6 yannv
   // address lines for the two memory ports
119
   wire [X_WIDTH:0]                     scanout_addr, lineplot_addr;
120
   wire                                scanout_clk, lineplot_clk;
121 5 yannv
 
122 6 yannv
   // Edge detectors for strobe lines
123
   always @(posedge clk_xy_i) prev_strobe_i <= strobe_i;
124
   assign strobe = strobe_i & ~prev_strobe_i;
125
   always @(posedge clk_video_i) prev_newline_i <= newline_i;
126
   assign newline = newline_i & ~prev_newline_i;
127
   always @(posedge clk_video_i) prev_newframe_i <= newframe_i;
128
   assign newframe = newframe_i & ~prev_newframe_i;
129
 
130
 
131 4 yannv
   // RAM read out of exposure buffer
132 6 yannv
   always @(posedge clk_fifo_i) begin
133
      // TODO: stop scanning until newline once we're through the entire buffer
134 4 yannv
      expr<=exposures[exprptr];
135
      if (!strobe) begin
136
         // do not skip current read position if strobe inserts a new pixel
137
         exprptr<=exprptr+1;
138
      end
139
   end
140 3 yannv
 
141 4 yannv
   // decode and mux: split fields from exposure buffer, or collect new at strobe
142 6 yannv
   assign expx = strobe?x_i:expr[X_WIDTH+Y_WIDTH+AGE_WIDTH-1:Y_WIDTH+AGE_WIDTH];
143
   assign expy = strobe?y_i:expr[Y_WIDTH+AGE_WIDTH-1:AGE_WIDTH];
144
   assign expi = strobe?(2**AGE_WIDTH)-1:expr[AGE_WIDTH-1:0];
145 4 yannv
   // detect whether pixel even needs to be stored back
146
   assign exposed = expi!=0;
147 5 yannv
   // detect whether pixel applies to current backbuffer
148 6 yannv
      // TODO: use a next line input port, the double buffering delays this data
149
      // by an entire scanline.
150
   assign rowmatch=(expy==yout_i);
151 4 yannv
 
152 6 yannv
   always @(posedge clk_fifo_i) begin
153 4 yannv
      // Feed incoming exposures into exposure buffer
154 6 yannv
      // TODO: stop scanning until newline once we're through the entire buffer
155 4 yannv
      if (exposed) begin
156 5 yannv
         exposures[expwptr] <= {expx, expy, expy==yout_i?expi-1:expi};
157 4 yannv
         expwptr <= expwptr+1;
158
      end
159
   end
160 3 yannv
 
161 6 yannv
 
162
   // Fron buffer address
163
   assign scanout_addr = {bufsel,xout_i};
164
   assign scanout_clk = clk_video_i;
165
   always @(posedge scanout_clk) begin
166
      // Wipe front buffer
167
      scanlines[scanout_addr] <= wipe_i;
168 4 yannv
      // Read out front buffer
169 6 yannv
      pixel_o <= scanlines[scanout_addr];
170
   end
171 5 yannv
 
172 6 yannv
   // Back buffer address
173
   assign lineplot_addr = {~bufsel, expx};
174
   assign lineplot_clk = clk_fifo_i;
175
   always @(posedge lineplot_clk) begin
176
      //            pixel_o <= scanlines[lineplot_addr];
177
      // Store exposures for next scanline
178
      if (rowmatch) begin
179
         scanlines[lineplot_addr] <= expi;
180 4 yannv
      end
181 6 yannv
   end
182 5 yannv
 
183 6 yannv
   always @(posedge clk_video_i) begin
184 4 yannv
      // swap buffers when signaled
185 6 yannv
      if (newline) begin
186 4 yannv
         bufsel <= ~bufsel;
187
      end
188
   end
189 5 yannv
 
190 3 yannv
endmodule

powered by: WebSVN 2.1.0

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