satty_008
Newbie level 5
- Joined
- Jan 4, 2013
- Messages
- 8
- Helped
- 0
- Reputation
- 0
- Reaction score
- 0
- Trophy points
- 1,281
- Activity points
- 1,388
LIBRARY IEEE;
USE IEEE.std_logic_1164.all;
USE IEEE.numeric_std.all;
-- Serial UART receiver
entity uart_receiver is
generic (
WIDTH_1 : natural := 4
);
port (
CLK : in std_logic; -- Clock
RST : in std_logic; -- Reset
RXCLK : in std_logic; -- receiver clock (2x baudrate)
RXSTART : in std_logic; -- Start receiver
RXCLEAR : in std_logic; -- Clear receiver state
WLS : in std_logic_vector(1 downto 0); -- Word length select
STB : in std_logic; -- Number of stop bits
PEN : in std_logic; -- Parity enable
EPS : in std_logic; -- Even parity select
SP : in std_logic; -- Stick parity
SIN : in std_logic := '1'; -- Input data
PE : out std_logic; -- Parity error
FE : out std_logic; -- Framing error
-- WIDTH : in natural; -- Break interrupt
DOUT : out std_logic_vector(7 downto 0); -- Output data
RXFINISHED : out std_logic -- Receiver operation finished
);
end uart_receiver;
architecture rtl of uart_receiver is
component slib_input_filter is
generic (
SIZE : natural := 4 -- Filter counter size
);
port (
CLK : in std_logic; -- Clock
RST : in std_logic; -- Reset
CE : in std_logic; -- Clock enable
D : in std_logic; -- Signal input
Q : out std_logic -- Signal output
);
end component;
component slib_counter
generic (
WIDTH : natural := 4 -- Counter width
);
port (
CLK : in std_logic; -- Clock
RST : in std_logic; -- Reset
CLEAR : in std_logic; -- Clear counter register
LOAD : in std_logic; -- Load counter register
ENABLE : in std_logic; -- Enable count operation
DOWN : in std_logic; -- Count direction down
D : in std_logic_vector(WIDTH-1 downto 0); -- Load counter register input
Q : out std_logic_vector(WIDTH-1 downto 0); -- Shift register output
OVERFLOW : out std_logic ; -- Counter overflow
HALF : out std_logic
);
end component;
signal iHalf :std_logic;
-- FSM
type rxstate_type is (IDLE, START, DATA, PAR, STOP, MWAIT);
signal CState, NState : rxstate_type;
-- Signals
signal iRx2 : std_logic; -- Next RX step
signal iParityReceived : std_logic; -- Parity from Tx
signal iRxParity : std_logic :='0'; -- Receiver Generated Parity
signal iRXFinished : std_logic :='0'; -- RX finished
signal iDOUT : std_logic_vector(7 downto 0); -- Store incoming data according to bit no.
signal iRXStart : std_logic;
signal iFE : std_logic; -- Internal frame error
signal iNoStopReceived : std_logic; -- No valid stop bit received
signal iDataCount : integer range 0 to 8; -- Data bit counter
signal iDataCountInit : std_logic; -- Initialize data bit counter to word length
signal iDataCountFinish : std_logic; -- Data bit counter finished
signal iBaudCount : std_logic_vector(WIDTH_1-1 downto 0); -- Baud counter output
signal iBaudCountClear : std_logic; -- Baud counter clear
signal iBaudStep : std_logic; -- Next symbol pulse
signal iBaudStepD : std_logic; -- Next symbol pulse delayed by one clock
signal iFStopBit : std_logic; -- Filtered SIN for stop bit detection
begin
-- Baudrate counter: RXCLK/16
RX_BRC: slib_counter generic map (
WIDTH => 4--WIDTH_1
) port map (
CLK => CLK,
RST => RST,
CLEAR => iBaudCountClear,
LOAD => '0',
ENABLE => '1',
DOWN => '0',
D => (others=>'0'),
Q => iBaudCount,
OVERFLOW => iBaudStep,
HALF =>iHalf
);
STOP_CHECK: slib_input_filter
generic map (
SIZE => 4 -- Filter counter size
)
port map (
CLK => clk, -- Clock
RST => rst, -- Reset
CE => rxclk, -- Clock enable
D => SIN, -- Signal input
Q => iFSTOPBIT -- Signal output
);
-- Data bit capture
RX_DATACOUNT: process (CLK, RST)
begin
if (RST = '1') then
iDataCount <= 0;
iDOUT <= (others => '0');
elsif (CLK'event and CLK = '1') then
if (iDataCountInit = '1') then
iDataCount <= 0;
iDOUT <= (others => '0');
else
if (iBaudStep = '1' and iDataCountFinish = '0') then
iDOUT(iDataCount) <= SIN;
iDataCount <= iDataCount + 1;
end if;
end if;
end if;
end process;
iDataCountFinish <= '1' when (WLS = "00" and iDataCount = 5) or
(WLS = "01" and iDataCount = 6) or
(WLS = "10" and iDataCount = 7) or
(WLS = "11" and iDataCount = 8) else '0';
-- FSM update process
RX_FSMUPDATE: process (CLK, RST)
begin
if (RST = '1') then
CState <= IDLE;
elsif (CLK'event and CLK = '1') then
CState <= NState;
end if;
end process;
-- RX FSM
RX_FSM: process (CState,NSTATE,RST, SIN,iFStopBit, iBaudStep, iBaudCount, iDataCountFinish, PEN, WLS, STB)
begin
-- Defaults
NState <= IDLE;
iBaudCountClear <= '0';
iDataCountInit <= '0';
iRXFinished <= '0';
case CState is
when IDLE => if (SIN = '0') then -- Start detected
NState <= START;
end if;
iBaudCountClear <= '1';
iDataCountInit <= '0';
when START => iDataCountInit <= '1';
if (iBaudStep = '1') then -- Wait for start bit end
if (SIN = '0') then
NState <= DATA;
end if;
else
NState <= START;
end if;
when DATA => if (iDataCountFinish = '1') then -- Received all data bits
if (PEN = '1') then
NState <= PAR; -- Parity enabled
else
NState <= STOP; -- No parity
end if;
else
NState <= DATA;
end if;
when PAR => if (iBaudStep = '1') then -- Wait for parity bit
NState <= STOP;
else
NState <= PAR;
end if;
when STOP => if (ibaudstep = '1') then -- Wait for stop bit
if (iFStopBit = '0') then -- No stop bit received
iRXFinished <= '0';
NState <= MWAIT;
else
iRXFinished <= '1';
NState <= IDLE; -- Stop bit end
end if;
else
NState <= STOP;
end if;
when MWAIT => if (SIN = '0') then -- Wait for mark
NState <= MWAIT;
end if;
when others => null;
end case;
end process;
-- Framing error
iNoStopReceived <= '1' when (SIN = '0' and (CState = STOP and ibaudstep='1')) else '0';
iFE <= '1' when iNoStopReceived = '1' else '0';
-- Output signals
DOUT <= ('-'&'-'&'-'& iDOUT(4 downto 0)) when ((WLS = "00") and iRxFinished <= '1') else
('-'&'-'& iDOUT(5 downto 0)) when ((WLS = "01") and iRxFinished <= '1')else
('-'& iDOUT(6 downto 0)) when ((WLS = "10")and iRxFinished <= '1') else
iDOUT when ((WLS = "11")and iRxFinished <= '1');
FE <= iFE;
RXFINISHED <= iRXFinished;
end rtl;
what should be the process arguments for both nstate and cstate.. my cstate is not changing at the right time !! please help. thanks in ADVANCE !!
USE IEEE.std_logic_1164.all;
USE IEEE.numeric_std.all;
-- Serial UART receiver
entity uart_receiver is
generic (
WIDTH_1 : natural := 4
);
port (
CLK : in std_logic; -- Clock
RST : in std_logic; -- Reset
RXCLK : in std_logic; -- receiver clock (2x baudrate)
RXSTART : in std_logic; -- Start receiver
RXCLEAR : in std_logic; -- Clear receiver state
WLS : in std_logic_vector(1 downto 0); -- Word length select
STB : in std_logic; -- Number of stop bits
PEN : in std_logic; -- Parity enable
EPS : in std_logic; -- Even parity select
SP : in std_logic; -- Stick parity
SIN : in std_logic := '1'; -- Input data
PE : out std_logic; -- Parity error
FE : out std_logic; -- Framing error
-- WIDTH : in natural; -- Break interrupt
DOUT : out std_logic_vector(7 downto 0); -- Output data
RXFINISHED : out std_logic -- Receiver operation finished
);
end uart_receiver;
architecture rtl of uart_receiver is
component slib_input_filter is
generic (
SIZE : natural := 4 -- Filter counter size
);
port (
CLK : in std_logic; -- Clock
RST : in std_logic; -- Reset
CE : in std_logic; -- Clock enable
D : in std_logic; -- Signal input
Q : out std_logic -- Signal output
);
end component;
component slib_counter
generic (
WIDTH : natural := 4 -- Counter width
);
port (
CLK : in std_logic; -- Clock
RST : in std_logic; -- Reset
CLEAR : in std_logic; -- Clear counter register
LOAD : in std_logic; -- Load counter register
ENABLE : in std_logic; -- Enable count operation
DOWN : in std_logic; -- Count direction down
D : in std_logic_vector(WIDTH-1 downto 0); -- Load counter register input
Q : out std_logic_vector(WIDTH-1 downto 0); -- Shift register output
OVERFLOW : out std_logic ; -- Counter overflow
HALF : out std_logic
);
end component;
signal iHalf :std_logic;
-- FSM
type rxstate_type is (IDLE, START, DATA, PAR, STOP, MWAIT);
signal CState, NState : rxstate_type;
-- Signals
signal iRx2 : std_logic; -- Next RX step
signal iParityReceived : std_logic; -- Parity from Tx
signal iRxParity : std_logic :='0'; -- Receiver Generated Parity
signal iRXFinished : std_logic :='0'; -- RX finished
signal iDOUT : std_logic_vector(7 downto 0); -- Store incoming data according to bit no.
signal iRXStart : std_logic;
signal iFE : std_logic; -- Internal frame error
signal iNoStopReceived : std_logic; -- No valid stop bit received
signal iDataCount : integer range 0 to 8; -- Data bit counter
signal iDataCountInit : std_logic; -- Initialize data bit counter to word length
signal iDataCountFinish : std_logic; -- Data bit counter finished
signal iBaudCount : std_logic_vector(WIDTH_1-1 downto 0); -- Baud counter output
signal iBaudCountClear : std_logic; -- Baud counter clear
signal iBaudStep : std_logic; -- Next symbol pulse
signal iBaudStepD : std_logic; -- Next symbol pulse delayed by one clock
signal iFStopBit : std_logic; -- Filtered SIN for stop bit detection
begin
-- Baudrate counter: RXCLK/16
RX_BRC: slib_counter generic map (
WIDTH => 4--WIDTH_1
) port map (
CLK => CLK,
RST => RST,
CLEAR => iBaudCountClear,
LOAD => '0',
ENABLE => '1',
DOWN => '0',
D => (others=>'0'),
Q => iBaudCount,
OVERFLOW => iBaudStep,
HALF =>iHalf
);
STOP_CHECK: slib_input_filter
generic map (
SIZE => 4 -- Filter counter size
)
port map (
CLK => clk, -- Clock
RST => rst, -- Reset
CE => rxclk, -- Clock enable
D => SIN, -- Signal input
Q => iFSTOPBIT -- Signal output
);
-- Data bit capture
RX_DATACOUNT: process (CLK, RST)
begin
if (RST = '1') then
iDataCount <= 0;
iDOUT <= (others => '0');
elsif (CLK'event and CLK = '1') then
if (iDataCountInit = '1') then
iDataCount <= 0;
iDOUT <= (others => '0');
else
if (iBaudStep = '1' and iDataCountFinish = '0') then
iDOUT(iDataCount) <= SIN;
iDataCount <= iDataCount + 1;
end if;
end if;
end if;
end process;
iDataCountFinish <= '1' when (WLS = "00" and iDataCount = 5) or
(WLS = "01" and iDataCount = 6) or
(WLS = "10" and iDataCount = 7) or
(WLS = "11" and iDataCount = 8) else '0';
-- FSM update process
RX_FSMUPDATE: process (CLK, RST)
begin
if (RST = '1') then
CState <= IDLE;
elsif (CLK'event and CLK = '1') then
CState <= NState;
end if;
end process;
-- RX FSM
RX_FSM: process (CState,NSTATE,RST, SIN,iFStopBit, iBaudStep, iBaudCount, iDataCountFinish, PEN, WLS, STB)
begin
-- Defaults
NState <= IDLE;
iBaudCountClear <= '0';
iDataCountInit <= '0';
iRXFinished <= '0';
case CState is
when IDLE => if (SIN = '0') then -- Start detected
NState <= START;
end if;
iBaudCountClear <= '1';
iDataCountInit <= '0';
when START => iDataCountInit <= '1';
if (iBaudStep = '1') then -- Wait for start bit end
if (SIN = '0') then
NState <= DATA;
end if;
else
NState <= START;
end if;
when DATA => if (iDataCountFinish = '1') then -- Received all data bits
if (PEN = '1') then
NState <= PAR; -- Parity enabled
else
NState <= STOP; -- No parity
end if;
else
NState <= DATA;
end if;
when PAR => if (iBaudStep = '1') then -- Wait for parity bit
NState <= STOP;
else
NState <= PAR;
end if;
when STOP => if (ibaudstep = '1') then -- Wait for stop bit
if (iFStopBit = '0') then -- No stop bit received
iRXFinished <= '0';
NState <= MWAIT;
else
iRXFinished <= '1';
NState <= IDLE; -- Stop bit end
end if;
else
NState <= STOP;
end if;
when MWAIT => if (SIN = '0') then -- Wait for mark
NState <= MWAIT;
end if;
when others => null;
end case;
end process;
-- Framing error
iNoStopReceived <= '1' when (SIN = '0' and (CState = STOP and ibaudstep='1')) else '0';
iFE <= '1' when iNoStopReceived = '1' else '0';
-- Output signals
DOUT <= ('-'&'-'&'-'& iDOUT(4 downto 0)) when ((WLS = "00") and iRxFinished <= '1') else
('-'&'-'& iDOUT(5 downto 0)) when ((WLS = "01") and iRxFinished <= '1')else
('-'& iDOUT(6 downto 0)) when ((WLS = "10")and iRxFinished <= '1') else
iDOUT when ((WLS = "11")and iRxFinished <= '1');
FE <= iFE;
RXFINISHED <= iRXFinished;
end rtl;
what should be the process arguments for both nstate and cstate.. my cstate is not changing at the right time !! please help. thanks in ADVANCE !!