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

Subversion Repositories pdp1

[/] [pdp1/] [trunk/] [rtl/] [verilog/] [vector2scanline.v] - Diff between revs 5 and 6

Go to most recent revision | Show entire file | Details | Blame | View Log

Rev 5 Rev 6
Line 16... Line 16...
// $Log$
// $Log$
// Additional Comments: 
// Additional Comments: 
//
//
//////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////
 
 
module vector2scanline(
/*
                       clk_i,          // clock
 * Design: Two interfaces are provided, each with their own clock.
 
 *         The first is an XY plotting interface, where each new point
 
 *         is indicated by a rising edge on strobe_i.
 
 *         The second is the scanline/raster video port, where a pixel
 
 *         clock reads out a single scanline, and rising edges on
 
 *         newline_i and newframe_i indicate when a new or first line
 
 *         should start.
 
 *
 
 * The target design runs a pixel clock of 193MHz and plotting clock
 
 * of 50MHz, ensuring that no plotted point is missed.
 
 * A register to store the plotted point could be added instead, but
 
 * currently hold times are guaranteed to work (changes only occur on
 
 * a 200kHz cycle). Expect timing warnings, however.
 
 *
 
 * Internal structure: One ring buffer FIFO stores plotted points and their
 
 * respective age. Age is decremented only when the points are copied into
 
 * the scanline buffer (once per frame).
 
 * A dual-port scanline buffer is filled in with plotted points in a back-
 
 * buffer while the forward buffer is read out to video and subsequently
 
 * wiped.
 
 *
 
 * The FIFO could be factored out and converted to LFSR counting.
 
 *
 
 * TODO: Make the scanning stop once it has reached the edges.
 
 *       Connect to main design. Add next scanline ports, so double
 
 *       buffers do not delay everything one line.
 
 *
 
 */
 
 
 
module vector2scanline(
 
                       clk_xy_i,          // clock
                       strobe_i,      // new exposed pixel trigger
                       strobe_i,      // new exposed pixel trigger
                       x_i,          // column of exposed pixel
                       x_i,          // column of exposed pixel
                       y_i,          // row of exposed pixel
                       y_i,          // row of exposed pixel
 
 
 
                       clk_fifo_i,
 
 
                       // Video output interface
                       // Video output interface
 
                       clk_video_i,    // pixel clock
                       xout_i,   // current pixel column
                       xout_i,   // current pixel column
                       yout_i,   // current pixel row
                       yout_i,   // current pixel row
                       newline_i,      // line buffer swap signal
                       newline_i,      // line buffer swap signal
                       newframe_i,     // new frame signal
                       newframe_i,     // new frame signal
                       pixel_o  // output pixel intensity
                       pixel_o,  // output pixel intensity, unregistered
                       /*AUTOARG*/);
                       /*AUTOARG*/
 
   // Inputs
 
   wipe_i
 
   );
 
 
 
 
   parameter X_WIDTH = 10;     // bit width of column coordinate
   parameter X_WIDTH = 10;     // bit width of column coordinate
   parameter Y_WIDTH = 10;     // bit width of row coordinate
   parameter Y_WIDTH = 10;     // bit width of row coordinate
   parameter HIST_WIDTH = 10;  // log2 of maximum lit pixels (exposure buffer)
   parameter HIST_WIDTH = 10;  // log2 of maximum lit pixels (exposure buffer)
   parameter AGE_WIDTH = 8;    // width of exposure age counter
   parameter AGE_WIDTH = 8;    // width of exposure age counter
 
 
   input clk_i;
   input clk_xy_i;
 
 
   input strobe_i;
   input strobe_i;
   input [X_WIDTH-1:0] x_i;
   input [X_WIDTH-1:0] x_i;
   input [Y_WIDTH-1:0] y_i;
   input [Y_WIDTH-1:0] y_i;
 
 
 
   input               clk_fifo_i;
 
   input [AGE_WIDTH-1:0] wipe_i;
 
 
 
   input               clk_video_i;
   input [X_WIDTH-1:0] xout_i;
   input [X_WIDTH-1:0] xout_i;
   input [Y_WIDTH-1:0] yout_i;
   input [Y_WIDTH-1:0] yout_i;
   input               newline_i, newframe_i;
   input               newline_i, newframe_i;
   output [AGE_WIDTH-1:0] pixel_o;
   output [AGE_WIDTH-1:0] pixel_o;
 
   reg                    pixel_o;
 
 
 
   // Used for edge detection on strobe signals
 
   reg prev_strobe_i, prev_newline_i, prev_newframe_i;
 
   // Result of edge detectors
 
   wire strobe, newline, newframe;
 
 
   // positions and age of lit pixels
   // positions and age of lit pixels
   reg [X_WIDTH+Y_WIDTH+AGE_WIDTH-1:0] exposures [(2**HIST_WIDTH)-1:0];
   reg [X_WIDTH+Y_WIDTH+AGE_WIDTH-1:0] exposures [(2**HIST_WIDTH)-1:0];
   // output register of exposed pixels buffer
   // output register of exposed pixels buffer
   reg [X_WIDTH+Y_WIDTH+AGE_WIDTH-1:0] expr;
   reg [X_WIDTH+Y_WIDTH+AGE_WIDTH-1:0] expr;
