UART 송신기에 대한 일반적인 보오율 생성기 프로세스를 구축하려고합니다.Baud Rate Clock VHDL - 부동 소수점 예외 오류 및/또는 스타일 문제
전송률 분배기를 무시하고 민감도 목록의 clk 신호를 전달하면 송신기가 정상적으로 작동합니다. 하지만 구분선을 구현하려고하면 오류가 발생합니다 (코드 주석에 설명되어 있음). 나는 두 가지 다른 방법을 시도했는데 둘 다 오류를 주거나 예상 된 결과를 얻지 못했습니다. 네, fbaud를 두 번 할당했기 때문에 게시 된 정확한 코드는 작동하지 않습니다.
아마도 보오드 생성기가 어떻게 작동하는지 이해할 수 없습니다. 내 이해에서, FPGA 클럭 rs232 통신을위한 빠른 50mHz에서 실행됩니다. 그래서 우리는 우리의 성격을 전달하기 전에 일정한 클럭주기를 기다려야합니다.
이 경우 우리는 변수 보 (baud)을 가지고 있으므로 baud generator를 통해 주식 시계를 나눠서 송신 상태 머신에 'tick'신호를 보내기 전에 기다려야하는 클럭 사이클 수를 얻습니다.
baud divider는 테스트 벤치에서 x "000008"로 설정됩니다.
-- Universal Asynch Receiver Transmitter
---------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity eds_uart is
generic (width : positive := 16);
port (clk,reset: in std_logic ;
din_wen: in std_logic; -- state machine sets value thus buffer needed
brd : in std_logic_vector(23 downto 0); -- buad rate dividor
din : in std_logic_vector(7 downto 0); -- input value
txd: out std_logic; -- sent data bit
tx_busy : buffer std_logic -- sent data bit active
);
end entity eds_uart;
architecture behaviour of eds_uart is
type state_type is (idle_s, wait_s, transmit_s); -- three possible states of uat
signal current_s: state_type;
signal tick: std_logic := '0'; -- baud rate clock
signal count: integer := 0; -- count number of characters sent
signal shift: std_logic_vector(9 downto 0); -- intermediate vector to be shifted
signal fbaud: integer := 0;
signal fbaud_counter: integer := 0;
begin
--- process that is causing the issue.
process(clk, brd) begin
fbaud <= (50000000)/to_integer(signed(brd)); -- 50,000,000 is the default clock Hz
------ error message ------
--# ** Warning: NUMERIC_STD.TO_INTEGER: metavalue detected, returning 0
-- # Time: 0 ns Iteration: 0 Instance: /eds_uart_tb/inst_uart
-- # ** Fatal: (SIGFPE) Floating point exception.
--# Time: 0 ns Iteration: 0 Process: /eds_uart_tb/inst_uart/line__29 File:
fbaud <= 50000;
--- error ---
-- this command simply does not work, it compiles and runs though
-- I don't get any transitions in my output wave
-- I don't think it is entering the transmit stage based on a clock signal
if (rising_edge(clk)) then
if (fbaud_counter = fbaud) then -- tick when proper number of counts have appeared
tick <= '1';
elsif (fbaud_counter < fbaud) then
tick <= '0';
fbaud_counter <= fbaud_counter + 1;
end if;
end if;
end process;
process(tick, reset, din) begin
if (reset = '1') then
current_s <= idle_s; -- default state
count <= 0; -- reset character counter
txd <= '1';
tx_busy <= '0';
elsif (current_s = idle_s and din_wen = '1') then -- transition when write enable is high
current_s <= wait_s; -- transition
tx_busy <= '1';
shift <= '1' & din & '0'; -- init shift value
end if;
if(rising_edge(tick)) then
if (current_s = wait_s) then -- transition on clock signal
current_s <= transmit_s;
elsif (current_s = transmit_s) then -- transition on clock signal
if (count < 9) then
txd <= shift(0); -- output value
shift <= '0' & shift(9 downto 1); -- shift to next value
count <= count + 1; -- increment counter
current_s <= transmit_s; -- dont change state
elsif (count = 9) then
txd <= shift(0); -- send last element
count <= 0;
tx_busy <= '0'; -- reset busy signal
current_s <= idle_s; -- start process again
end if;
end if;
end if;
end process;
end architecture behaviour ;
시험용 벤치도 함께 보여주십시오. metavalue detected warning은 일반적으로 브레드 입력이 테스트 벤치에서 제대로 구동되지 않는다는 것을 의미합니다 (적어도 시간 0은 아님). 또한, 클록 라우팅이나 MMCM/PLL을 사용하여 살펴 보는 것만으로는 회의 타이밍이 더 어려워 지므로 (시계 라우팅을 사용하지 않기 때문에) 이런 방식으로 시계를 생성하는 것은 나쁜 습관으로 간주됩니다. 또한 상태, tx_busy 및 시프트 플롭에서 비동기식 세트 및 재설정을 사용하는 것 같습니다. 이것이 심지어 합성을 허용한다면 하드웨어가 작동하는 방식과 일치하지 않기 때문에 나쁜 습관으로 간주됩니다. – QuantumRipple