Here's my code Dave. At first I used nested if statements but later I
scraped it and test the conditions all together (maybe timing issue
contributing because of nested if statements) in the hopes making it
work. Sorry for the lack of comments on the code, but basically the
state machine has to check for rise time in FRAME_VALID and LINE_VALID
and also fall time in PIXCLK when Rin is activated (Rin is the signal
from CPU saying it needs data from CMOS).
Once that is achieved I am supposed to latch the incoming data from
DataCMOS bus to the memory, but for now, I just incremented a counter
to show that I have saved one additional pixel of data. Also after
collecting 8 data, it supposed to go to state StoreDone and remain
there until reset (debugging purposes).
I have not used ModelSim but I used the simulator tool given within
Altera's Quartus II software. It works fine there. Is it the same
thing? Also the datasheet of the CMOS sensor can be found in
http://download.micron.com/pdf/datasheets/imaging/mt9m001_1300_mono.pdf.
Thanks for all your help. Hope to hear from you soon.
Mugilan
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.all;
USE IEEE.STD_LOGIC_ARITH.all;
USE IEEE.STD_LOGIC_UNSIGNED.all;
LIBRARY ALTERA_MF;
LIBRARY LPM;
USE ALTERA_MF.ALTERA_MF_COMPONENTS.ALL;
USE LPM.LPM_COMPONENTS.ALL;
entity TestState is
PORT (
-- Input ports
reset,
clock,
--GetData,
--ReadSuc,
PIXCLK, -- At falling edge valid data from DataCMOS can be
stored
FRAME_VALID, -- At rising edge, data from 1st active pixel
LINE_VALID, -- At LINE_VALID high, active row of pixels
Rin : IN STD_LOGIC;
DataCMOS : IN STD_LOGIC_VECTOR(7 DOWNTO 0);
-- Output ports
DataOut: OUT STD_LOGIC_VECTOR(7 DOWNTO 0);
InitialState,
GetTransState,
FCheckState,
LCheckState,
PCheckState,
StoreState,
StoreDoneState: OUT STD_LOGIC;
DONE: OUT STD_LOGIC
);
end TestState;
ARCHITECTURE A OF TestState IS
TYPE STATE_TYPE IS (Initial, GetTrans, FCheck, LCheck, PCheck,
Store, StoreDone);
SIGNAL state : STATE_TYPE;
--SIGNAL complete : STD_LOGIC;
Signal Rinternal : STD_LOGIC;
Signal F_Rising : STD_LOGIC;
Signal L_Rising : STD_LOGIC;
Signal P_Fall : STD_LOGIC;
Signal wrena : STD_LOGIC;
Signal wrenb : STD_LOGIC;
--SIGNAL Counter1 : STD_LOGIC_VECTOR(2 DOWNTO 0);
--SIGNAL Test1 : STD_LOGIC_VECTOR(2 DOWNTO 0);
SIGNAL Memadda : STD_LOGIC_VECTOR(9 DOWNTO 0);
SIGNAL Memaddb : STD_LOGIC_VECTOR(9 DOWNTO 0);
SIGNAL Counter : STD_LOGIC_VECTOR(10 DOWNTO 0);
SIGNAL DataCMOSInternal : STD_LOGIC_VECTOR(7 DOWNTO 0);
SIGNAL DataOutInternal : STD_LOGIC_VECTOR(7 DOWNTO 0);
BEGIN
-- MEMORY : altsyncram
-- GENERIC MAP (
-- intended_device_family => "Cyclone II",
-- width_a => 8,
-- widthad_a => 10,
-- numwords_a => 1024,
-- operation_mode => "SINGLE_PORT",
-- outdata_reg_a => "UNREGISTERED",
-- indata_aclr_a => "NONE",
-- wrcontrol_aclr_a => "NONE",
-- address_aclr_a => "NONE",
-- outdata_aclr_a => "NONE",
-- init_file => "SDStateMachineExample.mif",
-- lpm_hint => "ENABLE_RUNTIME_MOD=NO",
-- lpm_type => "altsyncram"
-- )
-- PORT MAP (
-- wren_a => MW,
-- clock0 => NOT(CLOCK),
-- address_a => MemAdd,
-- data_a => DataCMOSInternal,
-- q_a => DataOutInternal
-- );
Memory: altsyncram
GENERIC MAP
(OPERATION_MODE => "BIDIR_DUAL_PORT", --
"BIDIR_DUAL_PORT";
WIDTH_A => 8, -- 1;
WIDTHAD_A => 10, -- 1;
NUMWORDS_A => 1024, -- 1;
OUTDATA_REG_A => "UNREGISTERED",
ADDRESS_ACLR_A => "NONE",
OUTDATA_ACLR_A => "NONE",
INDATA_ACLR_A => "NONE",
WRCONTROL_ACLR_A => "NONE",
--BYTEENA_ACLR_A : STRING := "NONE";
--WIDTH_BYTEENA_A : INTEGER := 1;
WIDTH_B => 8, -- 1;
WIDTHAD_B => 10, -- 1;
NUMWORDS_B => 1024, -- 1;
RDCONTROL_REG_B => "CLOCK0",
ADDRESS_REG_B => "CLOCK0",
INDATA_REG_B => "CLOCK0",
WRCONTROL_WRADDRESS_REG_B => "CLOCK0",
--BYTEENA_REG_B : STRING := "CLOCK1";
OUTDATA_REG_B => "UNREGISTERED",
OUTDATA_ACLR_B => "NONE",
RDCONTROL_ACLR_B => "NONE",
INDATA_ACLR_B => "NONE",
WRCONTROL_ACLR_B => "NONE",
ADDRESS_ACLR_B => "NONE",
--BYTEENA_ACLR_B : STRING := "NONE";
--WIDTH_BYTEENA_B : INTEGER := 1;
--BYTE_SIZE : INTEGER := 8;
READ_DURING_WRITE_MODE_MIXED_PORTS => "DONT_CARE",
--RAM_BLOCK_TYPE => "AUTO";
--INIT_FILE : STRING := "UNUSED";
--INIT_FILE_LAYOUT : STRING := "PORT_A";
--MAXIMUM_DEPTH : INTEGER := 0;
INTENDED_DEVICE_FAMILY => "CYCLONE II",
LPM_HINT => "BOGUS",
lpm_type => "altsyncram")
PORT MAP(
clock0 => NOT(clock),
--Port A
wren_a => wrena,
address_a => MemAdda,
data_a => DataCMOSInternal,
--q_a => BogusLinesA,
--PortB
wren_b => wrenb,
address_b => MemAddb,
--data_b => BogusLinesB,
q_b => DataOutInternal
);
DataCMOSInternal <= DataCMOS;
DataOut <= DataOutInternal;
--Rinternal <= Rin;
Main : PROCESS (clock, reset)
BEGIN
IF reset = '1' THEN
--Rinternal <= '0';
state <= Initial; -- Initial to this state
ELSIF clock'EVENT AND clock = '1' THEN
CASE state IS -- Case statement to determine next state logic
WHEN Initial =>
------------------------------
------Define Parameters-------
F_Rising <= '0';
L_Rising <= '0';
P_Fall <= '0';
Counter <= "00000000000";
------------------------------
Case Rin IS
WHEN '0' => state <= Initial;
WHEN '1' => state <= GetTrans;
WHEN OTHERS => state <= Initial;
END CASE;
WHEN GetTrans =>
IF Rin = '1' THEN
F_Rising <= FRAME_VALID;
L_Rising <= LINE_VALID;
P_Fall <= PIXCLK;
state <= FCheck;
ELSE
state <= Initial;
END IF;
WHEN FCheck =>
IF Rin = '1' AND F_Rising = '0' AND FRAME_VALID
= '1' THEN
F_Rising <= FRAME_VALID;
L_Rising <= LINE_VALID;
P_Fall <= PIXCLK;
state <= LCheck;
ELSIF Rin = '1' AND F_Rising = '0' AND
FRAME_VALID = '0' THEN
F_Rising <= FRAME_VALID;
L_Rising <= LINE_VALID;
P_Fall <= PIXCLK;
state <= FCheck;
ELSIF Rin = '1' AND F_Rising = '1' AND
FRAME_VALID = '0' THEN
F_Rising <= FRAME_VALID;
L_Rising <= LINE_VALID;
P_Fall <= PIXCLK;
state <= FCheck;
ELSIF Rin = '1' AND F_Rising = '1' AND
FRAME_VALID = '1' THEN
F_Rising <= FRAME_VALID;
L_Rising <= LINE_VALID;
P_Fall <= PIXCLK;
state <= FCheck;
ELSE
state <= Initial;
END IF;
WHEN LCHECK =>
IF Rin = '1' AND FRAME_VALID = '1' AND L_Rising
= '0' AND
LINE_VALID = '1' THEN
F_Rising <= FRAME_VALID;
L_Rising <= LINE_VALID;
P_Fall <= PIXCLK;
state <= PCheck; --PCheck
ELSIF Rin = '1' AND FRAME_VALID = '1' AND
L_Rising = '0' AND
LINE_VALID = '0' THEN
F_Rising <= FRAME_VALID;
L_Rising <= LINE_VALID;
P_Fall <= PIXCLK;
state <= LCheck;
ELSIF Rin = '1' AND FRAME_VALID = '1' AND
L_Rising = '1' AND
LINE_VALID = '0' THEN
F_Rising <= FRAME_VALID;
L_Rising <= LINE_VALID;
P_Fall <= PIXCLK;
state <= LCheck;
ELSIF Rin = '1' AND FRAME_VALID = '1' AND
L_Rising = '1' AND
LINE_VALID = '1' THEN
F_Rising <= FRAME_VALID;
L_Rising <= LINE_VALID;
P_Fall <= PIXCLK;
state <= LCheck;
ELSE
state <= Initial;
END IF;
WHEN PCheck =>
IF Rin = '1' AND FRAME_VALID = '1' AND
LINE_VALID = '1' AND P_Fall
= '1' AND PIXCLK = '0' THEN
F_Rising <= FRAME_VALID;
L_Rising <= LINE_VALID;
P_Fall <= PIXCLK;
Counter <= Counter + 1;
state <= Store; --PCheck
ELSIF Rin = '1' AND FRAME_VALID = '1' AND
LINE_VALID = '1' AND
P_Fall = '0' AND PIXCLK = '0' THEN
F_Rising <= FRAME_VALID;
L_Rising <= LINE_VALID;
P_Fall <= PIXCLK;
state <= PCheck;
ELSIF Rin = '1' AND FRAME_VALID = '1' AND
LINE_VALID = '1' AND
P_Fall = '0' AND PIXCLK = '1' THEN
F_Rising <= FRAME_VALID;
L_Rising <= LINE_VALID;
P_Fall <= PIXCLK;
state <= PCheck;
ELSIF Rin = '1' AND FRAME_VALID = '1' AND
LINE_VALID = '1' AND
P_Fall = '1' AND PIXCLK = '1' THEN
F_Rising <= FRAME_VALID;
L_Rising <= LINE_VALID;
P_Fall <= PIXCLK;
state <= PCheck;
ELSIF Rin = '1' AND FRAME_VALID = '1' AND
LINE_VALID = '0' AND
P_Fall = '0' AND PIXCLK = '0' THEN
F_Rising <= FRAME_VALID;
L_Rising <= LINE_VALID;
P_Fall <= PIXCLK;
state <= LCheck;
ELSIF Rin = '1' AND FRAME_VALID = '1' AND
LINE_VALID = '0' AND
P_Fall = '0' AND PIXCLK = '1' THEN
F_Rising <= FRAME_VALID;
L_Rising <= LINE_VALID;
P_Fall <= PIXCLK;
state <= LCheck;
ELSIF Rin = '1' AND FRAME_VALID = '1' AND
LINE_VALID = '0' AND
P_Fall = '1' AND PIXCLK = '0' THEN
F_Rising <= FRAME_VALID;
L_Rising <= LINE_VALID;
P_Fall <= PIXCLK;
state <= LCheck;
ELSIF Rin = '1' AND FRAME_VALID = '1' AND
LINE_VALID = '0' AND
P_Fall = '1' AND PIXCLK = '1' THEN
F_Rising <= FRAME_VALID;
L_Rising <= LINE_VALID;
P_Fall <= PIXCLK;
state <= LCheck;
ELSE
state <= Initial;
END IF;
WHEN Store =>
IF Counter <= "00000000111" THEN
F_Rising <= FRAME_VALID;
L_Rising <= LINE_VALID;
P_Fall <= PIXCLK;
state <= PCheck; --PCheck
ELSE
F_Rising <= FRAME_VALID;
L_Rising <= LINE_VALID;
P_Fall <= PIXCLK;
state <= StoreDone;
END IF;
WHEN StoreDone =>
-- IF Rin = '1' THEN
--
-- F_Rising <= FRAME_VALID;
-- L_Rising <= LINE_VALID;
-- P_Fall <= PIXCLK;
-- state <= StoreDone;
--
-- ELSE
--
-- F_Rising <= FRAME_VALID;
-- L_Rising <= LINE_VALID;
-- P_Fall <= PIXCLK;
-- state <= Initial;
--
-- END IF;
state <= StoreDone;
WHEN OTHERS => state <= Initial;
END CASE;
END IF;
END PROCESS Main;
-- WITH state SELECT
-- Done <= '1' WHEN Initial;
-- '0' WHEN GrabData,
-- '1' WHEN UpdateAdd,
-- '0' WHEN GetTrans,
-- '0' WHEN GetTrans1,
-- '0' WHEN GetTrans2,
-- '0' WHEN StoreTrans,
-- '0' WHEN StoreTrans1,
-- '0' WHEN StoreTrans2,
-- '1' WHEN StoreDone;
WITH state SELECT
GetTransState <= '0' WHEN Initial,
'1' WHEN GetTrans,
'0' WHEN FCheck,
'0' WHEN LCheck,
'0' WHEN PCheck,
'0' WHEN Store,
'0' WHEN StoreDone;
WITH state SELECT
InitialState <= '1' WHEN Initial,
'0' WHEN GetTrans,
'0' WHEN FCheck,
'0' WHEN LCheck,
'0' WHEN PCheck,
'0' WHEN Store,
'0' WHEN StoreDone;
-- '0' WHEN StoreTrans1,
-- '0' WHEN StoreTrans2,
-- '0' WHEN StoreDone;
WITH state SELECT
FCheckState <= '0' WHEN Initial,
'1' WHEN GetTrans,
'0' WHEN FCheck,
'0' WHEN LCheck,
'0' WHEN PCheck,
'0' WHEN Store,
'0' WHEN StoreDone;
WITH state SELECT
LCheckState <= '0' WHEN Initial,
'0' WHEN GetTrans,
'0' WHEN FCheck,
'1' WHEN LCheck,
'0' WHEN PCheck,
'0' WHEN Store,
'0' WHEN StoreDone;
WITH state SELECT
PCheckState <= '0' WHEN Initial,
'0' WHEN GetTrans,
'0' WHEN FCheck,
'0' WHEN LCheck,
'1' WHEN PCheck,
'0' WHEN Store,
'0' WHEN StoreDone;
WITH state SELECT
StoreState <= '0' WHEN Initial,
'0' WHEN GetTrans,
'0' WHEN FCheck,
'0' WHEN LCheck,
'0' WHEN PCheck,
'1' WHEN Store,
'0' WHEN StoreDone;
WITH state SELECT
StoreDoneState <= '0' WHEN Initial,
'0' WHEN GetTrans,
'0' WHEN FCheck,
'0' WHEN LCheck,
'0' WHEN PCheck,
'0' WHEN Store,
'1' WHEN StoreDone;
END A;
--- In David Hawkins <> wrote:
>
> Hi Mugilan,
>
> > I recently ran into another problem while trying to interface the CMOS
> > sensor to the FPGA. The CMOS sensor had 3 main control signals
> > (Frame_Valid, Line_Valid and PIXCLK) as an indicator to latch data
> > through its 8 bit data bus. Frame_Valid pulses high at active columns,
> > Line_Valid pulses high at active rows and fall time of PIXCLK
> > indicates stable data to be latched.
>
> Send me the data sheet, and I'll check it out.
>
> > To deal with this, I created a state machine that runs through a
> > series of states that check for each control signal consecutively. My
> > problem is that my state machine does not work, i.e. the program is
> > not in any of the states. I verified this by connecting each state to
> > an output pin that pulses high if the machine is within the state. I
> > used a logic analyzer to measure these lines and as soon as I finish
> > resetting, it starts from state "Initial" and jumps out of the state
> > machine loop.
> >
> > Frankly, I have no clue of what is going on. I have an "ELSE" clause
> > at the end of each "IF" statements that specifies it to go to the
> > state "Initial" if it fails to meet all the conditions.
> >
> > I hope you can shed some light on this. Thank you
>
> Whenever you write VHDL code, you should always write a test
> bench and simulate it in ModelSim. Altera has a free edition.
> If something works correctly in the testbench but not in hardware,
> then you either have a timing issue, or an error in your
> simulation models. I'm glad to hear you are probing around
> with a logic analyzer - thats a good debugging skill.
>
> If you send me the data sheet for the CMOS sensor, I can
> probably throw a simple simulation and state machine together.
>
> Send me your state machine code too, and I can provide some
> feedback on it for you.
>
> Cheers,
> Dave
>
------------------------------------
Yahoo! Groups Links
<*> To visit your group on the web, go to:
http://groups.yahoo.com/group/ts-7000/
<*> Your email settings:
Individual Email | Traditional
<*> To change settings online go to:
http://groups.yahoo.com/group/ts-7000/join
(Yahoo! ID required)
<*> To change settings via email:
<*> To unsubscribe from this group, send an email to:
<*> Your use of Yahoo! Groups is subject to:
http://docs.yahoo.com/info/terms/
|