VHDL如何将32位变量转换为4 x 8位std_logic_vector?

时间:2013-09-22 20:03:55

标签: vhdl

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

我正在使用(标称32位)整数变量,我想将其写入8位UART为4字节(即作为二进制数据)

即。变量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。

2 个答案:

答案 0 :(得分:1)

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

  1. 将输出值注册为32位向量,并为每个输出操作使用不同的范围(正如您在代码示例中所做的那样)
  2. 将输出值注册为32位向量,并在每次输出操作后一次将此值移位8位。这样,您可以在所有操作中使用相同的范围。下面的代码应该给你一个想法:
  3. 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被声明为变量,但被指定为信号。

答案 1 :(得分:0)

您展示的代码没有任何问题。您可以使用Index将分配与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; 

Bytes accessed by index

或使用类型转换功能隐藏复杂性:

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;

并给出相同的答案。