我已经定义了一个数组
type stream_pix_rx is array(59 downto 0) of signed(31 downto 0);
signal pix_32_width : stream_pix_rx := (others => "00000000000000000000000000000000");
我在pix_32_width每个时钟接收32位。
我想分别使用8位的所有四个插槽。我有另一个8位数组:
type pix_rx is array(239 downto 0) of signed(8 downto 0);
signal pix_8_width : pix_rx := (others => "00000000");
I want to put pix_8_width(i) <= pix_32_width(j(first 8 bits));
then pix_8_width(i+1) <= pix_32_width(j(next 8 bits));
等等。
Edit_ADD: 我在每个时钟周期或事件处串行接收32位流,所以每当我收到32位(在一个事件之后),我想把它放在pix_8_width(0到3)中。当我收到下一个32位流时,我想把它放在pix_8_width(4到7)中,依此类推。 当我的第60个32位完成时,我希望在第一个32位流中接收它们并将其放入pix_8_width(0到3)等等...... 我该怎么办?
这种事情会很简单吗?
pix_32_width(i) <= unsigned(S_AXIS_TDATA);
pix_8_width(4*i to 4*i+3) <= pix_32_width(i);
i <= i + 1;
要了解我想要实现的事情的大局: 我问过一个问题 https://electronics.stackexchange.com/questions/109359/where-is-the-pixel-data-in-xilinx-axi-video-dma-ip-to-apply-a-sobel-filter-on 这有更多细节。
答案 0 :(得分:1)
由于您正在从一个数组表示转换为另一个数组表示而没有中间逻辑,因此您可以将其实现为转换函数:
function conv_32_to_8(p32: stream_pix_rx) return pix_rx is
variable p8 : pix_rx;
begin
for i in p32'range loop
for j in 0 to 3 loop
p8(i*4 + j) := p32(i)((j+1)*8 - 1 downto j*8);
end loop;
end loop;
return p8;
end function;
此函数以little-endian顺序隔离字节。要将其连接到big-endian,请将p8(i*4 + j)
替换为p8(i*4 + (3 - j))
。
要使用此功能,您可以实施连续分配,以便在pix_8_width
上发生事件时更新pix_32_width
:
pix_8_width <= conv_32_to_8(pix_32_width);
如果您想控制转换何时完成,也可以在流程中调用它。
最后。您可以使用(others => (others => '0'))
简化阵列初始化。这样可以省去尝试为内部数组输入正确数量的零的麻烦。
答案 1 :(得分:1)
您的Edit_ADD意味着单个数组类型:
我在每个时钟周期或者串行接收32位流 事件,所以每当我收到一个32位(在一个事件之后)我想放 它在pix_8_width(0到3)。当我收到下一个32位流 我想把它放在pix_8_width(4到7)中,依此类推。而当我的第60个32 比特完成我想在第一个32比特流接收它们并把它 在pix_8_width(0到3)等等...... 我该怎么做 ?
强调添加
听起来像是一个环形缓冲区。
对于内存,您永远不必同时从写入侧或读取侧访问完整阵列。存储器阵列可以是一种类型或另一种类型。你不需要两者之间的联合。您可以在输入侧或输出侧进行转换。
此示例显示可以在pixel_rx数组类型中组织内存:
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity pix_ringbuff is
port (
clk: in std_logic;
reset_n: in std_logic;
pixel32w: in signed (31 downto 0);
wrptr: in unsigned(5 downto 0);
wr_en: in std_logic;
rdptr: in unsigned(7 downto 0);
pixel8w: out signed (7 downto 0)
);
end entity;
architecture fum of pix_ringbuff is
-- The memory array:
type pix_rx is array(239 downto 0) of signed(7 downto 0);
signal pix_8_width : pix_rx := (others => (others => '0'));
begin
WRITE:
process(clk, reset_n)
variable wrt_ptr: natural range 0 to 239;
begin
if reset_n = '0' then
pix_8_width <= (others => (others => '0'));
elsif rising_edge(clk) and wr_en ='1' then
wrt_ptr := to_integer(wrptr) * 4;
pix_8_width(wrt_ptr) <= pixel32w(31 downto 24);
pix_8_width(wrt_ptr + 1) <= pixel32w(23 downto 16);
pix_8_width(wrt_ptr + 2) <= pixel32w(15 downto 8);
pix_8_width(wrt_ptr + 3) <= pixel32w(7 downto 0);
end if;
end process;
READ:
process (rdptr, pix_8_width)
begin
pixel8w <= pix_8_width(to_integer(rdptr));
end process;
end architecture;
缺少的是用于发出即将发生的翻转,空状态,高水位或低水位标记的信号。这些内容与指针(计数器)一样在内存中,指针显示为无符号,看到你使用了签名的像素数据。
注意所有4个像素都写在一个时钟中。字节Endian顺序与您所需的分配匹配:
pix_8_width(4*i to 4*i+3) <= pix_32_width(i);
这不起作用,因为一边是pix_rx,另一边是stream_pix_rx。
使用目标聚合:
(pix_8_width(i*4), pix_8_width(i*4+1),
pix_8_width(i*4+2), pix_8_width(i*4+3)) <=
pixel32'(
pixel32w(31 downto 24),
pixel32w(23 downto 16),
pixel32w(15 downto 8),
pixel32w(7 downto 0)
);
不应该起作用,目标聚合元素不是静态的。 IEEE Std 1076-1993 8.4信号分配声明(-2008,10.5 / 10.5.2.1):
如果信号赋值语句的目标是a的形式 聚合,那么聚合的类型必须是可以确定的 上下文,不包括聚合本身,但包括事实 聚合的类型必须是复合类型。基本类型 波形产生的每个事务的值组件 右侧的元素必须与基本类型相同 总计。此外, 中的表达式与每个元素关联 聚合必须是一个表示信号的本地静态名称 。 这种形式的信号分配指定了切片或子元素 与命名信号关联的驱动程序的右侧值 作为聚合的相应切片或子元素。
强调添加
包含i声明为变量的表达式或指定切片范围的信号不是局部静态的,这意味着在分析时进行评估。
您可以使用聚合将一种数组类型分配给另一种。它必须列出每个元素,并且会在聚合本地静态时占用大量源代码。
您的原始作业附近有一些内容:
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity footest is
end entity;
architecture foo of footest is
type stream_pix_rx is array(0 to 59) of signed(31 downto 0);
signal pix_32_width : stream_pix_rx :=
(X"FEEDFACE",X"DEADBEEF",
X"00010203",X"04050607",others => (others => '0'));
type pix_rx is array(0 to 239) of signed(7 downto 0);
signal pix_8_width : pix_rx := (others => (others => '0'));
signal i: natural range 0 to 59 := 42;
begin
pix_8_width (i*4 to i*4+3) <=
(
pix_32_width(i)(31 downto 24),
pix_32_width(i)(23 downto 16),
pix_32_width(i)(15 downto 8),
pix_32_width(i)(7 downto 0)
);
STIM:
process
begin
for j in stream_pix_rx'range loop
if j = 59 then
wait;
else
wait for 10 ns;
end if;
i <= j;
end loop;
end process;
end architecture;
给出了:
左侧不是聚合体,不需要是静态的。请注意,阵列类型范围已从降序转换为升序,以使左侧切片与建议的信号分配相匹配。