2013-09-22 194 views
1

我有一个问题,其可能是在2个部分:VHDL如何将32位变量转换为4 x 8位std_logic_vector?

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

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

我应该如何砍32位整型变量为4个独立的8位std_logic_vectors我的UART代码如预期,我应该如何通过这些给UART一个字节的时间?

我知道std_logic_vector(to_unsigned(计数,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。

回答

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; 

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; 

,并给出了相同的答案。

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被声明为一个变量,但被分配到一个信号。