基于行为体系结构的桶形移位器VHDL代码结构

基于行为体系结构的桶形移位器VHDL代码结构,vhdl,digital-logic,Vhdl,Digital Logic,我试图建立一个16位桶移位器与左,右移位能力。我对如何构造代码有一些问题,以便它能够完成我想做的事情 我有一个决定方向的操作码输入、一个要移位的输入向量、一个输出向量和一个4位的位置向量 我正在使用位置向量以某种方式设置移位“级别”。我想检查位置(0),如果设置为1,则移动一个位置。然后检查位置(1)和换档2位置、位置(3)4位置和位置(3)8位置 我认为,如果我遍历位置向量中的每个位置,并按顺序移位位,它最终应该会得到所有选项。当这个方向正常工作时,我将添加其他操作码 我一直在为架构分配中间向

我试图建立一个16位桶移位器与左,右移位能力。我对如何构造代码有一些问题,以便它能够完成我想做的事情

我有一个决定方向的操作码输入、一个要移位的输入向量、一个输出向量和一个4位的位置向量

我正在使用位置向量以某种方式设置移位“级别”。我想检查位置(0),如果设置为1,则移动一个位置。然后检查位置(1)和换档2位置、位置(3)4位置和位置(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;
实体eds\U移位器为
端口(a:位向量(15到0);--输入
位置:在位_向量中(从3向下到0);--位置
opc:位向量(3到0);--操作码
y:输出位_向量(15到0)——输出
);
终端实体eds_移位器;
eds_移位器的结构行为是
开始
过程(a、pos、opc)——输入向量
信号s1、s2、s3、s4:位_向量(15向下至0);--中间步骤
开始

s1代码中有几个问题:

  • 不能用作顺序语句时(在过程中;在VHDL-2008之前),以及
    else
    部分看起来也像一条语句,语法不正确

  • 信号
    无法在过程中声明

  • 信号的新值在可用之前需要一个增量周期,因此
    
    s*
    必须在灵敏度列表中,才能使值波动通过

  • VHDL提供了标准的移位函数,应该使用这些函数,而不是 家庭建造(这看起来甚至是错误的)。注意,VHDL在fix操作符中移位 (VHDL-2008之前)已知会产生意外结果,因此请使用函数 相反阅读更多

因此,基于此,带流程的代码可以更新为:

library ieee;
use ieee.numeric_bit.all;

architecture behavior of eds_shifter is
begin
  process(a, pos, opc)                                                   -- input vectors
  begin
    if opc = "0000" then  -- Shift left
      y <= bit_vector(shift_left(unsigned(a), to_integer(unsigned(pos))));
    else  -- Assuming shift right
      y <= bit_vector(shift_right(unsigned(a), to_integer(unsigned(pos))));
    end if;
  end process;
end architecture behavior;

注释>代码向量未被广泛使用,因此考虑更新使用

std\u logic\u vector
,代码可以是:

library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

entity eds_shifter is
  port (a   : in  std_logic_vector(15 downto 0);  --input
        pos : in  std_logic_vector(3 downto 0);   -- position
        opc : in  std_logic_vector(3 downto 0);   -- opcode
        y   : out std_logic_vector(15 downto 0)   --output
        );
end entity eds_shifter;

architecture behavior of eds_shifter is
begin

  y <= std_logic_vector(shift_left(unsigned(a), to_integer(unsigned(pos)))) when (opc = "0000") else
       std_logic_vector(shift_right(unsigned(a), to_integer(unsigned(pos))));

end architecture behavior;
ieee库;
使用ieee.std_logic_1164.all;
使用ieee.numeric_std.all;
实体eds_移位器为
端口(a:标准逻辑向量(15到0);--输入
位置:在标准逻辑向量(3向下到0);--位置
opc:标准逻辑向量(3到0);--操作码
y:输出标准逻辑向量(15到0)——输出
);
终端实体eds_移位器;
eds_移位器的结构行为是
开始
y在修改后的代码中:

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;
...

除非你最终想通过管道传输你的移位器,在这种情况下你应该回到中间信号,你还需要通过管道传输你的其他输入来匹配。但是,也许我们超越了自己…

我认为您对硬件描述与编写软件的区别以及过程如何在VHDL中工作缺乏全面的理解。这就是说,您可以使用多个并发分配来执行您想要的操作(级联式桶移位器)。请参见下面的模型:

-- note, entirely untested!
library ieee;
use ieee.std_logic_1164.all;

entity eds_shifter is
port ( a   : in  std_logic_vector(15 downto 0) ; --input
       pos : in  std_logic_vector(3 downto 0); -- position
       opc : in  std_logic_vector(3 downto 0); -- opcode
       y   : out std_logic_vector(15 downto 0) --output
    );
end entity eds_shifter ;

architecture behavior of eds_shifter is
    signal s1,s2,s3,s4 : std_logic_vector(15 downto 0); -- intermediate steps
begin
    --opcode 0000 is shift left, else is shift right
    s1 <= a(14 downto 0) & '0' when pos(0) = '1' and opc = "0000" else --maybe shift by 1 place
        '0' & a(15 downto 1) when pos(0) = '1' and opc /= "0000" else
        a;

    s2 <= s1(13 downto 0) & "00" when pos(1) = '1' and opc = "0000" else --maybe shift 2 places 
        "00" & s1(15 downto 2) when pos(1) = '1' and opc /= "0000" else
        s1;

    s3 <= s2(11 downto 0) & x"0" when pos(2) = '1' and opc = "0000" else --maybe shift 4 places
        x"0" & s2(15 downto 4) when pos(2) = '1' and opc /= "0000" else
        s2;

    s4 <= s3(7 downto 0) & x"00" when pos(3) = '1' and opc = "0000" else --maybe shift 8 places
        x"00" & s3(15 downto 8) when pos(3) = '1' and opc /= "0000" else
        s3;

    y <= s4;
end architecture behavior;
——注意,完全未经测试!
图书馆ieee;
使用ieee.std_logic_1164.all;
实体eds_移位器为
端口(a:标准逻辑向量(15到0);--输入
位置:在标准逻辑向量(3向下到0);--位置
opc:标准逻辑向量(3到0);--操作码
y:输出标准逻辑向量(15到0)——输出
);
终端实体eds_移位器;
eds_移位器的结构行为是
信号s1、s2、s3、s4:std_逻辑_向量(15向下至0);--中间步骤
开始
--操作码0000为左移,否则为右移

s1更安全的说法是,在VHDL-2008之前,条件信号赋值(当)不能用于进程语句(cond.sig.assign.作为顺序语句),并且可能不支持,不支持合成。参见IEEE标准1076-2008 10.5.3条件信号分配(其中§10为10.顺序语句)。也支持选定的信号分配。实际上,并发信号分配语句和顺序信号分配语句之间的合成没有区别。
y <= bit_vector(shift_left(unsigned(a), to_integer(unsigned(pos)))) when opc = "0000" else
     bit_vector(shift_right(unsigned(a), to_integer(unsigned(pos))));
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

entity eds_shifter is
  port (a   : in  std_logic_vector(15 downto 0);  --input
        pos : in  std_logic_vector(3 downto 0);   -- position
        opc : in  std_logic_vector(3 downto 0);   -- opcode
        y   : out std_logic_vector(15 downto 0)   --output
        );
end entity eds_shifter;

architecture behavior of eds_shifter is
begin

  y <= std_logic_vector(shift_left(unsigned(a), to_integer(unsigned(pos)))) when (opc = "0000") else
       std_logic_vector(shift_right(unsigned(a), to_integer(unsigned(pos))));

end architecture behavior;
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;
...
process (a, pos, opc)
  variable result : std_logic_vector(15 downto 0);
begin
  result := a;
  if pos(0) = '1' and opc = "0000" then
    result := result(14 downto 0) & '0';
  end if;
  if pos(1) = '1' and opc = "0000" then
    result := result(13 downto 0) & "00";
  end if;
  ...
  y <= result;
end process;
-- note, entirely untested!
library ieee;
use ieee.std_logic_1164.all;

entity eds_shifter is
port ( a   : in  std_logic_vector(15 downto 0) ; --input
       pos : in  std_logic_vector(3 downto 0); -- position
       opc : in  std_logic_vector(3 downto 0); -- opcode
       y   : out std_logic_vector(15 downto 0) --output
    );
end entity eds_shifter ;

architecture behavior of eds_shifter is
    signal s1,s2,s3,s4 : std_logic_vector(15 downto 0); -- intermediate steps
begin
    --opcode 0000 is shift left, else is shift right
    s1 <= a(14 downto 0) & '0' when pos(0) = '1' and opc = "0000" else --maybe shift by 1 place
        '0' & a(15 downto 1) when pos(0) = '1' and opc /= "0000" else
        a;

    s2 <= s1(13 downto 0) & "00" when pos(1) = '1' and opc = "0000" else --maybe shift 2 places 
        "00" & s1(15 downto 2) when pos(1) = '1' and opc /= "0000" else
        s1;

    s3 <= s2(11 downto 0) & x"0" when pos(2) = '1' and opc = "0000" else --maybe shift 4 places
        x"0" & s2(15 downto 4) when pos(2) = '1' and opc /= "0000" else
        s2;

    s4 <= s3(7 downto 0) & x"00" when pos(3) = '1' and opc = "0000" else --maybe shift 8 places
        x"00" & s3(15 downto 8) when pos(3) = '1' and opc /= "0000" else
        s3;

    y <= s4;
end architecture behavior;