具有行为架构的桶式移位器的VHDL代码结构 [英] Structure of VHDL code for barrel shifter with behavior architecture

查看:122
本文介绍了具有行为架构的桶式移位器的VHDL代码结构的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试构建一个具有左右移位功能的16位桶形移位器.我在如何构造代码方面遇到一些问题,以便它可以执行我想做的事情.

I am trying to build a 16 bit barrel shifter with left and right shift capabilities. I am having some issues with how to structure the code so that it will do what I think I want to do.

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

I have an opcode input that decides on the direction, an input vector to be shifted, an output vector, and a position vector with 4 bits.

我正在使用位置矢量以某种方式设置移位级别".我要检查position(0),如果将其设置为1,则将其移动一个位置.然后检查position(1)并移动2个位置,position(3)4个位置,position(3)8个位置.

I am using the position vector to set a shift 'level' in a way. I want to check position(0) and if it is set to 1, shift one position. And then check position(1) and shift 2 positions, position(3) 4 positions, and position(3) 8 positions.

我认为,如果我遍历位置向量中的每个位置并顺序移位这些位,则最终应该获得所有选项.当此方向正常运行时,我将添加其他操作码.

I think that if I run through every position in the position vector and sequentially shift the bits it should eventually get all options. I will add the other opcode when this direction works properly.

我一直在为架构分配中间向量.我不确定应该使用哪种正确的方法,也无法在google中找到任何内容.案例系统可能会更好.

I am stuck on the assigning the intermediate vectors for the architecture. I am not sure what the proper method should be and I can not find anything in google. Perhaps a Case system would work better.

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.

编辑

感谢您的详细回复.我知道内置了通用移位函数,但我想尝试自己弄清楚如何实现它.

Thank you for the detailed response. I understand that there are generic shift functions built in but I want to try to figure out how to implement it myself.

感谢有关bit_vector的提示.据我了解,只有当您确定输入不是多源的时,才可以使用位类型.在这种情况下,应该没问题,但我会继续考虑,以备将来使用.

Thanks for the tip about the bit_vector. From what I understand bit types are only ok to use when you are sure that the input is not multisourced. In this case it should probably be ok, but I will go ahead and keep it in mind for the future.

我认为我想尝试的概念是合理的.如果您检查每个位置的位是否为1,并在最后移位适当的数量,则移位的位数将等于位置向量的值.

I think the concept I want to try is sound. If you check each bit in position for a 1 and shift by the appropriate amount at the end the number of bits shifted will equal the value of the position vector.

a ="1111 1111 1111 1111"和pos ="1010",因此我们需要将小数点后十位移位.因此,我们进行了第一次迭代,并且没有任何变化,第二次移位了2位,第三次移位了0位,第四次移位了8位,总共移位了10位,得出a ="1111 1100 0000 0000" .

a = "1111 1111 1111 1111" and pos = "1010" so we need to shift by decimal 10 places. So we do the first iteration and it has no change, the second shifts by 2 bits, third iteration shifts by 0 bits, and the fourth shifts by 8 bits for a total of 10 bits shifted to get a="1111 1100 0000 0000".

我的问题不在于特定的移位操作(也许是错误的,如果这样会使用不同的方法,现在我只是很好奇如何实现我的想法),我的问题是编写可更新向量的代码然后检查位置向量中的下一个位置.我正在查看您发布的有关增量周期和灵敏度列表的信息. VHDL可能会造成混乱,因为您必须按照通过处理器运行的操作来描述现实世界.与标准编程相比,它需要不同的思维.

My issue is not with the specific shifting operation (perhaps it is wrong and if so will use a different method, right now I am simply curious about how to implement my idea), my issue is writing code that will update the vector and then check the next position in the position vector. I was looking at what you posted about the delta cycle and sensitivity list. VHDL can be confusing since you have to describe the real world in terms of operations rippling through a processor. And it requires a different thinking than with standard programming.

我尝试了下面的代码,但是它只在测试台中更改和移动一次.我建立了一个测试台,可以运行所有位置组合,但是使用以下代码,它仅在pos = 1000时移动,然后才移动8个位置.是否有任何强制代码在每个if语句(不仅是最后一个)上检查的内容?

I tried the below code but it only changes and shifts in my test bench once. I set up a test bench that runs through all combinations of positions but with the following code it only shifts at pos = 1000 and then it shifts 8 places. Is there any of forcing the code to check at each if statement, not only the last one?

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;

推荐答案

我认为您缺少对硬件描述与编写软件的不同之处以及进程在VHDL中如何工作的完整理解.也就是说,您可以使用多个并发分配来执行所需的操作(级联样式的桶形移位器).参见下面的模型:

I think you're missing a complete understanding of how hardware description differs from writing software and how processes work in VHDL. That said, you can use several concurrent assignments to do what you want (a cascade style barrel shifter). See the model below:

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

通常建议使用的完成转移的方法仍然使用内置函数,并且如果优化器正在执行其工作,则它们很可能会变成相同的硬件后合成.尽管这样的练习有助于理解硬件的工作原理,但要意识到这样做并没有多大用处,并且对于大型项目的一小部分而言,它无用,因为这样做会增加代码大小并降低可读性,无济于事.

The recommended method of accomplishing shifting in general remains using the built-in functions, and they will likely turn into the same hardware post-synthesis if the optimizer is doing its job. While exercises like this are good for understanding how hardware works, realize that this is no more efficient, and it isn't useful as a small component of a larger project because it will increase code size and reduce readability for no benefit.

这篇关于具有行为架构的桶式移位器的VHDL代码结构的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