/////////////////////////////////////////////////////////////////////
//// ////
//// LWB rev 1.2 -- SAA7113 Control Logic ////
//// ////
//// ////
//// Author: Liu Tao ////
//// liutao94@tsinghua.org.cn ////
//// ////
//// ////
//// ////
/////////////////////////////////////////////////////////////////////
//// ////
//// Copyright (C) 2003 Liu Tao ////
//// liutao94@tsinghua.org.cn ////
//// ////
//// ////
/////////////////////////////////////////////////////////////////////
`include "timescale.v"
module LWBSAA7113 (reset,clk,llck,vpo,rst,capture,error,SRAM_CE_,SRAM_OE_,SRAM_WE_,la,ld);
//=================================================================================
//input
//=================================================================================
/*___________________________________________________ */
//reset
input reset;//
/*___________________________________________________ */
//from saa7113
input clk;//50MHz clock
input llck;//SAA7113 video clock (27 MHz)
input [7:0] vpo;//data from SAA7113
input [1:0] rst;//real-time video status
input capture;//flag for grab video data
//=================================================================================
//output
//=================================================================================
/*___________________________________________________ */
//to sram
output error;//state indicator,to LED
output SRAM_CE_;
output SRAM_OE_;
output SRAM_WE_;
output [18:0] la;//address bus to sram
output [7:0] ld;//data bus to sram
//=================================================================================
//reg
//=================================================================================
/*___________________________________________________ */
//video in state machine declaration
reg [3:0] presState;//
reg [3:0] nextState;//
reg [3:0] returnState;
reg [3:0] nextReturnState;
//=================================================================================
//parameters
//=================================================================================
/*___________________________________________________ */
//state declaration
parameter stIdle = 4'b0000;//IDLE STATE,START UP OF A STATE MACHINE,RESET
parameter stWaitForEscape = 4'b0001;//CHECK FOR "FF",START OF TIMING REFERENCE CODE
parameter stCheckEscape1 = 4'b0010;//CHECK FOR "00",SECOND
parameter stCheckEscape2 = 4'b0011;//CHECK FOR "00",THIRD
parameter stCheckForNewPage = 4'b0100;//CHECK FOR "01",It is in vertical blanking stage,
parameter stCheckForFirstLine = 4'b0101;//CHECK FOR "000",for SAV in valid row
parameter stChromaBlue = 4'b0110;//write Cb to sram,here not in use
parameter stLumaBlue = 4'b0111;//write Lb to sram
parameter stChromaRed = 4'b1000;//write Cr to sram,not in use
parameter stLumaRed = 4'b1001;//write Lr to sram,
parameter stCheckForEndLine = 4'b1010;//CHECK for end of line
parameter stCheckForNewLine = 4'b1011;//CHECK for new line
parameter stError = 4'b1100;//ERROR state
//=================================================================================
//wires
//=================================================================================
/*___________________________________________________ */
//vpo data from saa7113
reg [7:0] vpoLatch;//synchronise data on the vpo bus to LLCK
reg [7:0] luminanceB;
reg [7:0] luminanceR;
reg [7:0] chrominanceB;//not use now
reg [7:0] chrominanceR;//not use now
reg [7:0] nextLuminanceB;
reg [7:0] nextLuminanceR;
reg [7:0] nextChrominanceB;//not use now
reg [7:0] nextChrominanceR;//not use now
reg [8:0] grab_cntr_hori;//counter for horizon 720
reg [8:0] grab_cntr_vert;//counter for vertical 286
reg clr_grab_cntr;//clear both grab counters
reg inc_grab_hori;//increment horizontal counter for each 2 pixels
reg inc_grab_vert;//increment vertical counter and clear horizontal counter
reg field;//0 for 1st field,1 for 2nd field
reg nextField;//remember next field
reg grab;//write current data
reg nextGrab;
wire [18:0] grab_addr;
reg [18:0] write_addr;
reg [7:0] writeData;
reg write;
reg lastwrite;
reg dowrite;
// reg capture;//
reg error;
//=================================================================================
//hookup sram interface
//=================================================================================
/*___________________________________________________ */
//address
LWBSRAM L_SRAM (
.clk(clk),
.reset(reset),
.doWrite(dowrite),
.writeAddr(write_addr),
.writeData(writeData),
.SRAM_CE_(SRAM_CE_),
.SRAM_OE_(SRAM_OE_),
.SRAM_WE_(SRAM_WE_),
.SRAM_ADDR(la),
.SRAM_DATA(ld)
);
//=================================================================================
//Assigning
//=================================================================================
/*___________________________________________________ */
//address
assign grab_addr = {grab_cntr_vert,field,grab_cntr_hori};
//colour calculations: these have not been fully tested and may need to be edited
//These convert the YUV data to RGB
// red = ("00" & luminanceB & x"00") + (("01" & x"24") * chrominanceR) - ("00" & x"7D00");
// blue // green
//=================================================================================
//State Machine
//=================================================================================
/*___________________________________________________ */
//write data to sram
/*___________________________________________________ */
//write data to sram
always @(posedge llck or negedge reset)
if (!reset)
begin
presState grab returnState field grab_cntr_hori grab_cntr_vert
end
else
begin
vpoLatch presState grab
returnState field chrominanceR chrominanceB luminanceR luminanceB
if (nextGrab)
write_addr
if (grab) //note that this is executed 1 cycle after nextGrab is seen to go high.
begin
// writeData writeData write end
else
write
// operate on the grab counters for vertical and horizontal movement
if (clr_grab_cntr)
begin
grab_cntr_hori grab_cntr_vert end
else
if (inc_grab_hori == 1)
grab_cntr_hori
if (inc_grab_vert == 1)
begin
grab_cntr_vert grab_cntr_hori end
end
/*___________________________________________________ */
//grab data from vpo bus
always @(presState or vpoLatch or returnState or field or luminanceB or luminanceR or chrominanceB or chrominanceR or capture)
begin
//default signal values
clr_grab_cntr inc_grab_hori inc_grab_vert
nextGrab
nextReturnState nextField nextLuminanceB nextLuminanceR nextChrominanceB nextChrominanceR
error
//state machine
case (presState)
stIdle://
if (capture == 1'b1)
begin
nextState nextReturnState end
else
nextState
stWaitForEscape://Look for the first character in the sequence, keep looking until found
if (vpoLatch == 8'hFF)
nextState else
nextState
stCheckEscape1://Second character in the escape sequence is 0
if (vpoLatch == 8'h00)
nextState else
nextState
stCheckEscape2://Third charcter in the escape sequence is 0. Go to returnState to check SAV/EAV code
if (vpoLatch == 8'h00)
nextState else
nextState
stCheckForNewPage://Wait for an SAV or EAV in field 0 while in the vertical blanking stage
if (vpoLatch[6:5] == 2'b01) //If it is then wait until the first line of active video
begin
nextState nextReturnState clr_grab_cntr end
else //Look for another SAV/EAV until we find the type we want.
begin
nextState nextReturnState end
stCheckForFirstLine://Wait for an SAV in field 0 while in the active video region
if (vpoLatch[6:4] == 3'b000) //start recording data
begin
nextState nextField end
else //Look for another SAV/EAV until we find the type we want.
begin
nextState nextReturnState end
stChromaBlue://This may be the start of another pair of pixels or the end of data
if (vpoLatch == 8'hFF) //If the byte is FF then it is the start of the EAV.
begin
nextState nextReturnState end
else if (vpoLatch == 8'h00)
nextState else //latch data into register and continue
begin
nextState nextChrominanceB end
stLumaBlue://As long as valid data is present continue latching data
if ((vpoLatch !== 8'hFF) && (vpoLatch !== 8'h00))
begin
nextState nextLuminanceB end
else
nextState
stChromaRed://As long as valid data is present continue latching data
if ((vpoLatch !== 8'hFF) && (vpoLatch !== 8'h00))
begin
nextState nextChrominanceR end
else
nextState
stLumaRed://As long as valid data is present continue latching data and setup to write current data
if ((vpoLatch !== 8'hFF) && (vpoLatch !== 8'h00))
begin
nextState nextLuminanceR nextGrab inc_grab_hori end
else
nextState
stCheckForEndLine://possible conditions here are the end of field 0, end of field 1,or an EAV code indicating a new line in the active region.
if (vpoLatch[6:4] == 3'b111) //end of field 1
nextState else if (vpoLatch[6:4] == 3'b011) //end of field 0
begin
clr_grab_cntr nextState nextReturnState end
else if (vpoLatch[5:4] == 2'b01) //end of line
begin
inc_grab_vert nextState nextReturnState end
else // EAV expected but SAV received
nextState
stCheckForNewLine://Wait until an SAV in the active video range arrives
if (vpoLatch[5:4] == 2'b00)
begin
nextState nextField end
else // Wait for another code
begin
nextState nextReturnState end
stError://Wait until another capture is requested before continuing
if (capture == 1'b1)
begin
nextState nextReturnState end
else
begin
nextState error end
default:
nextState
endcase
end
/*___________________________________________________ */
//synchronizes writes to the 50MHz clock
always @(negedge reset or posedge clk)
if(!reset)
begin
dowrite lastwrite end
else
begin
lastwrite if (!write && lastwrite)
dowrite else
dowrite
end
endmodule