M
Mary
Guest
Im trying to write a code for UART. for functional simulation it came
out well. but the timing simulation it went wrong. Can anyone tell me
is ther any problem with the code......
entity uart_state is
generic( char_length_g: natural :=8);
port(
clock:in std_ulogic;
clock_dsp:in std_ulogic;
reset:in std_ulogic;
wr :in std_ulogic;
strb :in std_ulogic;
page :in std_ulogic;
add :in std_ulogic;
Rxd :in std_ulogic;
parity_err,frame_err,overrun_err: out std_ulogic;
Txd ut std_ulogic;
Data :inout std_ulogic_vector(char_length_g-1 downto 0);
Dout: out std_ulogic_vector( 7 downto 0)
);
end uart_state;
architecture uart_state_a of uart_state is
signal
input_buff,output_buff,status_reg:std_ulogic_vector(char_length_g-1
downto 0);
signal tx_enable:std_ulogic;
procedure Data_to_uart is
begin
if reset='1' then
input_buff<=(others=>'0');
Data<=(others=>'0');
tx_enable<='0';
Dout<=(others=>'0');
elsif page='0' then
if add='1' then
if wr='0' then
if strb='0' then
input_buff<=Data;
Data<=(others=>'Z');
tx_enable<='1';
end if;
elsif wr='1' then
if strb='0' then
Dout<=output_buff;
tx_enable<='0';
end if;
end if;
if add='0' then
if wr='1' then
if strb='0' then
Dout<=status_reg;
tx_enable<='0';
end if;
end if;
end if;
end if;
end if;
end procedure Data_to_uart ;
begin
Data_to_uart;
process (clock,reset)
type tx_state is(idle,start,send,parity,stop);
variable tx_state_t:tx_state;
type rx_state is(idle,receive,parity,stop1,stop2,full,err);
variable rx_state_t:rx_state;
--------------------------------------------------------------------------------------------
--------Register Declaration-------
variable tx_buffer_reg ,tx_shift_reg:std_ulogic_vector(char_length_g-1
downto 0);
variable tx_status_reg:std_ulogic_vector(3 downto 0);
variable tx_count:integer range 0 to char_length_g;
variable serial_tx:std_ulogic;
----------------------------------
variable rx_buffer_reg
,rx_shift_reg:std_ulogic_vector(char_length_g-1 downto 0);
variable rx_status_reg:std_ulogic_vector(3 downto 0);
variable rx_count:integer range 0 to char_length_g;
-------Initialization---------------
procedure init_reg is
begin
tx_buffer_reg:=(others=>'0');
tx_shift_reg :=(others=>'0');
tx_status_reg:=(others=>'1');
tx_count :=0;
tx_state_t :=idle;
serial_tx :='1';
rx_buffer_reg:=(others=>'0');
rx_shift_reg:=(others=>'0');
rx_status_reg:=(others=>'1');
rx_count:=0;
rx_state_t :=idle;
output_buff<=(others=>'0');
end procedure init_reg;
--------------------------------------------------------------------------
------------Parity
Checking-----------------------------------------------
procedure parity (Data:in std_ulogic_vector (char_length_g-1 downto
0);
outputut std_ulogic) is
variable temp1:std_logic;
begin
temp1:='1';
for i in 0 to (char_length_g-1) loop
temp1:=temp1 XOR Data(i);
end loop ;
output:=temp1;
end procedure parity;
-------------------------------------------------------------------------
-------------Serial Transmission
---------------------------------------
procedure transmit is
begin
case tx_state_t is
when idle=>
if tx_status_reg(1) ='0' then
tx_state_t:=start;
end if;
when start=>
serial_tx:='0';
tx_shift_reg:=tx_buffer_reg;
parity(tx_buffer_reg,tx_status_reg(3));
tx_status_reg(1):='1';
tx_status_reg(2):='0';
tx_state_t:=send;
when send=>
if tx_status_reg(2)='0'then
serial_tx:=tx_shift_reg(0);
tx_count:=tx_count+ 1 ;
tx_shift_reg:='1'& tx_shift_reg(char_length_g-1 downto 1);
if tx_count=char_length_g then
tx_count:=0;
tx_state_t:=parity;
tx_status_reg(2):='1';
end if;
end if;
when parity=>
serial_tx:=tx_status_reg(3);
tx_state_t:=stop;
when stop=>
for i in 0 to 1 loop
serial_tx:='1';
end loop;
tx_state_t:=idle;
end case;
end procedure transmit ;
--------------------------------------------------------------------------
-----------------------Receiver----------------------------
procedure receiver is
begin
case rx_state_t is
when idle=>
rx_count:=0 ;
if Rxd='0' then
rx_state_t:=receive;
end if;
when receive=>
rx_shift_reg:=Rxd&rx_shift_reg(char_length_g-1 downto 1);
rx_count:=rx_count+1;
if rx_count=char_length_g then
rx_count:=0;
parity(rx_shift_reg,rx_status_reg(3));
rx_state_t:=parity;
end if;
when parity=>
if Rxd=rx_status_reg(3)then
parity_err<='0';
rx_state_t:=stop1;
else
parity_err<='1';
rx_state_t:=err;
end if;
when stop1=>
if Rxd='1' then
rx_state_t:=stop2;
else
frame_err<='1';
rx_state_t:=err;
end if;
When Stop2=>
if Rxd='1' then
rx_state_t:=full;
else
frame_err<='1';
rx_state_t:=err;
end if;
when full=>
if rx_status_reg(2)='1' then
output_buff<=rx_shift_reg;
rx_status_reg(2):='0';
overrun_err<='0';
rx_state_t:=idle;
else rx_state_t:=err;
overrun_err<='1';
end if;
when err=>
null;
end case;
end procedure receiver;
-------------------------------------------------------------------------
--------------Outputs----------------------------------------------------
procedure update_port is
begin
Txd<=serial_tx;
end procedure update_port;
--------------------------------------------------------------------------
procedure cpu_reg is
begin
if tx_enable='1' then
if tx_status_reg(1) ='1' then
tx_buffer_reg:=input_buff;
tx_status_reg(1):='0';
end if;
end if;
end procedure cpu_reg;
--------------------------------------------------------------------
----------------Updating
Registers----------------------------------------
procedure update_regs is
begin
transmit;
receiver;
cpu_reg;
Status_reg<=rx_status_reg & tx_status_reg;
end procedure update_regs;
---------------------------------------------------------------------
begin
if reset='1' then
init_reg;
----------------Initializing --------------------
elsif clock'event and clock='1' then
update_regs;
--------------Call for Transmitter & Receiver---------------
end if;
update_port
-------------Call for Updating output ports------
end process;
end uart_state_a;
out well. but the timing simulation it went wrong. Can anyone tell me
is ther any problem with the code......
entity uart_state is
generic( char_length_g: natural :=8);
port(
clock:in std_ulogic;
clock_dsp:in std_ulogic;
reset:in std_ulogic;
wr :in std_ulogic;
strb :in std_ulogic;
page :in std_ulogic;
add :in std_ulogic;
Rxd :in std_ulogic;
parity_err,frame_err,overrun_err: out std_ulogic;
Txd ut std_ulogic;
Data :inout std_ulogic_vector(char_length_g-1 downto 0);
Dout: out std_ulogic_vector( 7 downto 0)
);
end uart_state;
architecture uart_state_a of uart_state is
signal
input_buff,output_buff,status_reg:std_ulogic_vector(char_length_g-1
downto 0);
signal tx_enable:std_ulogic;
procedure Data_to_uart is
begin
if reset='1' then
input_buff<=(others=>'0');
Data<=(others=>'0');
tx_enable<='0';
Dout<=(others=>'0');
elsif page='0' then
if add='1' then
if wr='0' then
if strb='0' then
input_buff<=Data;
Data<=(others=>'Z');
tx_enable<='1';
end if;
elsif wr='1' then
if strb='0' then
Dout<=output_buff;
tx_enable<='0';
end if;
end if;
if add='0' then
if wr='1' then
if strb='0' then
Dout<=status_reg;
tx_enable<='0';
end if;
end if;
end if;
end if;
end if;
end procedure Data_to_uart ;
begin
Data_to_uart;
process (clock,reset)
type tx_state is(idle,start,send,parity,stop);
variable tx_state_t:tx_state;
type rx_state is(idle,receive,parity,stop1,stop2,full,err);
variable rx_state_t:rx_state;
--------------------------------------------------------------------------------------------
--------Register Declaration-------
variable tx_buffer_reg ,tx_shift_reg:std_ulogic_vector(char_length_g-1
downto 0);
variable tx_status_reg:std_ulogic_vector(3 downto 0);
variable tx_count:integer range 0 to char_length_g;
variable serial_tx:std_ulogic;
----------------------------------
variable rx_buffer_reg
,rx_shift_reg:std_ulogic_vector(char_length_g-1 downto 0);
variable rx_status_reg:std_ulogic_vector(3 downto 0);
variable rx_count:integer range 0 to char_length_g;
-------Initialization---------------
procedure init_reg is
begin
tx_buffer_reg:=(others=>'0');
tx_shift_reg :=(others=>'0');
tx_status_reg:=(others=>'1');
tx_count :=0;
tx_state_t :=idle;
serial_tx :='1';
rx_buffer_reg:=(others=>'0');
rx_shift_reg:=(others=>'0');
rx_status_reg:=(others=>'1');
rx_count:=0;
rx_state_t :=idle;
output_buff<=(others=>'0');
end procedure init_reg;
--------------------------------------------------------------------------
------------Parity
Checking-----------------------------------------------
procedure parity (Data:in std_ulogic_vector (char_length_g-1 downto
0);
outputut std_ulogic) is
variable temp1:std_logic;
begin
temp1:='1';
for i in 0 to (char_length_g-1) loop
temp1:=temp1 XOR Data(i);
end loop ;
output:=temp1;
end procedure parity;
-------------------------------------------------------------------------
-------------Serial Transmission
---------------------------------------
procedure transmit is
begin
case tx_state_t is
when idle=>
if tx_status_reg(1) ='0' then
tx_state_t:=start;
end if;
when start=>
serial_tx:='0';
tx_shift_reg:=tx_buffer_reg;
parity(tx_buffer_reg,tx_status_reg(3));
tx_status_reg(1):='1';
tx_status_reg(2):='0';
tx_state_t:=send;
when send=>
if tx_status_reg(2)='0'then
serial_tx:=tx_shift_reg(0);
tx_count:=tx_count+ 1 ;
tx_shift_reg:='1'& tx_shift_reg(char_length_g-1 downto 1);
if tx_count=char_length_g then
tx_count:=0;
tx_state_t:=parity;
tx_status_reg(2):='1';
end if;
end if;
when parity=>
serial_tx:=tx_status_reg(3);
tx_state_t:=stop;
when stop=>
for i in 0 to 1 loop
serial_tx:='1';
end loop;
tx_state_t:=idle;
end case;
end procedure transmit ;
--------------------------------------------------------------------------
-----------------------Receiver----------------------------
procedure receiver is
begin
case rx_state_t is
when idle=>
rx_count:=0 ;
if Rxd='0' then
rx_state_t:=receive;
end if;
when receive=>
rx_shift_reg:=Rxd&rx_shift_reg(char_length_g-1 downto 1);
rx_count:=rx_count+1;
if rx_count=char_length_g then
rx_count:=0;
parity(rx_shift_reg,rx_status_reg(3));
rx_state_t:=parity;
end if;
when parity=>
if Rxd=rx_status_reg(3)then
parity_err<='0';
rx_state_t:=stop1;
else
parity_err<='1';
rx_state_t:=err;
end if;
when stop1=>
if Rxd='1' then
rx_state_t:=stop2;
else
frame_err<='1';
rx_state_t:=err;
end if;
When Stop2=>
if Rxd='1' then
rx_state_t:=full;
else
frame_err<='1';
rx_state_t:=err;
end if;
when full=>
if rx_status_reg(2)='1' then
output_buff<=rx_shift_reg;
rx_status_reg(2):='0';
overrun_err<='0';
rx_state_t:=idle;
else rx_state_t:=err;
overrun_err<='1';
end if;
when err=>
null;
end case;
end procedure receiver;
-------------------------------------------------------------------------
--------------Outputs----------------------------------------------------
procedure update_port is
begin
Txd<=serial_tx;
end procedure update_port;
--------------------------------------------------------------------------
procedure cpu_reg is
begin
if tx_enable='1' then
if tx_status_reg(1) ='1' then
tx_buffer_reg:=input_buff;
tx_status_reg(1):='0';
end if;
end if;
end procedure cpu_reg;
--------------------------------------------------------------------
----------------Updating
Registers----------------------------------------
procedure update_regs is
begin
transmit;
receiver;
cpu_reg;
Status_reg<=rx_status_reg & tx_status_reg;
end procedure update_regs;
---------------------------------------------------------------------
begin
if reset='1' then
init_reg;
----------------Initializing --------------------
elsif clock'event and clock='1' then
update_regs;
--------------Call for Transmitter & Receiver---------------
end if;
update_port
-------------Call for Updating output ports------
end process;
end uart_state_a;