1

我有一个问题可能分为两部分:

我正在使用一个(名义上为 32 位)整数变量,我想将它作为 4 个字节(即作为二进制数据)写入 8 位 UART

即变量Count:整数范围0到2147483647;

我应该如何按照我的 UART 代码的预期将 32 位整数变量切割成 4 个单独的 8 位 std_logic_vectors,我应该如何一次将这些传递给 UART 一个字节?

我知道 std_logic_vector(to_unsigned(Count, 32)) 会将整数变量转换为 32 位 std_logic_vector,但是然后呢?我是否应该创建一个 32 位 std_logic_vector,将转换后的 Count 值分配给它,然后使用类似于以下代码的内容对其进行细分?我意识到以下假设计数变量在 4 个时钟周期内没有变化,并假设 UART 可以在每个时钟周期接受一个新字节,并且缺乏任何重新触发 4 字节发送周期的方法,但我是对的在这里跟踪,还是有更好的方法?

variable CountOut  : std_logic_vector(31 downto 0);

process (clock)

   variable Index : integer range 0 to 4 := 0;

   begin

   if rising_edge(clock) then

      CountOut <= std_logic_vector(to_unsigned(Count, 32);

      if (Index = 0) then
         UartData(7 downto 0) <= CountOut(31 downto 24);
         Index := 1;
      elsif (Index = 1) then
         UartData(7 downto 0) <= CountOut(23 downto 16);
         Index := 2;
      elsif (Index = 2) then
         UartData(7 downto 0) <= CountOut(15 downto 8);
         Index := 3;
      elsif (Index =31) then
         UartData(7 downto 0) <= CountOut(7 downto 0);
         Index := 4;
      else
         Index := Index;
      end if;

   end if;

end process;

任何意见或建议将不胜感激。

谢谢,

MAI-AU。

4

2 回答 2

1

你似乎走在正确的轨道上。我相信这个问题有两个基本的解决方案:

  1. 将输出值注册为 32 位向量,并为每个输出操作使用不同的范围(如您在代码示例中所做的那样)
  2. 将输出值注册为 32 位向量,并在每次输出操作后将该值一次移位 8 位。这样,您可以在所有操作中使用相同的范围。下面的代码应该给你一个想法:
process (clock)
   variable Index: integer range 0 to 4 := 0;
begin
   if rising_edge(clock) then      
      if (Index = 0) then
         CountOut <= std_logic_vector(to_unsigned(Count, 32));
         Index := Index + 1;
      elsif (Index < 4) then
         UartData <= CountOut(31 downto 24);
         CountOut <= CountOut sll 8;
         Index := Index + 1;
      end if;
   end if;
end process;

另外,请检查您的分配,在您的示例中,CountOut 被声明为变量,但被分配为信号。

于 2013-09-22T21:56:07.400 回答
0

您显示的代码没有任何问题。您可以做一些事情来使用索引分离对 UartData 的分配以允许循环。

library ieee;
use ieee.std_logic_1164.all;

entity union is
end entity;

architecture foo of union is
    type union32 is array (integer range 1 to 4) of std_logic_vector(7 downto 0);
    signal UartData:    std_logic_vector(7 downto 0);
begin

TEST:
    process 
    variable quad:    union32;
    constant fourbytes:    std_logic_vector(31 downto 0) := X"deadbeef";
    begin

        quad := union32'(fourbytes(31 downto 24), fourbytes(23 downto 16),
                         fourbytes(15 downto 8),fourbytes(7 downto 0));

        for i in union32'RANGE loop
            wait for 9.6 us;
            UartData <= Quad(i);
        end loop; 

        wait for 9.6 us;  -- to display the last byte
        wait;  -- one ping only
    end process;
end architecture; 

索引访问的字节数

或者使用类型转换函数来隐藏复杂性:

library ieee;
use ieee.std_logic_1164.all;

entity union is
    type union32 is array (integer range 1 to 4) of std_logic_vector(7 downto 0);
end entity;

architecture fee of union is

    signal UartData:    std_logic_vector(7 downto 0);

    function toquad (inp: std_logic_vector(31 downto 0)) return union32 is
    begin
        return union32'(inp(31 downto 24), inp(23 downto 16),
                        inp(15 downto 8),  inp( 7 downto 0));
    end function;
begin

TEST:
    process 
    variable quad:    union32;
    constant fourbytes:    std_logic_vector(31 downto 0) := X"deadbeef";
    begin

        quad := toquad (fourbytes);

        for i in union32'RANGE loop
            wait for 9.6 us;
            UartData <= Quad(i);
        end loop; 

        wait for 9.6 us;  -- to display the last byte
        wait;  -- one ping only
    end process;
end architecture;

并给出了相同的答案。

于 2013-09-22T21:43:28.840 回答