Line 63... Line 107...
   // whether this pixel belongs to the next (backbuffer) scanline
   // whether this pixel belongs to the next (backbuffer) scanline
   wire                                rowmatch;
   wire                                rowmatch;
   // addresses for exposure buffer read and write ports
   // addresses for exposure buffer read and write ports
   reg [HIST_WIDTH-1:0]         exprptr=0, expwptr=0;
   reg [HIST_WIDTH-1:0]         exprptr=0, expwptr=0;
 
 
   // scanline pixel buffers, store intensity
   // dual port scanline pixel buffer, stores intensity
   // double-buffered; one gets wiped as it is displayed
   // double-buffered; one gets wiped as it is displayed
   // the other gets filled in with current exposures
   // the other gets filled in with current exposures
   reg [AGE_WIDTH-1:0]                  scanline0 [(2**X_WIDTH)-1:0];
   reg [AGE_WIDTH-1:0]                  scanlines [(2**X_WIDTH):0];
   reg [AGE_WIDTH-1:0]                  scanline1 [(2**X_WIDTH)-1:0];
 
   // output intensity for current pixel
 
   reg [AGE_WIDTH-1:0]                  pixelout;
 
   // selection register for which scanline buffer is output/filled in
   // selection register for which scanline buffer is output/filled in
   reg                                 bufsel = 0;
   reg                                 bufsel = 0;
   // address lines for scanline buffers
   // address lines for the two memory ports
   wire [X_WIDTH-1:0]                   sl0w, sl1w;
   wire [X_WIDTH:0]                     scanout_addr, lineplot_addr;
 
   wire                                scanout_clk, lineplot_clk;
 
 
 
   // Edge detectors for strobe lines
 
   always @(posedge clk_xy_i) prev_strobe_i <= strobe_i;
 
   assign strobe = strobe_i & ~prev_strobe_i;
 
   always @(posedge clk_video_i) prev_newline_i <= newline_i;
 
   assign newline = newline_i & ~prev_newline_i;
 
   always @(posedge clk_video_i) prev_newframe_i <= newframe_i;
 
   assign newframe = newframe_i & ~prev_newframe_i;
 
 
 
 
   // RAM read out of exposure buffer
   // RAM read out of exposure buffer
   always @(posedge clk_i) begin
   always @(posedge clk_fifo_i) begin
 
      // TODO: stop scanning until newline once we're through the entire buffer
      expr<=exposures[exprptr];
      expr<=exposures[exprptr];
      if (!strobe) begin
      if (!strobe) begin
         // do not skip current read position if strobe inserts a new pixel
         // do not skip current read position if strobe inserts a new pixel
         exprptr<=exprptr+1;
         exprptr<=exprptr+1;
      end
      end
   end
   end
 
 
   // decode and mux: split fields from exposure buffer, or collect new at strobe
   // decode and mux: split fields from exposure buffer, or collect new at strobe
   assign expx = strobe_i?x_i:expr[X_WIDTH+Y_WIDTH+AGE_WIDTH-1:Y_WIDTH+AGE_WIDTH];
   assign expx = strobe?x_i:expr[X_WIDTH+Y_WIDTH+AGE_WIDTH-1:Y_WIDTH+AGE_WIDTH];
   assign expy = strobe_i?y_i:expr[Y_WIDTH+AGE_WIDTH-1:AGE_WIDTH];
   assign expy = strobe?y_i:expr[Y_WIDTH+AGE_WIDTH-1:AGE_WIDTH];
   assign expi = strobe_i?(2**AGE_WIDTH)-1:expr[AGE_WIDTH-1:0];
   assign expi = strobe?(2**AGE_WIDTH)-1:expr[AGE_WIDTH-1:0];
   // detect whether pixel even needs to be stored back
   // detect whether pixel even needs to be stored back
   assign exposed = expi!=0;
   assign exposed = expi!=0;
   // detect whether pixel applies to current backbuffer
   // detect whether pixel applies to current backbuffer
      // TODO: use a next line input port, this incrementer won't work for
      // TODO: use a next line input port, the double buffering delays this data
      // line 0 (which is unused in display.vhd) and could be shared.
      // by an entire scanline.
   assign rowmatch=(expy==y_i+1);
   assign rowmatch=(expy==yout_i);
 
 
   always @(posedge clk_i) begin
   always @(posedge clk_fifo_i) begin
      // Feed incoming exposures into exposure buffer
      // Feed incoming exposures into exposure buffer
 
      // TODO: stop scanning until newline once we're through the entire buffer
      if (exposed) begin
      if (exposed) begin
         exposures[expwptr] <= {expx, expy, expy==yout_i?expi-1:expi};
         exposures[expwptr] <= {expx, expy, expy==yout_i?expi-1:expi};
         expwptr <= expwptr+1;
         expwptr <= expwptr+1;
      end
      end
   end
   end
 
 
   // scanline buffers switch output or expose roles based on bufsel
 
   assign sl0w=bufsel?expx:xout_i;
 
   assign sl1w=bufsel?xout_i:expx;
 
 
 
   always @(posedge clk_i) begin
   // Fron buffer address
 
   assign scanout_addr = {bufsel,xout_i};
 
   assign scanout_clk = clk_video_i;
 
   always @(posedge scanout_clk) begin
 
      // Wipe front buffer
 
      scanlines[scanout_addr] <= wipe_i;
      // Read out front buffer
      // Read out front buffer
      pixelout <= bufsel?scanline1[xout_i]:scanline0[xout_i];
      pixel_o <= scanlines[scanout_addr];
 
   end
 
 
      // Store exposures for next scanline and wipe front buffer
   // Back buffer address
      if (bufsel) begin
   assign lineplot_addr = {~bufsel, expx};
         if (rowmatch)
   assign lineplot_clk = clk_fifo_i;
           scanline0[sl0w] <= expi;
   always @(posedge lineplot_clk) begin
         scanline1[sl1w] <= 0;
      //            pixel_o <= scanlines[lineplot_addr];
      end else begin
      // Store exposures for next scanline
         if (rowmatch)
      if (rowmatch) begin
           scanline1[sl1w] <= expi;
         scanlines[lineplot_addr] <= expi;
         scanline0[sl0w] <= 0;
      end
      end
      end
 
 
 
   always @(posedge clk_video_i) begin
      // swap buffers when signaled
      // swap buffers when signaled
      if (newline_i) begin
      if (newline) begin
         bufsel <= ~bufsel;
         bufsel <= ~bufsel;
      end
      end
   end
   end
 
 
   // output pixel intensity
 
   assign pixel_o = pixelout;
 
 
 
endmodule
endmodule
 
 
 No newline at end of file
 No newline at end of file

powered by: WebSVN 2.1.0

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