-- -- Dalton Project -- Tony Givargis, Rilesh Patel, Deepa Varghese, Roman Lysecky, Puneet Mehra -- 12/29/98 -- Version 1.2 -- Notes: This file implements the CCD PRE PROCESSOR. -- -- This device reads a WIDTHxHEIGHT CCD image with 1 black pixel -- terminating each row of the image. Using this 1 pixels the -- CCD PRE PROCESSOR computes the average 0-bias of the A/D and -- subtracts this ammount from the next row. Consequently the 1 -- pixels is removed from the image. -- -- The CCD PRE PROCESSORS has an 32-bit configuration/status register -- and an 32-bit data register. -- -- IMAGE_READY_REG: -- -- MSB LSB -- --------------------------------------------------------------- -- | NU ..........................................NU | IMAGE_READY | -- --------------------------------------------------------------- -- ^ -- | -- | -- | -- set on completion of acquisition ---------------------- -- -- IMAGE_START_REG: -- -- MSB LSB -- --------------------------------------------------------------- -- | NU .......................................NU | START_NEW_SCAN | -- --------------------------------------------------------------- -- ^ -- | -- | -- set to start image acquisition -------- -- -- DATA_REG: -- -- MSB LSB -- --------------------------------------------------------------- -- | NU .......................................... NU | B/W | -- --------------------------------------------------------------- -- 8-BITS -- -- Each read of this register will return the next pixel of the -- image in scanning from the top, left corner row by row. Reading -- this register beyond the last pixel will return the last pixel. -- --*************************************************************************-- library IEEE; use IEEE.STD_LOGIC_1164.all; use IEEE.STD_LOGIC_ARITH.all; --*************************************************************************-- entity CCD_IN is generic( IMAGE_READY_REG : INTEGER := 512; IMAGE_START_REG : INTEGER := 513; DATA_REG : INTEGER := 514; IMAGE_WIDTH : INTEGER range 1 to 1024 := 16; IMAGE_HEIGHT : INTEGER range 1 to 1024 := 16 ); port( scan_clk : in STD_LOGIC; scan_data : in UNSIGNED(7 downto 0); clk : in STD_LOGIC; rst : in STD_LOGIC; ib_data : inout UNSIGNED(31 downto 0); ib_addr : in UNSIGNED(22 downto 0); ib_rd : in STD_LOGIC; ib_wr : in STD_LOGIC; ib_valid : out STD_LOGIC); end CCD_IN; --*************************************************************************-- architecture BHV_CCD_IN of CCD_IN is -- -- type declarations -- subtype PIXEL_TYPE is UNSIGNED(7 downto 0); type ROW_PIXEL_TYPE is array(0 to IMAGE_WIDTH-1) of PIXEL_TYPE; type IMAGE_TYPE is array(0 to IMAGE_HEIGHT-1) of ROW_PIXEL_TYPE; type STATE_TYPE is (START, GRAB); -- -- constant declarations -- constant Z_32 : UNSIGNED(31 downto 0) := "ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ"; constant C0_32 : UNSIGNED(31 downto 0) := "00000000000000000000000000000000"; constant C0_8 : UNSIGNED(7 downto 0) := "00000000"; constant C0_24 : UNSIGNED(23 downto 0) := "000000000000000000000000"; -- -- signal declarations -- signal row1 : INTEGER range 0 to IMAGE_HEIGHT; signal col1 : INTEGER range 0 to IMAGE_WIDTH; signal row2 : INTEGER range 0 to IMAGE_HEIGHT; signal col2 : INTEGER range 0 to IMAGE_WIDTH; signal image : IMAGE_TYPE; signal bias : UNSIGNED(7 downto 0); signal image_ready : UNSIGNED(31 downto 0); signal image_start : UNSIGNED(31 downto 0); signal state : STATE_TYPE; begin -- -- image capture process -- process(scan_clk, rst) begin if( rst = '1' ) then state <= START; row1 <= 0; col1 <= 0; bias <= C0_8; image_ready <= C0_32; elsif( scan_clk'event and scan_clk = '1' ) then case( state ) is when START => row1 <= 0; col1 <= 0; if( image_start(0) = '1' ) then image_ready(0) <= '0'; state <= GRAB; end if; when GRAB => if( col1 < IMAGE_WIDTH ) then if( row1 < IMAGE_HEIGHT ) then image(row1)(col1) <= scan_data - bias; end if; col1 <= col1 + 1; else if( row1 < IMAGE_HEIGHT ) then col1 <= 0; row1 <= row1 + 1; bias <= scan_data; else image_ready(0) <= '1'; if( image_start(0) = '0' ) then state <= START; end if; end if; end if; end case; end if; end process; -- -- register read/write process -- process(clk, rst) begin if( rst = '1' ) then -- -- steady state -- row2 <= 0; col2 <= 0; ib_data <= Z_32; ib_valid <= '0'; image_start <= C0_32; elsif( clk'event and clk = '1' ) then if( ib_rd = '1' ) then if( ib_addr = conv_integer(IMAGE_READY_REG) ) then ib_data <= image_ready; ib_valid <= '1'; elsif( ib_addr = conv_integer(DATA_REG) ) then -- -- send the current pixel -- ib_data <= C0_24 & image(row2)(col2); ib_valid <= '1'; -- -- move to next pixel -- if( col2 < IMAGE_WIDTH-1 ) then col2 <= col2 + 1; else col2 <= 0; if( row2 if( isa_rd = '1' ) then ib_addr <= isa_addr; ib_rd <= '1'; state <= READ_S; elsif( isa_wr = '1' ) then ib_data <= isa_data; ib_addr <= isa_addr; ib_wr <= '1'; state <= WRITE_S; end if; when READ_S => state <= READ_WAIT_S; when READ_WAIT_S => if( ib_valid = '1' ) then isa_data_read <= ib_data; read_done <= '1'; state <= IDLE_S; else state <= READ_WAIT_S; end if; when WRITE_S => write_done <= '1'; state <= IDLE_S; when others => state <= IDLE_S; end case; end if; end process; -- -- ISA mux process -- process(clk, rst) begin if( rst = '1') then -- -- steady state -- isa_state <= IDLE_ISA_S; isa_data <= C0_32; isa_addr <= C0_23; isa_wr <= '0'; isa_rd <= '0'; iochrdy <= 'Z'; pdata <= Z_8; elsif( clk'event and clk = '1') then -- -- steady state -- isa_wr <= '0'; isa_rd <= '0'; iochrdy <= 'Z'; pdata <= Z_8; case( isa_state ) is when IDLE_ISA_S => if( ale = '1' ) then if( paddr = conv_integer(IMAGE_READY_REG) or paddr = conv_integer(IMAGE_START_REG) or paddr = conv_integer(DATA_REG) ) then isa_addr <= paddr; isa_state <= READ_WRITE_S; else isa_state <= IDLE_ISA_S; end if; else isa_state <= IDLE_ISA_S; end if; when READ_WRITE_S => if( ior = '1' ) then iochrdy <= '0'; isa_rd <= '1'; isa_state <= READ1_S; elsif( iow = '1') then iochrdy <= '0'; isa_addr <= paddr; isa_data(7 downto 0) <= pdata; isa_state <= WRITE1_S; else isa_state <= IDLE_ISA_S; end if; when READ1_S => iochrdy <= '0'; isa_state <= READ1_WAIT_S; when READ1_WAIT_S => if( read_done = '1' ) then iochrdy <= '1'; pdata <= isa_data_read(7 downto 0); isa_state <= READ2_IDLE_S; else iochrdy <= '0'; isa_state <= READ1_WAIT_S; end if; when READ2_IDLE_S => if( ale = '1' ) then if( paddr = isa_addr ) then isa_state <= READ2_CHK_S; elsif( paddr = conv_integer(IMAGE_READY_REG) or paddr = conv_integer(IMAGE_START_REG) or paddr = conv_integer(DATA_REG) ) then isa_addr <= paddr; isa_state <= READ_WRITE_S; else isa_state <= IDLE_ISA_S; end if; else isa_state <= READ2_IDLE_S; end if; when READ2_CHK_S => if( ior = '1' ) then iochrdy <= '0'; isa_state <= READ2_S; elsif( iow = '1') then iochrdy <= '0'; isa_addr <= paddr; isa_data(7 downto 0) <= pdata; isa_state <= WRITE1_S; else isa_state <= IDLE_ISA_S; end if; when READ2_S => iochrdy <= '0'; isa_state <= READ2_WAIT_S; when READ2_WAIT_S => iochrdy <= '1'; pdata <= isa_data_read(15 downto 8); isa_state <= READ3_IDLE_S; when READ3_IDLE_S => if( ale = '1' ) then if( paddr = isa_addr ) then isa_state <= READ3_CHK_S; elsif( paddr = conv_integer(IMAGE_READY_REG) or paddr = conv_integer(IMAGE_START_REG) or paddr = conv_integer(DATA_REG) ) then isa_addr <= paddr; isa_state <= READ_WRITE_S; else isa_state <= IDLE_ISA_S; end if; else isa_state <= READ3_IDLE_S; end if; when READ3_CHK_S => if( ior = '1' ) then iochrdy <= '0'; isa_state <= READ3_S; elsif( iow = '1') then iochrdy <= '0'; isa_addr <= paddr; isa_data(7 downto 0) <= pdata; isa_state <= WRITE1_S; else isa_state <= IDLE_ISA_S; end if; when READ3_S => iochrdy <= '0'; isa_state <= READ3_WAIT_S; when READ3_WAIT_S => iochrdy <= '1'; pdata <= isa_data_read(23 downto 16); isa_state <= READ4_IDLE_S; when READ4_IDLE_S => if( ale = '1' ) then if( paddr = isa_addr ) then isa_state <= READ4_CHK_S; elsif( paddr = conv_integer(IMAGE_READY_REG) or paddr = conv_integer(IMAGE_START_REG) or paddr = conv_integer(DATA_REG) ) then isa_addr <= paddr; isa_state <= READ_WRITE_S; else isa_state <= IDLE_ISA_S; end if; else isa_state <= READ4_IDLE_S; end if; when READ4_CHK_S => if( ior = '1' ) then iochrdy <= '0'; isa_state <= READ4_S; elsif( iow = '1') then iochrdy <= '0'; isa_addr <= paddr; isa_data(7 downto 0) <= pdata; isa_state <= WRITE1_S; else isa_state <= IDLE_ISA_S; end if; when READ4_S => iochrdy <= '0'; isa_state <= READ4_WAIT_S; when READ4_WAIT_S => iochrdy <= '1'; pdata <= isa_data_read(31 downto 24); isa_state <= IDLE_ISA_S; when WRITE1_S => if( iow = '1' ) then iochrdy <= '1'; isa_state <= WRITE1_S; else isa_state <= WRITE2_IDLE_S; end if; when WRITE2_IDLE_S => if( ale = '1' ) then if( paddr = isa_addr ) then isa_state <= WRITE2_CHK_S; elsif( paddr = conv_integer(IMAGE_READY_REG) or paddr = conv_integer(IMAGE_START_REG) or paddr = conv_integer(DATA_REG) ) then isa_addr <= paddr; isa_state <= READ_WRITE_S; else isa_state <= IDLE_ISA_S; end if; else isa_state <= WRITE2_IDLE_S; end if; when WRITE2_CHK_S => if( ior = '1' ) then iochrdy <= '0'; isa_rd <= '1'; isa_state <= READ1_S; elsif( iow = '1') then iochrdy <= '0'; isa_data(15 downto 8) <= pdata; isa_state <= WRITE2_S; else isa_state <= IDLE_ISA_S; end if; when WRITE2_S => if( iow = '1' ) then iochrdy <= '1'; isa_state <= WRITE2_S; else isa_state <= WRITE3_IDLE_S; end if; when WRITE3_IDLE_S => if( ale = '1' ) then if( paddr = isa_addr ) then isa_state <= WRITE3_CHK_S; elsif( paddr = conv_integer(IMAGE_READY_REG) or paddr = conv_integer(IMAGE_START_REG) or paddr = conv_integer(DATA_REG) ) then isa_addr <= paddr; isa_state <= READ_WRITE_S; else isa_state <= IDLE_ISA_S; end if; else isa_state <= WRITE3_IDLE_S; end if; when WRITE3_CHK_S => if( ior = '1' ) then iochrdy <= '0'; isa_rd <= '1'; isa_state <= READ1_S; elsif( iow = '1') then iochrdy <= '0'; isa_data(23 downto 16) <= pdata; isa_state <= WRITE3_S; else isa_state <= IDLE_ISA_S; end if; when WRITE3_S => if( iow = '1' ) then iochrdy <= '1'; isa_state <= WRITE3_S; else isa_state <= WRITE4_IDLE_S; end if; when WRITE4_IDLE_S => if( ale = '1' ) then if( paddr = isa_addr ) then isa_state <= WRITE4_CHK_S; elsif( paddr = conv_integer(IMAGE_READY_REG) or paddr = conv_integer(IMAGE_START_REG) or paddr = conv_integer(DATA_REG) ) then isa_addr <= paddr; isa_state <= READ_WRITE_S; else isa_state <= IDLE_ISA_S; end if; else isa_state <= WRITE4_IDLE_S; end if; when WRITE4_CHK_S => if( ior = '1' ) then iochrdy <= '0'; isa_rd <= '1'; isa_state <= READ1_S; elsif( iow = '1') then iochrdy <= '0'; isa_data(31 downto 24) <= pdata; isa_wr <= '1'; isa_state <= WRITE4_S; else isa_state <= IDLE_ISA_S; end if; when WRITE4_S => iochrdy <= '0'; if( write_done = '1' ) then isa_state <= WRITE4_WAIT_S; else isa_state <= WRITE4_S; end if; when WRITE4_WAIT_S => if( iow = '1' ) then iochrdy <= '1'; isa_state <= WRITE4_WAIT_S; else isa_state <= IDLE_ISA_S; end if; when others => isa_state <= IDLE_ISA_S; end case; end if; end process; end BHV_CCD_IM; --*************************************************************************-- library IEEE; use IEEE.STD_LOGIC_1164.all; use IEEE.STD_LOGIC_ARITH.all; --*************************************************************************-- entity CCD is generic( IMAGE_READY_REG : INTEGER := 512; IMAGE_START_REG : INTEGER := 513; DATA_REG : INTEGER := 514; IMAGE_WIDTH : INTEGER range 1 to 1024 := 16; IMAGE_HEIGHT : INTEGER range 1 to 1024 := 16); port( scan_clk : in STD_LOGIC; scan_data : in UNSIGNED(7 downto 0); clk : in STD_LOGIC; rst : in STD_LOGIC; pdata : inout UNSIGNED(7 downto 0); paddr : in UNSIGNED(22 downto 0); ior : in STD_LOGIC; iow : in STD_LOGIC; ale : in STD_LOGIC; iochrdy : out STD_LOGIC ); end CCD; --*************************************************************************-- architecture STR_CCD of CCD is -- -- component declarations -- component CCD_IN generic( IMAGE_READY_REG : INTEGER := 512; IMAGE_START_REG : INTEGER := 513; DATA_REG : INTEGER := 514; IMAGE_WIDTH : INTEGER range 1 to 1024 := 16; IMAGE_HEIGHT : INTEGER range 1 to 1024 := 16 ); port( scan_clk : in STD_LOGIC; scan_data : in UNSIGNED(7 downto 0); clk : in STD_LOGIC; rst : in STD_LOGIC; ib_data : inout UNSIGNED(31 downto 0); ib_addr : in UNSIGNED(22 downto 0); ib_rd : in STD_LOGIC; ib_wr : in STD_LOGIC; ib_valid : out STD_LOGIC ); end component; component CCD_IM generic( IMAGE_READY_REG : INTEGER := 512; IMAGE_START_REG : INTEGER := 513; DATA_REG : INTEGER := 514 ); port( clk : in STD_LOGIC; rst : in STD_LOGIC; pdata : inout UNSIGNED(7 downto 0); paddr : in UNSIGNED(22 downto 0); ior : in STD_LOGIC; iow : in STD_LOGIC; ale : in STD_LOGIC; iochrdy : out STD_LOGIC; ib_data : inout UNSIGNED(31 downto 0); ib_addr : out UNSIGNED(22 downto 0); ib_rd : out STD_LOGIC; ib_wr : out STD_LOGIC; ib_valid : in STD_LOGIC ); end component; -- -- component configurations -- for all : CCD_IN use entity WORK.CCD_IN(BHV_CCD_IN); for all : CCD_IM use entity WORK.CCD_IM(BHV_CCD_IM); -- -- signals -- signal ib_data : UNSIGNED(31 downto 0); signal ib_addr : UNSIGNED(22 downto 0); signal ib_rd : STD_LOGIC; signal ib_wr : STD_LOGIC; signal ib_valid : STD_LOGIC; begin -- -- component instantiations -- U1 : CCD_IN generic map( IMAGE_READY_REG, IMAGE_START_REG, DATA_REG, IMAGE_WIDTH, IMAGE_HEIGHT ) port map( scan_clk, scan_data, clk, rst, ib_data, ib_addr, ib_rd, ib_wr, ib_valid ); U2 : CCD_IM generic map( IMAGE_READY_REG, IMAGE_START_REG, DATA_REG ) port map( clk, rst, pdata, paddr, ior, iow, ale, iochrdy, ib_data, ib_addr, ib_rd, ib_wr, ib_valid ); end STR_CCD; --*************************************************************************-- configuration CFG_CCD of CCD is for STR_CCD end for; end CFG_CCD; --*************************************************************************-- -- end of file --