Я сейчас изучаю VHDL и пытался реализовать UART (1 стартовый бит, 8 бит данных, 1 стоповый бит) для периодической отправки жестко закодированной строки.
Все работает как положено - я получаю строку каждую 1 секунду. Однако второго персонажа нет.
Неважно, какой длины строка, какой это символ. Я проверил этот факт на осциллографе, и для этого конкретного символа нет формы сигнала. 1 стартовый бит, 8 бит для первого символа, стоповый бит, стартовый бит и 8 бит для третьего символа, а не для второго.
Следующий код предназначен для тактовой частоты 10 МГц, разделенной для отправки с ~ 38 400 бит в секунду, я также пробовал с 9600 бит в секунду, у обоих та же проблема.
Я использую плату разработки Altera MAX10: http://maximator-fpga.org/
Короткое видео о том, как это работает: https://gfycat.com/JoyousIllliterateGuillemot
UART.vhd:
LIBRARY ieee;
USE ieee.std_logic_1164.all;
use ieee.numeric_std.ALL;
use ieee.std_logic_arith.all;
entity UART is
port (
clk_10mhz: in STD_LOGIC;
txPin: out STD_LOGIC
);
end entity;
architecture Test of UART is
signal txStart: STD_LOGIC;
signal txIdle: STD_LOGIC;
signal txData: STD_LOGIC_VECTOR(7 downto 0);
component TX is
port (
clk_in: in STD_LOGIC;
start: in STD_LOGIC;
data: in STD_LOGIC_VECTOR(7 downto 0);
tx: out STD_LOGIC;
txIdle: out STD_LOGIC
);
end component TX;
begin
process (clk_10mhz, txIdle)
variable clkDividerCounter : integer range 0 to 10000000;
variable textToSend : string(1 to 31) := "Hello darkness my old friend!" & CR & LF;
variable currentCharacterIndex : integer range 0 to 31;
begin
if (rising_edge(clk_10mhz)) then
if (clkDividerCounter < 10000000) then
clkDividerCounter := clkDividerCounter + 1;
else
clkDividerCounter := 0;
currentCharacterIndex := 1;
end if;
if (txIdle = '1' and currentCharacterIndex > 0) then
txData <= CONV_STD_LOGIC_VECTOR(character'pos(textToSend(currentCharacterIndex)),8);
txStart <= '1';
if (currentCharacterIndex < 31) then
currentCharacterIndex := currentCharacterIndex + 1;
else
currentCharacterIndex := 0;
txStart <= '0';
end if;
end if;
end if;
end process;
u1: TX port map (clk_10mhz, txStart, txData, txPin, txIdle);
end Test;
TX.vhd:
LIBRARY ieee;
USE ieee.std_logic_1164.all;
use ieee.numeric_std.ALL;
entity TX is
port (
clk_in: in STD_LOGIC;
start: in STD_LOGIC;
data: in STD_LOGIC_VECTOR(7 downto 0);
tx: out STD_LOGIC;
txIdle: out STD_LOGIC
);
end entity;
architecture Test of TX is
signal idle: STD_LOGIC;
begin
process (clk_in)
variable bitIndex : integer range 0 to 9;
variable clkDividerCounter : integer range 0 to 260;
variable dataFrame : STD_LOGIC_VECTOR(9 downto 0);
variable dataFrameCurrentIndex : integer range 0 to 9;
begin
if (rising_edge(clk_in)) then
if (start = '1' and idle = '1') then
dataFrame(0) := '0';
dataFrame(8 downto 1) := data;
dataFrame(9) := '1';
dataFrameCurrentIndex := 0;
idle <= '0';
end if;
if (idle = '0') then
if (clkDividerCounter < 260) then
clkDividerCounter := clkDividerCounter + 1;
else
if (dataFrameCurrentIndex <= 9) then
tx <= dataFrame(dataFrameCurrentIndex);
dataFrameCurrentIndex := dataFrameCurrentIndex + 1;
else
idle <= '1';
end if;
clkDividerCounter := 0;
end if;
end if;
txIdle <= idle;
end if;
end process;
end Test;
std_logic_arith
. - person user_1818839   schedule 21.05.2016