📄 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 //////// //////// /////////////////////////////////////////////////////////////////////////`timescale 1ns / 10psmodule 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; endendmodule
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -