UART - URGENT - I have 24 hours

FPGA projects on this site, or abroad

UART - URGENT - I have 24 hours

Postby gcpfox » Thu Jun 16, 2011 6:12 pm

Hello guys, IM new here in the forum and need much help. I'm desperate.
I have until tomorrow to deliver a simple, yet my uart Tx doesn't work.
Board Altera Cyclone 2

code:
baund rate generation

library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
---------------------------------

entity baud_rate_generator is
port(
-- Portas do processador
CLK_IN : IN STD_LOGIC; -- Clock do sistema.
NRST : IN STD_LOGIC; -- Reset assíncrono.
BRG_REG : IN STD_LOGIC_VECTOR(15 downto 0);
BRG_PULSE : OUT STD_LOGIC
);
end baud_rate_generator;

architecture arch of baud_rate_generator is
-- Contador da divisao
signal div_counter : STD_LOGIC_VECTOR(15 downto 0);
begin
process(NRST, CLK_IN, BRG_REG) is
begin
if(NRST = '0') then
div_counter <= (others => '0');
BRG_PULSE <= '0';
elsif(rising_edge(CLK_IN)) then
BRG_PULSE <= '0';
if(div_counter = BRG_REG + 1) then
BRG_PULSE <= '1';
div_counter <= (others => '0');
else
BRG_PULSE <= '0';
div_counter <= div_counter + 1;
end if;
end if;
end process;
end arch;

baund rate generation

RX

library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
---------------------------------

entity rx is
port(
CLK_IN : IN STD_LOGIC; -- Clock do sistema.
NRST : IN STD_LOGIC; -- Reset assíncrono.
RX_D : OUT STD_LOGIC_VECTOR(7 downto 0);
RX_REG_RD : IN STD_LOGIC; -- Habilitar leitura do RX
RX_RDY : OUT STD_LOGIC;
PAR_ERR : OUT STD_LOGIC; -- Erro de paridade
FRM_ERR : OUT STD_LOGIC; -- Erro de framing
OVR_ERR : OUT STD_LOGIC; -- Erro de overrum
PAR_ENA : IN STD_LOGIC; -- 1 => paridade habilitada
PAR_EO : IN STD_LOGIC; -- 0 => paridade par; 1 => paridade ímpar
RX_IN : IN STD_LOGIC;
BRG_PULSE : IN STD_LOGIC -- Pulso (gerado pelo baud rate generate)
);
end rx;

---------------------------------
architecture arch of rx is
-- Estados
type STATE is (iddle, start, data, parity, stop);
signal rx_state_reg, rx_state_next : STATE;

signal rx_s_reg, rx_s_next : STD_LOGIC_VECTOR(2 downto 0);
-- paridade
signal parity_counter : STD_LOGIC_VECTOR(3 downto 0);

signal rx_in_reg : STD_LOGIC; -- Para sincronizar o sinal de entrada
signal rx_reg : STD_LOGIC_VECTOR(7 downto 0); -- Registrador dos dados recebidos
signal rx_buf_reg : STD_LOGIC_VECTOR(7 downto 0); -- Buffer do registrador dos dados recebidos
signal rx_is_empty : STD_LOGIC := '1'; -- Para verificar se os dados foram enviados (buffer enviado, vazio)
-- Contador para gerar o pulso multiplicado por 16
signal counter_16 : STD_LOGIC_VECTOR(3 downto 0);
begin
process(NRST, CLK_IN, RX_IN) is
begin
if (NRST = '0') then
RX_D <= (others => '0'); -- Dados recebidos
rx_buf_reg <= (others => '0');
RX_RDY <= '0'; -- rx_rdy
OVR_ERR <= '0'; -- ovr_err
PAR_ERR <= '0'; -- par_err
FRM_ERR <= '0'; -- frm_err
rx_state_reg <= iddle; -- Estado de espera
rx_s_reg <= (others => '0');
rx_buf_reg <= (others => '0');
rx_is_empty <= '1';
elsif (rising_edge(CLK_IN)) then
rx_in_reg <= RX_IN; -- Sincronizar o sinal assincrono (rx_in_reg <= R_IN)
rx_buf_reg <= rx_reg;
if(RX_REG_RD = '1') then
RX_D <= rx_buf_reg; -- Receber os dados do buffer RX
rx_is_empty <= '1'; -- Para indicar que o RX está vazio
RX_RDY <= '1';
end if;

rx_state_reg <= rx_state_next;
rx_s_reg <= rx_s_next;

case rx_state_reg is
-- Espera o comando para iniciar
when iddle =>
if (BRG_PULSE = '1') then
if (rx_in_reg = '0') then
rx_state_next <= start;
end if;
if(counter_16 = 15) then
counter_16 <= (others => '0');
else
counter_16 <= counter_16 + 1;
end if;
end if;
-- Inicia
when start =>
RX_RDY <= '0';
if (BRG_PULSE = '1') then
if(counter_16 = 7) then
-- Testar par verificar se ocorreu o erro de framing em start
if (rx_in_reg = '1') then -- Se entrada for 1
rx_state_next <= iddle;
else
parity_counter <= (others => '0');
rx_s_next <= (others => '0');
rx_state_next <= data;
end if;
end if;
counter_16 <= counter_16 + 1;

end if;
-- Transfere os dados para o registrador
when data =>
if (BRG_PULSE = '1') then

if(counter_16 = 7) then
rx_reg(conv_integer(rx_s_reg)) <= rx_in_reg;
-- Contar os bits '1'
if (rx_in_reg = '1') then
parity_counter <= parity_counter + 1;
end if;
if (rx_s_reg = 7) then
-- Verificar paridade
if (PAR_ENA = '1') then
rx_state_next <= parity;
else
rx_state_next <= stop;
end if;
rx_s_next <= (others => '0');
else
rx_s_next <= rx_s_reg + 1;
end if;
counter_16 <= counter_16 + 1;
elsif(counter_16 = 15) then
counter_16 <= (others => '0');
else
counter_16 <= counter_16 + 1;
end if;
end if;


-- Verificar paridade
when parity =>
if (BRG_PULSE = '1') then

if(counter_16 = 7) then
rx_state_next <= stop;
-- Verificar se o erro de paridade ocorre
if(PAR_EO = '0') then -- Se paridade par (par_eo = '0')
if(parity_counter(0)='0') then
if(rx_in_reg = '0') then
PAR_ERR <= '0';
else
PAR_ERR <= '1'; -- Erro de paridade caso buffer seja impar
end if;
else
if(rx_in_reg = '0') then
PAR_ERR <= '0'; -- Erro de paridade caso buffer seja impar
else
PAR_ERR <= '1';
end if;
end if;
else -- Se paridade impar
if(parity_counter(0)='0') then
if(rx_in_reg = '0') then
PAR_ERR <= '1';
else
PAR_ERR <= '0'; -- Erro de paridade caso buffer seja par
end if;
else
if(rx_in_reg = '0') then
PAR_ERR <= '1'; -- Erro de paridade caso buffer seja par
else
PAR_ERR <= '0';
end if;
end if;
end if;
counter_16 <= counter_16 + 1;
elsif(counter_16 = 15) then
counter_16 <= (others => '0');
else
counter_16 <= counter_16 + 1;
end if;
end if;
-- Termina o comando, transfere os dados do registrador para o buffer de saida
when stop =>
if (BRG_PULSE = '1') then

if(counter_16 = 7) then

-- Testar par verificar se ocorreu o erro de framing em stop
if (rx_in_reg = '0') then -- Se entrada for 0
FRM_ERR <= '1'; -- Erro de framing
else
FRM_ERR <= '0';
-- Para verificar erro de overrun
if (rx_is_empty = '0') then -- Se não estiver vazio
OVR_ERR <= '1'; -- Erro de overrun
-- Continua no estado e com o erro até ler os dados antigos
else
OVR_ERR <= '0';
rx_buf_reg <= rx_reg; -- Receber os dados do registrador para o buffer
rx_state_next <= iddle;
rx_is_empty <= '0'; -- Para indicar que o RX não está vazio
end if;
end if;
counter_16 <= counter_16 + 1;
elsif(counter_16 = 15) then
counter_16 <= (others => '0');
else
counter_16 <= counter_16 + 1;
end if;
end if;
end case;
end if;
end process;
end arch;

Glue Logic
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
---------------------------------

entity glue_logic is

port(
-- Portas do processador
CLK_IN : IN STD_LOGIC; -- Clock do sistema.
NRST : IN STD_LOGIC; -- Reset assíncrono.
D : INOUT STD_LOGIC_VECTOR(7 downto 0); -- Porta bidirecional de dados com 8 bits.
-- Durante as operações de leitura, saida.
-- Durante as operações de escrita, entrada.

ADDR : IN STD_LOGIC_VECTOR(1 downto 0); -- endereçamento para registradores internos
NCS : IN STD_LOGIC; -- Entrada de chip select.

RD_NWR : IN STD_LOGIC;

-- Portas para o RX
RX_D : IN STD_LOGIC_VECTOR(7 downto 0); -- Entrada de dados do RX
RX_REG_RD : OUT STD_LOGIC; -- Habilitar leitura do RX
RX_RDY : IN STD_LOGIC; -- Exibir a entrada de dado serial
PAR_ERR : IN STD_LOGIC; -- Erro de paridade
FRM_ERR : IN STD_LOGIC; -- Erro de framing
OVR_ERR : IN STD_LOGIC; -- Erro de overrum

-- Portas para o TX
TX_D : OUT STD_LOGIC_VECTOR(7 downto 0); -- Saida de dados para o TX
TX_REG_WR : OUT STD_LOGIC; -- Habilitar transmissão de dados
TX_REG_EMPTY : IN STD_LOGIC; -- Registrador de transmissao vazio
TX_BUSY : IN STD_LOGIC; -- Transmissor em uso
PAR_ENA : OUT STD_LOGIC; -- 1 => paridade habilitada
PAR_EO : OUT STD_LOGIC; -- 0 => paridade par; 1 => paridade ímpar

-- Porta para o BAUD RATE GENERATOR
BRG_REG : OUT STD_LOGIC_VECTOR(15 downto 0) -- DIVISOR DO CLKx16

);
end glue_logic;

