📄 lwbsaa7113.v
字号:
/////////////////////////////////////////////////////////////////////
//// ////
//// 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 <= ("00" & luminanceB & x"00") + (("10" & x"07") * chrominanceB) - ("00" & x"EE80");
// green <= ("00" & luminanceB & x"00") + ("00" & x"9200") - (("00" & x"65") * chrominanceB) - (("00" & x"95") * chrominanceR);
//=================================================================================
//State Machine
//=================================================================================
/*___________________________________________________ */
//write data to sram
/*___________________________________________________ */
//write data to sram
always @(posedge llck or negedge reset)
if (!reset)
begin
presState <= stIdle;
grab <= 1'b0;
returnState <= stIdle;
field <= 1'b0;
grab_cntr_hori <= 1'b0;
grab_cntr_vert <= 1'b0;
end
else
begin
vpoLatch <= vpo;//synchronize asynchronous data
presState <= nextState;// go to next state
grab <= nextGrab;//delay so colour can be calculated
returnState <= nextReturnState;
field <= nextField;
chrominanceR <= nextChrominanceR;
chrominanceB <= nextChrominanceB;
luminanceR <= nextLuminanceR;
luminanceB <= nextLuminanceB;
if (nextGrab)
write_addr <= grab_addr;//give write address plenty of setup time
if (grab) //note that this is executed 1 cycle after nextGrab is seen to go high.
begin
// writeData <= '0' & colour; -- high colour (15 bit) full colour. 360 double pixels wide.
writeData <= luminanceR;
write <= 1'b1;
end
else
write <= 1'b0;
// operate on the grab counters for vertical and horizontal movement
if (clr_grab_cntr)
begin
grab_cntr_hori <= 1'b0;
grab_cntr_vert <= 1'b0;
end
else
if (inc_grab_hori == 1)
grab_cntr_hori <= grab_cntr_hori + 1;
if (inc_grab_vert == 1)
begin
grab_cntr_vert <= grab_cntr_vert + 1;
grab_cntr_hori <= 1'b0; // clear horizontal counter with each new line
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 <= 1'b0;
inc_grab_hori <= 1'b0;
inc_grab_vert <= 1'b0;
nextGrab <= 1'b0;
nextReturnState <= returnState;
nextField <= field;
nextLuminanceB <= luminanceB;
nextLuminanceR <= luminanceR;
nextChrominanceB <= chrominanceB;
nextChrominanceR <= chrominanceR;
error <= 1'b0;
//state machine
case (presState)
stIdle://
if (capture == 1'b1)
begin
nextState <= stWaitForEscape; // Look for an escape sequence
nextReturnState <= stCheckForNewPage;// Check for start of field 0
end
else
nextState <= stIdle;
stWaitForEscape://Look for the first character in the sequence, keep looking until found
if (vpoLatch == 8'hFF)
nextState <= stCheckEscape1;
else
nextState <= stWaitForEscape;
stCheckEscape1://Second character in the escape sequence is 0
if (vpoLatch == 8'h00)
nextState <= stCheckEscape2;
else
nextState <= stError;
stCheckEscape2://Third charcter in the escape sequence is 0. Go to returnState to check SAV/EAV code
if (vpoLatch == 8'h00)
nextState <= returnState;
else
nextState <= stError;
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 <= stWaitForEscape;
nextReturnState <= stCheckForFirstLine;
clr_grab_cntr <= 1'b1;//initialise counter
end
else //Look for another SAV/EAV until we find the type we want.
begin
nextState <= stWaitForEscape;
nextReturnState <= stCheckForNewPage;
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 <= stChromaBlue;
nextField <= 1'b0;//initialise field
end
else //Look for another SAV/EAV until we find the type we want.
begin
nextState <= stWaitForEscape;
nextReturnState <= stCheckForFirstLine;
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 <= stCheckEscape1;//Go to second state of subroutine
nextReturnState <= stCheckForEndLine;//Check if this is the last line of the field
end
else if (vpoLatch == 8'h00)
nextState <= stError;
else //latch data into register and continue
begin
nextState <= stLumaBlue;
nextChrominanceB <= vpoLatch;
end
stLumaBlue://As long as valid data is present continue latching data
if ((vpoLatch !== 8'hFF) && (vpoLatch !== 8'h00))
begin
nextState <= stChromaRed;
nextLuminanceB <= vpoLatch;
end
else
nextState <= stError;
stChromaRed://As long as valid data is present continue latching data
if ((vpoLatch !== 8'hFF) && (vpoLatch !== 8'h00))
begin
nextState <= stLumaRed;
nextChrominanceR <= vpoLatch;
end
else
nextState <= stError;
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 <= stChromaBlue;
nextLuminanceR <= vpoLatch;
nextGrab <= 1'b1;//Set up a write after a delay (see clocked process)
inc_grab_hori <= 1'b1;//Increment horizontal counter every two pixels
end
else
nextState <= stError;
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 <= stIdle;
else if (vpoLatch[6:4] == 3'b011) //end of field 0
begin
clr_grab_cntr <= 1'b1;//reset counter for field 1
nextState <= stWaitForEscape;
nextReturnState <= stCheckForNewLine;//start capture at first new line
end
else if (vpoLatch[5:4] == 2'b01) //end of line
begin
inc_grab_vert <= 1'b1; // go to next line
nextState <= stWaitForEscape;
nextReturnState <= stCheckForNewLine;//capture next line from start
end
else // EAV expected but SAV received
nextState <= stError;
stCheckForNewLine://Wait until an SAV in the active video range arrives
if (vpoLatch[5:4] == 2'b00)
begin
nextState <= stChromaBlue;// capture next line
nextField <= vpoLatch[6];
end
else // Wait for another code
begin
nextState <= stWaitForEscape;
nextReturnState <= stCheckForNewLine;
end
stError://Wait until another capture is requested before continuing
if (capture == 1'b1)
begin
nextState <= stWaitForEscape;
nextReturnState <= stCheckForNewPage;
end
else
begin
nextState <= stError;
error <= 1'b1;//indicate error on error LED
end
default:
nextState <= stError;
endcase
end
/*___________________________________________________ */
//synchronizes writes to the 50MHz clock
always @(negedge reset or posedge clk)
if(!reset)
begin
dowrite <= 1'b0;
lastwrite <= 1'b0;
end
else
begin
lastwrite <= write;
if (!write && lastwrite)
dowrite <= 1'b1;
else
dowrite <= 1'b0;
end
endmodule
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -