//
// File: ntsc2zbt.v
// Date: 27-Nov-05
// Author: I. Chuang <ichuang@mit.edu>
//
// Example for MIT 6.111 labkit showing how to prepare NTSC data
// (from Javier's decoder) to be loaded into the ZBT RAM for video
// display.
//
// The ZBT memory is 36 bits wide; we only use 32 bits of this, to
// store 4 bytes of black-and-white intensity data from the NTSC
// video input.
/////////////////////////////////////////////////////////////////////////////
// Prepare data and address values to fill ZBT memory with NTSC data
module ntsc_to_zbt(clk, vclk, fvh, dv, din, ntsc_addr, ntsc_data, ntsc_we, sw);
input clk; // system clock
input vclk; // video clock from camera
input [2:0] fvh;
input dv;
input [7:0] din;
output [18:0] ntsc_addr;
output [35:0] ntsc_data;
output ntsc_we; // write enable for NTSC data
input sw; // switch which determines mode (for debugging)
parameter COL_START = 10'd30;
parameter ROW_START = 10'd30;
// here put the luminance data from the ntsc decoder into the ram
// this is for 1024 x 768 XGA display
reg [9:0] col = 0;
reg [9:0] row = 0;
reg [7:0] vdata = 0;
reg vwe;
reg old_dv;
reg old_frame; // frames are even / odd interlaced
reg even_odd; // decode interlaced frame to this wire
wire frame = fvh[2];
wire frame_edge = frame & ~old_frame;
always @ (posedge vclk) //LLC1 is reference
begin
old_dv <= dv;
vwe <= dv && !fvh[2] & ~old_dv; // if data valid, write it
old_frame <= frame;
even_odd = frame_edge ? ~even_odd : even_odd;
if (!fvh[2])
begin
col <= fvh[0] ? COL_START :
(!fvh[2] && !fvh[1] && dv && (col < 1024)) ? col + 1 : col;
row <= fvh[1] ? ROW_START :
(!fvh[2] && fvh[0] && (row < 768)) ? row + 1 : row;
vdata <= (dv && !fvh[2]) ? din : vdata;
end
end
// synchronize with system clock
reg [9:0] x[1:0],y[1:0];
reg [7:0] data[1:0];
reg we[1:0];
reg eo[1:0];
always @(posedge clk)
begin
{x[1],x[0]} <= {x[0],col};
{y[1],y[0]} <= {y[0],row};
{data[1],data[0]} <= {data[0],vdata};
{we[1],we[0]} <= {we[0],vwe};
{eo[1],eo[0]} <= {eo[0],even_odd};
end
// edge detection on write enable signal
reg old_we;
wire we_edge = we[1] & ~old_we;
always @(posedge clk) old_we <= we[1];
// shift each set of four bytes into a large register for the ZBT
reg [31:0] mydata;
always @(posedge clk)
if (we_edge)
mydata <= { mydata[23:0], data[1] };
// compute address to store data in
wire [18:0] myaddr = {1'b0, y[1][8:0], eo[1], x[1][9:2]};
// alternate (256x192) image data and address
wire [31:0] mydata2 = {data[1],data[1],data[1],data[1]};
wire [18:0] myaddr2 = {1'b0, y[1][8:0], eo[1], x[1][7:0]};
// update the output address and data only when four bytes ready
reg [18:0] ntsc_addr;
reg [35:0] ntsc_data;
wire ntsc_we = sw ? we_edge : (we_edge & (x[1][1:0]==2'b00));
always @(posedge clk)
if ( ntsc_we )
begin
ntsc_addr <= sw ? myaddr2 : myaddr; // normal and expanded modes
ntsc_data <= sw ? {4'b0,mydata2} : {4'b0,mydata};
end
endmodule // ntsc_to_zbt
This page: |
Created: | Thu Dec 8 21:40:00 2005 |
|
From: |
./ntsc2zbt.v |