architecture arch of glue_logic is
signal status_reg : STD_LOGIC_VECTOR(7 downto 0) := (others => '0'); -- Registrador status (0[tx_busy][tx_reg_empty]0[frm_err][par_err][over_err][rx_dy])
signal cntrl_reg : STD_LOGIC_VECTOR(7 downto 0) := (others => '0'); -- Registrador cntrl (xxx[par_ena][par_eo]xxx)
signal brg_reg0 : STD_LOGIC_VECTOR(7 downto 0); -- 8 bits menos significativos do divisor do baud rate generator
signal brg_reg1 : STD_LOGIC_VECTOR(7 downto 0); -- 8 bits mais significativos do divisor do baud rate generator
signal in_data : STD_LOGIC_VECTOR(7 downto 0) := (others => '0');
signal out_data : STD_LOGIC_VECTOR(7 downto 0);
begin
-- Para o registrador de status
process(NRST, CLK_IN, status_reg) is
begin
if (NRST = '0') then
status_reg <= (others => '0');
elsif rising_edge(CLK_IN) then
status_reg(0) <= RX_RDY;
status_reg(1) <= OVR_ERR;
status_reg(2) <= PAR_ERR;
status_reg(3) <= FRM_ERR;
status_reg(4) <= '0';
status_reg(5) <= TX_REG_EMPTY;
status_reg(6) <= TX_BUSY;
status_reg(7) <= '0';
end if;
end process;

-- Para o registrador cntrl
process(NRST, CLK_IN) is
begin
if (NRST = '0') then
PAR_ENA <= '0';
PAR_EO <= '0';
elsif rising_edge(CLK_IN) then
PAR_ENA <= cntrl_reg(3);
PAR_EO <= cntrl_reg(4);
end if;
end process;


-- Processo principal do glue logic
process(NRST, CLK_IN, ADDR, NCS, RD_NWR, brg_reg0, brg_reg1) is
begin
if (NRST = '0') then
cntrl_reg <= (others => '0');
brg_reg0 <= (others => '0');
brg_reg1 <= (others => '0');
in_data <= (others => '0');
TX_D <= (others => '0');
elsif rising_edge(CLK_IN) then
if(NCS = '0') then
if (RD_NWR = '0') then
case ADDR is
when "00" =>
TX_REG_WR <= '1';
when "01" =>
TX_REG_WR <= '0';
cntrl_reg <= out_data;
when "10" =>
TX_REG_WR <= '0';
brg_reg0 <= out_data;
when "11" =>
TX_REG_WR <= '0';
brg_reg1 <= out_data;
end case;
else
in_data <= (others => '0');
case ADDR is
when "00" =>
in_data <= RX_D;
RX_REG_RD <= '1';
when "01" => in_data <= status_reg;
when "10" => in_data <= brg_reg0;
when "11" => in_data <= brg_reg1;
end case;
end if;
end if;
TX_D <= out_data;
end if;
BRG_REG <= brg_reg1 & brg_reg0; -- bits mais significativos & menos significativos
end process;

-- Processo para controle do buffer tri-state
process(RD_NWR, D, in_data)
begin
if (RD_NWR = '0') then
D <= (others => 'Z');
else
D <= in_data;
end if;
out_data <= D;
end process;
end arch;


Tx
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
---------------------------------

entity tx is
port(
CLK_IN : IN STD_LOGIC; -- Clock do sistema.
NRST : IN STD_LOGIC; -- Reset assíncrono.
TX_D : IN STD_LOGIC_VECTOR(7 downto 0);
TX_REG_WR : IN STD_LOGIC; -- Habilitar envio de dados
TX_REG_EMPTY : OUT STD_LOGIC; -- Registrador de transmissao vazio
TX_BUSY : OUT STD_LOGIC; -- Transmissor em uso
PAR_ENA : IN STD_LOGIC; -- 1 => paridade habilitada
PAR_EO : IN STD_LOGIC; -- 0 => paridade par; 1 => paridade ímpar
BRG_PULSE : IN STD_LOGIC; -- Pulso (gerado pelo baud rate generate)
TX_OUT : OUT STD_LOGIC
);
end tx;

