2014-05-14 3 views
0

다음은 코드입니다.이 경우 패리티 비트 계산이 수행되지 않습니다. 패리티 비트는 for 루프를 사용하여 계산할 수 있지만이 컨텍스트에서 짝수 패리티 비트를 계산할 수있는 다른 짧거나 나은 방법이 있습니다. 8 대신 TxDataReg std_logic_vector 배열을 사용하는 것이 가능합니까? 배열을 만든 후 upt_tx 포트에서 데이터를 전송하기 위해 비트 단위로 8 비트의 8 개 신호 배열을 비트 단위로 액세스하려고합니다.8 비트 std_logic_vector에 짝수 패리티 비트와 2 정지 비트 추가

library IEEE; 
use IEEE.STD_LOGIC_1164.ALL; 
use IEEE.STD_LOGIC_UNSIGNED.ALL; 
use IEEE.STD_LOGIC_SIGNED.ALL; 
use IEEE.STD_LOGIC_ARITH.ALL; 
use IEEE.NUMERIC_STD.ALL; 

entity Uart_tx is 
    Port ( 
      tx_clk_in : in STD_LOGIC; 
      reset  : in STD_LOGIC; 
      tx   : out STD_LOGIC; 
      Rx_Data_in : in STD_LOGIC_VECTOR(63 downto 0) 

     ); 
end Uart_tx; 

architecture Behavioral of Uart_tx is 

signal Tx_Data  : STD_LOGIC_VECTOR(63 downto 0) := "00000000"; 

signal DataByteArray1 : std_logic_vector(7 downto 0) := (others => "00000000"); 
signal DataByteArray2 : std_logic_vector(7 downto 0) := (others => "00000000"); 
signal DataByteArray3 : std_logic_vector(7 downto 0) := (others => "00000000"); 
signal DataByteArray4 : std_logic_vector(7 downto 0) := (others => "00000000"); 
signal DataByteArray5 : std_logic_vector(7 downto 0) := (others => "00000000"); 
signal DataByteArray6 : std_logic_vector(7 downto 0) := (others => "00000000"); 
signal DataByteArray7 : std_logic_vector(7 downto 0) := (others => "00000000"); 
signal DataByteArray8 : std_logic_vector(7 downto 0) := (others => "00000000"); 

signal TxDataReg1 : std_logic_vector(10 downto 0) := (others => "00000000"); 
signal TxDataReg2 : std_logic_vector(10 downto 0) := (others => "00000000"); 
signal TxDataReg3 : std_logic_vector(10 downto 0) := (others => "00000000"); 
signal TxDataReg4 : std_logic_vector(10 downto 0) := (others => "00000000"); 
signal TxDataReg5 : std_logic_vector(10 downto 0) := (others => "00000000"); 
signal TxDataReg6 : std_logic_vector(10 downto 0) := (others => "00000000"); 
signal TxDataReg7 : std_logic_vector(10 downto 0) := (others => "00000000"); 
signal TxDataReg8 : std_logic_vector(10 downto 0) := (others => "00000000"); 


signal count : unsigned(2 downto 0) := (others => '0'); 
signal one_bit : std_logic := '0'; 

begin 

Tx_Data <= Rx_Data_in; 

DataByteArray1 <= Rx_Data_in(7 downto 0); 
DataByteArray2 <= Rx_Data_in(15 downto 8); 
DataByteArray3 <= Rx_Data_in(23 downto 16); 
DataByteArray4 <= Rx_Data_in(31 downto 24); 
DataByteArray5 <= Rx_Data_in(39 downto 32); 
DataByteArray6 <= Rx_Data_in(47 downto 40); 
DataByteArray7 <= Rx_Data_in(55 downto 48); 
DataByteArray8 <= Rx_Data_in(63 downto 56); 



Process (tx_clk_in) 
begin 

-- Calculate the parity bit 
for i in 0 to 7 loop 

one_bit = DataByteArray1(i); 
if one_bit = '1' then 
count = count + 1; 
end if; 
end loop; 
-- For all the registers,one even parity & two stop bits I am trying to add in the end 
if count mod 2 = 0 then 
TxDataReg1 <= DataByteArray1&'0'&'11'; -- I am not so sure that this works or not 
count <= "000"; 
else 
TxDataReg1 <= DataByteArray1&'1'&'11'; 
count <= "000"; 
end if; 

-- Send the uart data from TxDataReg1,TxDataReg2 ... 
-- etc. 
end process; 
end behavioral; 

답변

1

