首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >向8位std_logic_vector添加偶数奇偶校验位和2个停止位

向8位std_logic_vector添加偶数奇偶校验位和2个停止位
EN

Stack Overflow用户
提问于 2014-05-14 15:09:26
回答 2查看 1.4K关注 0票数 0

下面是代码:这里没有计算奇偶校验位。可以使用for循环来计算奇偶校验位,但是在这种情况下是否有其他更短或更好的方法来计算偶校验位。考虑到在创建数组之后,我希望逐位访问8位8位信号的数组,以便在uart_tx端口中发送数据,是否可以使用数组而不是8 TxDataReg std_logic_vector?

代码语言:javascript
复制
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;
EN

回答 2

Stack Overflow用户

发布于 2014-05-14 19:29:36

如果您创建了一个状态机,那么这个UART将更容易理解。状态机为您的代码提供了一个有组织的流程。这样的流程才更有意义。在VHDL语言中,你可以创建enumerated states,这意味着你可以给它们命名。我推荐这种方法。

在UART设计中,要准确知道何时插入奇偶校验位或何时插入2个停止位,在整个设计中保持计数器的难度要大得多。如果你有一个好的状态机,我相信它对你来说会更有意义。对于FPGA的新手来说,这是特别推荐的。

在计算奇偶校验时,只需保留一个运行的奇偶校验位,即可获得传出串行数据的XOR。创建一个状态以在正确的时间插入您的奇偶校验位,然后插入您的两个停止位。

有关这方面的示例,请查看此UART VHDL Code

票数 1
EN

Stack Overflow用户

发布于 2014-05-15 10:28:04

我赞同重新组织它的建议,以使用一次只处理一个字节的FSM。然后你就会有一个通用的异步。另一个控制器可以根据需要向其发送字节的TX实体。

来管理你的数据。如果您创建了一个字节数组的数组,则会更简单:

代码语言:javascript
复制
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-reduce操作。对于偶数奇偶校验,需要对所有位进行异或运算。对于奇数奇偶校验,您对所有位进行XOR运算并反转结果。由于XOR等效于受控反转,您可以通过设置初始状态并执行一次额外的XOR来选择奇偶校验类型,以根据您希望的奇数或偶数获得可选的反转。

代码语言:javascript
复制
-- 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
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/23647844

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档