我正在尝试构建一个具有左右移位功能的 16 位桶形移位器。我在如何构造代码方面遇到了一些问题,以便它可以做我想做的事情。
我有一个决定方向的操作码输入、一个要移位的输入向量、一个输出向量和一个 4 位的位置向量。
我正在使用位置向量以某种方式设置移位“级别”。我想检查位置(0),如果它设置为 1,则移动一个位置。然后检查 position(1) 和 shift 2 个位置, position(3) 4 个位置和 position(3) 8 个位置。
我认为,如果我遍历位置向量中的每个位置并顺序移动位,它最终应该会得到所有选项。当这个方向正常工作时,我将添加另一个操作码。
我坚持为架构分配中间向量。我不确定正确的方法应该是什么,我在谷歌中找不到任何东西。也许案例系统会更好地工作。
entity eds_shifter is
port ( a : in bit_vector(15 downto 0) ; --input
pos : in bit_vector(3 downto 0); -- position
opc : in bit_vector(3 downto 0); -- opcode
y : out bit_vector(15 downto 0) --output
);
end entity eds_shifter ;
architecture behavior of eds_shifter is
begin
process(a,pos,opc) -- input vectors
signal s1,s2,s3,s4 : bit_vector(15 downto 0); -- intermediate steps
begin
s1 <= a(14 downto 0) & '0' when pos(0) = '1' and opc = "0000" else -- shifting left by one
s1 <= a when pos(0) = '0' and opc = "0000" else -- carryover vector to next shift position
s2 <= s1(13 downto 0) & '0' when pos(1) = '1' and opc = "0000" else -- shift previous vector by 2
s2 <= s1 when pos(1) = '0' and opc = "0000" else
s3 <= s2(12 downto 0) & '0' when pos(2) = '1' and opc = "0000" else -- shift another 4 places
s3 <= s2 when pos(2) = '0' and opc = "0000" else
s4 <= s3(7 downto 0) & '0' when pos(3) = '1' and opc = "0000" else -- shift another 8 places
s4 <= s3 when pos(3) = '0' and opc = "0000" else
y <= s4 when opc = "0000";
end process;
end architecture behavior;
错误信息
** Error: */02/eds_shifter.vhd(14): Illegal sequential statement.
** Error: */02/eds_shifter.vhd(15): Type error resolving infix expression "<=" as type std.standard.bit_vector.
编辑
感谢您的详细回复。我知道有内置的通用移位功能,但我想尝试弄清楚如何自己实现它。
感谢您提供有关 bit_vector 的提示。据我了解,只有在您确定输入不是多源的时才可以使用位类型。在这种情况下,它可能应该没问题,但我会继续并记住它以备将来使用。
我认为我想尝试的概念是合理的。如果您检查位置中的每个位是否为 1 并在最后移动适当的数量,则移动的位数将等于位置向量的值。
a = "1111 1111 1111 1111" 和 pos = "1010" 所以我们需要移动小数点后 10 位。所以我们进行第一次迭代,它没有变化,第二次移动 2 位,第三次迭代移动 0 位,第四次移动 8 位,总共移动 10 位得到 a="1111 1100 0000 0000" .
我的问题不在于特定的移位操作(也许它是错误的,如果是这样将使用不同的方法,现在我只是好奇如何实现我的想法),我的问题是编写将更新向量然后检查的代码位置向量中的下一个位置。我正在查看您发布的有关增量周期和敏感度列表的内容。VHDL 可能会令人困惑,因为您必须根据通过处理器波动的操作来描述现实世界。它需要与标准编程不同的思维方式。
我尝试了下面的代码,但它只在我的测试台中改变和移动一次。我设置了一个测试台,它运行所有位置组合,但使用以下代码,它仅在 pos = 1000 处移动,然后移动 8 个位置。是否有任何强制代码检查每个 if 语句,而不仅仅是最后一个?
entity eds_shifter is
port ( a : in bit_vector(15 downto 0) ; --input
pos : in bit_vector(3 downto 0); -- position
opc : in bit_vector(3 downto 0); -- opcode
y : out bit_vector(15 downto 0) --output
);
end entity eds_shifter ;
architecture behavior of eds_shifter is
begin
process(a,pos,opc) -- input vectors
begin
if pos(0) = '1' and opc = "0000" then -- shifting left by one
y <= a(14 downto 0) & "0";
else
y <= a;
end if;
if pos(1) = '1' and opc = "0000" then -- shifting left by two
y <= a(13 downto 0) & "00";
else
y <= a;
end if;
if pos(2) = '1' and opc = "0000" then -- shifting left by four
y <= a(11 downto 0) & "0000";
else
y <= a;
end if;
if pos(3) = '1' and opc = "0000" then -- shifting left by eight
y <= a(7 downto 0) & "00000000";
else
y <= a;
end if;
end process;
结束架构行为;
试验台
entity eds_shifter_tb is
end eds_shifter_tb;
architecture behavior of eds_shifter_tb is
signal opc: bit_vector(3 downto 0);
signal pos: bit_vector(3 downto 0);
signal Y : bit_vector (15 downto 0);
signal a: bit_vector (15 downto 0);
begin
dut: entity work.eds_shifter(behavior)
port map(opc => opc,
pos => pos,
Y => Y,
a => a); -- assigns all ports to entity spec
a <= (others => '1'),
(others => '1') after 30 ns;
opc <= "0000",
"0001" after 30 ns;
pos <= "0000",
"0001" after 2 ns,
"0010" after 4 ns,
"0011" after 6 ns,
"0100" after 8 ns,
"0101" after 10 ns,
"0110" after 12 ns,
"0111" after 14 ns,
"1000" after 16 ns,
"1001" after 18 ns,
"1010" after 20 ns,
"1011" after 22 ns,
"1100" after 24 ns,
"1101" after 26 ns,
"1110" after 28 ns,
"1111" after 30 ns,
"0000" after 32 ns,
"0001" after 34 ns,
"0010" after 36 ns,
"0011" after 38 ns,
"0100" after 40 ns,
"0101" after 42 ns,
"0110" after 44 ns,
"0111" after 46 ns,
"1000" after 48 ns,
"1001" after 50 ns,
"1010" after 52 ns,
"1011" after 54 ns,
"1100" after 56 ns,
"1101" after 58 ns,
"1110" after 60 ns,
"1111" after 62 ns;
end behavior;