이 UART는 상태 시스템을 만든 경우 훨씬 이해하기 쉬울 것입니다. State Machine은 코드에 체계적인 흐름을 제공합니다. 흐름이 더 합리적입니다. VHDL에서 enumerated states을 만들면 이름을 지정할 수 있습니다. 나는이 방법을 권장한다.

패리티 비트를 삽입 할 시점이나 UART 설계에 2 스톱 비트를 삽입 할시기를 정확히 알기 위해 카운터 전체를 설계하는 것이 훨씬 더 어렵습니다. 당신이 좋은 상태 기계를 가지고 있다면 그것은 내가 믿는 것에 훨씬 더 의미가있을 것입니다. 이는 특히 FPGA를 처음 사용하는 모든 사람들에게 권장됩니다.

패리티를 계산할 때 나가는 직렬 데이터가 XOR 인 패리티 비트를 계속 실행하십시오. 정확한 시간에 패리티 비트를 삽입하는 상태를 만든 다음 두 개의 정지 비트를 삽입하십시오. 이것의 예를 들어

, 나는 두 번째 제안은 한 번에 단지 바이트에서 작동하는 FSM을 사용하려면이를 재구성하는 것이 UART VHDL Code

0

봐. 그런 다음 범용 비동기를 사용하게됩니다. 다른 컨트롤러가 필요에 따라 바이트를 보낼 수있는 TX 엔티티.

데이터 관리에 관해서.

subtype byte is std_logic_Vector(7 downto 0); 

type byte_array is array(natural range <>) of byte; 

signal data_byte_array : byte_array(1 to 8); 
signal byte_index : unsigned(2 downto 0); 
... 
-- Select the current byte 
cur_byte <= data_byte_array(to_integer(byte_index)); 

아류가 꼭 필요한 것은 그러나 이렇게 많은 하드로 코드를 넘쳐에서 당신을 저장하는 일반적인 데이터 유형에 사용하는 좋은 습관이다 : 당신이 바이트 배열의 배열을 만든 경우 그것은 간단 할 것 코딩 된 배열 범위.

패리티를 계산하려면 세트 비트 계산의 소프트웨어 방식보다는 논리 게이트를 구현하는 하드웨어 사고 방식을 채택해야합니다. 패리티 계산은 벡터의 모든 비트에 적용된 XOR 감소 연산으로 끝납니다. 짝수 패리티의 경우 모든 비트를 XOR합니다. 홀수 패리티의 경우 모든 비트를 XOR하고 결과를 반전합니다. XOR은 제어 된 반전과 같기 때문에 초기 상태를 설정하고 하나의 추가 XOR을 수행하여 홀수 또는 짝수에 대한 사용자의 요구에 따라 선택적 반전을 가져 와서 패리티 유형을 선택할 수 있습니다.

-- Any VHDL: 
variable parity : std_logic; 

parity := '0'; -- Set to '1' to get odd parity 
for i in cur_byte'range loop 
    parity := parity xor cur_byte(i); 
end loop; 

-- VHDL-2002 
use ieee.reduce_pack.xor_reduce; 
parity := xor_reduce(cur_byte); 

-- VHDL-2008 
parity := xor cur_byte; 

이러한 합성 방식은 모두 같은 로직으로 종결되므로 모든 실제적인 목적을 위해 모두 괜찮습니다. 이것은 명시 적으로 병렬 연산이므로 카운터의 불필요한 오버 헤드로 비트를 비트 단위로 탐색하지 않아도됩니다.

비표준 Synopsys 라이브러리 std_logic_unsigned, _signed 및 _arith를 진정한 표준 숫자 라이브러리 numeric_std와 혼합하여 근본적인 죄를 범했습니다. 같은 파일에 이들을 섞어서 사용하지 마십시오. Synopsys 라이브러리를 전혀 사용하지 마십시오. 그들은 잊혀진 최고의 역사적인 수차입니다.

+0

그리고 11 비트의 TX 레지스터를 만들어 TX 포트에 값을 넣을 수있는 부분은 괜찮습니까? 연결 연산자 사용. 일부 상태 머신이 가능한 일종의 일종입니다. 나는 상태 머신 개념을 적용하는데 좋지 않다. – user3217310

+0

하위 타입이 반드시 타입 바이트를 선언 할 수있는 수단이 아니다. std_logic_Vector (7 downto 0)이다. ?byte_array는 byte 배열 (자연 범위 <>)입니다. ? – user3217310

+0

하위 유형이 상위 유형과 "밀접하게"관련되어 있기 때문에 가능합니다. 배열 부속 유형은 길이가 일치 할 때 자유롭게 상호 교환 가능합니다. –

관련 문제