---------------------------------
architecture arch of tx is
-- Estados
type STATE is (iddle, start, data, parity, stop);
signal tx_state_reg, tx_state_next : STATE;
-- Para contar os bits do comando
signal tx_s_reg, tx_s_next : STD_LOGIC_VECTOR(2 downto 0);
-- Para contar a paridade
signal parity_counter : STD_LOGIC_VECTOR(3 downto 0);
-- Registradores
signal tx_is_busy : STD_LOGIC; -- Indicar que o TX esta ocupado
signal tx_is_empty : STD_LOGIC := '1'; -- Indicar que o TX estah vazio
signal tx_hld_reg : STD_LOGIC_VECTOR(7 downto 0); -- Registrador dos dados a serem transmitidos
-- Contador para gerar o pulso multiplicado por 16
signal counter_16 : STD_LOGIC_VECTOR(3 downto 0);
begin
process(NRST, CLK_IN) is
begin
if (NRST = '0') then
TX_REG_EMPTY <= '1'; -- tx_reg_empty
TX_BUSY <= '0'; -- tx_busy
tx_state_reg <= iddle;
tx_s_reg <= (others => '0');
TX_OUT <= '1';
tx_is_empty <= '1';
elsif (rising_edge(CLK_IN)) then
if (tx_reg_wr = '1') then -- Se TX habilitado
if (tx_is_empty = '0') then -- Se registrador de transmissao nao vazio. Tava 1 eu troquei para 0
tx_hld_reg <= tx_d; -- Insere no registrador de dados a serem enviados
tx_is_empty <= '1'; -- Registrador de transmissão fica vazio. Tava zero eu troquei para 1
end if;
end if;

tx_state_reg <= tx_state_next;
tx_s_reg <= tx_s_next;

case tx_state_reg is
-- Espera o comando para iniciar
when iddle =>
if (BRG_PULSE = '1') then
if(tx_is_empty = '1') then -- tava 0 eu troquei para 1
tx_state_next <= start;
tx_is_busy <= '1';
else
tx_is_busy <= '0'; -- TX livre
end if;
if(counter_16 = 15) then
counter_16 <= (others => '0');
else
counter_16 <= counter_16 + 1;
end if;
end if;
-- Inicia, indica na saida que o comando iniciou
when start =>
if (BRG_PULSE = '1') then
if(counter_16 = 7) then
tx_state_next <= data;
tx_s_reg <= (others => '0');
parity_counter <= (others => '0');
end if;
TX_OUT <= '0';
counter_16 <= counter_16 + 1;
end if;
-- Transfere os dados para a saida
when data =>
if (BRG_PULSE = '1') then

if(counter_16 = 7) then

TX_OUT <= tx_hld_reg(conv_integer(tx_s_reg));
-- Contar os bits '1'
if (tx_hld_reg(conv_integer(tx_s_reg)) = '1') then
parity_counter <= parity_counter + 1;
end if;
if(tx_s_reg = 7) then
tx_s_next <= (others => '0');
if (PAR_ENA = '1') then
tx_state_next <= parity;
else
tx_state_next <= stop;
end if;
else
tx_s_next <= tx_s_reg + 1;
end if;
counter_16 <= counter_16 + 1;
elsif(counter_16 = 15) then
counter_16 <= (others => '0');
else
counter_16 <= counter_16 + 1;
end if;
end if;
-- Para a paridade
when parity =>
if (BRG_PULSE = '1') then

if(counter_16 = 7) then

tx_state_next <= stop;
if (PAR_EO = '0') then
if(parity_counter(0)='0') then
TX_OUT <= '0';
else
TX_OUT <= '1';
end if;
else
if(parity_counter(0)='0') then
TX_OUT <= '1';
else
TX_OUT <= '0';
end if;
end if;
counter_16 <= counter_16 + 1;


elsif(counter_16 = 15) then
counter_16 <= (others => '0');
else
counter_16 <= counter_16 + 1;
end if;




end if;
-- Termina o comando, indica na saida que o comando terminou
when stop =>
if (BRG_PULSE = '0') then -- Estava 1 eu troquei para 0.
if(counter_16 = 7) then
TX_OUT <= '1';
tx_is_empty <= '1'; -- Registrador de transmissão fica cheio
tx_is_busy <= '0';
tx_state_next <= iddle; -- Volta para o estado de espera
counter_16 <= counter_16 + 1;
elsif(counter_16 = 15) then
counter_16 <= (others => '0');
else
counter_16 <= counter_16 + 1;
end if;
end if;
end case;

TX_BUSY <= tx_is_busy;
TX_REG_EMPTY <= tx_is_empty;
end if;
end process;
end arch;
gcpfox
 
Posts: 1
Joined: Thu Jun 16, 2011 5:59 pm

Return to General projects