Generics 使用;For Loop";用于通用VHDL代码中的寻址方法

Generics 使用;For Loop";用于通用VHDL代码中的寻址方法,generics,vhdl,addressing-mode,Generics,Vhdl,Addressing Mode,这是我第一次发帖,所以我会尽量说得更具体一些 在我将要发布的代码部分中,我试图以一种通用的方式实现我注释掉的“Case”-表达式中的代码。这段代码是一个更大的实现的一部分,我只保留了这段代码中当前使用的信号 因此,我希望我的输出“kin”和“din”是通用的,并且根据地址总线“bus_a”中的输入,寄存器“kin_2”和“din_2”的正确字(2字节长)应该填充“bus_di”的值当时的输入 在这里的示例中,我将使用“kin”和“din”的原始长度,每个长度为128位。因此,对于128位长度,N

这是我第一次发帖,所以我会尽量说得更具体一些

在我将要发布的代码部分中,我试图以一种通用的方式实现我注释掉的“Case”-表达式中的代码。这段代码是一个更大的实现的一部分,我只保留了这段代码中当前使用的信号

因此,我希望我的输出“kin”“din”是通用的,并且根据地址总线“bus_a”中的输入,寄存器“kin_2”“din_2”的正确字(2字节长)应该填充“bus_di”的值当时的输入

在这里的示例中,我将使用“kin”“din”的原始长度,每个长度为128位。因此,对于128位长度,N=16(16*8位=128位)和K=8

library IEEE;
use IEEE.NUMERIC_STD.ALL;
use IEEE.STD_LOGIC_1164.ALL;

entity stck_if is
    generic (N: integer:=16; K: integer:=8);

    port (  -------------- Clock and Reset
        clk: in std_logic;
        rst: in std_logic;


        bus_a: in std_logic_vector (15 downto 0); -- Address
        bus_di: in std_logic_vector (15 downto 0); --Data In

        kin: out std_logic_vector (8*N-1 downto 0);  
        din: out std_logic_vector (8*N-1 downto 0));    

end stck_if;

architecture stck_if_arch of stck_if is

        signal kin_2: std_logic_vector (8*N-1 downto 0);
        signal din_2: std_logic_vector (8*N-1 downto 0);
        signal encdec_2: std_logic;

        signal trig_wr: std_logic;

        begin

            proc1: process(clk,rst)
                variable int_add: integer:=0;
                variable add: std_logic_vector (15 downto 0);
                variable bit_add: std_logic_vector (15 downto 0);
                begin
                    if rst='1' then
                        encdec_2<='0';  
                        kin_2<=(others =>'0');
                        din_2<=(others =>'0');
                    elsif (clk'event and clk='1') then
                        if (trig_wr = '1') then

                            if (bus_a = "0000000000001100") then
                                    encdec_2 <= bus_di(0);
                            end if;

                            for i in 0 to K-1 loop
                                bit_add:="0000000100000000";
                                int_add:= 2*i;
                                add:=std_logic_vector(to_unsigned(int_add, 16));
                                bit_add:= std_logic_vector(unsigned(bit_add) + unsigned(add));
                                if (bus_a = bit_add) then
                                        kin_2((8*(N-int_add)-1) downto 8*(N-int_add)) <= bus_di;
                                end if;                             
                            end loop;


                            for i in 0 to K-1 loop
                                bit_add:="0000000101000000";
                                int_add:= 2*i;
                                add:=std_logic_vector(to_unsigned(int_add, 16));
                                bit_add:= std_logic_vector(unsigned(bit_add) + unsigned(add));
                                if (bus_a = bit_add) then
                                        din_2((8*(N-int_add)-1) downto 8*(N-int_add)) <= bus_di;
                                end if;                             
                            end loop;   



                            --case bus_a is
                            --  when "0000000000001100"=> encdec_2 <= bus_di(0);    --bus_a = 000C hex
                            --  when "0000000100000000"=> kin_2(127 downto 112) <= bus_di;  --bus_a = 0100 hex
                            --  when "0000000100000010"=> kin_2(111 downto 96) <= bus_di;   --bus_a = 0102 hex
                            --  when "0000000100000100"=> kin_2(95 downto 80) <= bus_di;    --bus_a = 0104 hex
                            --  when "0000000100000110"=> kin_2(79 downto 64) <= bus_di;    --bus_a = 0106 hex                                                                          
                            --  when "0000000100001000"=> kin_2(63 downto 48) <= bus_di;    --bus_a = 0108 hex
                            --  when "0000000100001010"=> kin_2(47 downto 32) <= bus_di;    --bus_a = 010A hex
                            --  when "0000000100001100"=> kin_2(31 downto 16) <= bus_di;    --bus_a = 010C hex
                            --  when "0000000100001110"=> kin_2(15 downto 0) <= bus_di; --bus_a = 010E hex

                            --  when "0000000101000000"=> din_2(127 downto 112) <= bus_di;  --bus_a = 0140 hex
                            --  when "0000000101000010"=> din_2(111 downto 96) <= bus_di;   --bus_a = 0142 hex
                            --  when "0000000101000100"=> din_2(95 downto 80) <= bus_di;    --bus_a = 0144 hex
                            --  when "0000000101000110"=> din_2(79 downto 64) <= bus_di;    --bus_a = 0146 hex                                                                          
                            --  when "0000000101001000"=> din_2(63 downto 48) <= bus_di;    --bus_a = 0148 hex
                            --  when "0000000101001010"=> din_2(47 downto 32) <= bus_di;    --bus_a = 014A hex
                            --  when "0000000101001100"=> din_2(31 downto 16) <= bus_di;    --bus_a = 014C hex
                            --  when "0000000101001110"=> din_2(15 downto 0) <= bus_di; --bus_a = 014E hex
                            --  when others => null;                    
                            --end case;
                        end if;
                    end if;
            end process;



            kin <= kin_2;
            din <= din_2;

end stck_if_arch;
虽然代码在编译时没有给出任何错误,但在模拟期间ModelSim会给出以下错误:

  • 由于致命错误,无法继续。 HDL呼叫序列: 在C:/Modeltech_pe_edu_10.4a/examples/stack.vhd 53 ForLoop循环停止
据我所知,问题在于“For-Loop”的使用以及我的假设,一定是VHDL无法转换以下表达式:

kin_2((8*(N-int_add)-1) downto 8*(N-int_add)) <= bus_di;

kinu 2((8*(N-int-u-add)-1)下至8*(N-int-u-add))以下版本在功能上应该与您的版本相同,更短,并且在我看来更容易阅读。然而,我不知道合成结果会是什么。我发现很难想象在带有变量的单进程描述中会出现哪些推断原语

architecture stck_if_arch of stck_if is
  signal kin_2: std_logic_vector (8*N-1 downto 0);
  signal din_2: std_logic_vector (8*N-1 downto 0);
  signal encdec_2: std_logic;
  signal trig_wr: std_logic;  
begin
  proc1: process(clk,rst)
    variable high: unsigned(9 downto 0);
    variable bid: integer range 0 to N-1;
    variable left, right: integer range 0 to 8*N-1;
  begin
    if rst='1' then
      encdec_2<='0';  
      kin_2<=(others =>'0');
      din_2<=(others =>'0');
    elsif (clk'event and clk='1') then
      if (trig_wr = '1') then

        high := unsigned(bus_a(15 downto 6));
        bid := to_integer(unsigned(bus_a(5 downto 1)));
        left := 16*(8-bid)-1;
        right := 16*(7-bid);

        if bus_a="0000000000001100" then
          encdec_2 <= bus_di(0);
        elsif bus_a(0)='0' then
          if high=4 then
            kin_2(left downto right) <= bus_di;
          elsif high=5 then
            din_2(left downto right) <= bus_di;
          end if;
        end if;

      end if;
    end if;
  end process;

 kin <= kin_2;
 din <= din_2;

end stck_if_arch;
architecture stck\u if\u stck\u的拱门
信号KINU 2:标准逻辑矢量(8*N-1向下至0);
信号din_2:std_逻辑_向量(8*N-1向下至0);
信号encdec_2:标准逻辑;
信号触发wr:标准逻辑;
开始
过程1:过程(时钟、rst)
变量高:无符号(9到0);
变量bid:从0到N-1的整数范围;
变量左、右:整数范围0到8*N-1;
开始
如果rst='1',则

下面的版本在功能上应该与你的版本相同,更短,而且——以我的拙见——更容易阅读。然而,我不知道合成结果会是什么。我发现很难想象在带有变量的单进程描述中会出现哪些推断原语

architecture stck_if_arch of stck_if is
  signal kin_2: std_logic_vector (8*N-1 downto 0);
  signal din_2: std_logic_vector (8*N-1 downto 0);
  signal encdec_2: std_logic;
  signal trig_wr: std_logic;  
begin
  proc1: process(clk,rst)
    variable high: unsigned(9 downto 0);
    variable bid: integer range 0 to N-1;
    variable left, right: integer range 0 to 8*N-1;
  begin
    if rst='1' then
      encdec_2<='0';  
      kin_2<=(others =>'0');
      din_2<=(others =>'0');
    elsif (clk'event and clk='1') then
      if (trig_wr = '1') then

        high := unsigned(bus_a(15 downto 6));
        bid := to_integer(unsigned(bus_a(5 downto 1)));
        left := 16*(8-bid)-1;
        right := 16*(7-bid);

        if bus_a="0000000000001100" then
          encdec_2 <= bus_di(0);
        elsif bus_a(0)='0' then
          if high=4 then
            kin_2(left downto right) <= bus_di;
          elsif high=5 then
            din_2(left downto right) <= bus_di;
          end if;
        end if;

      end if;
    end if;
  end process;

 kin <= kin_2;
 din <= din_2;

end stck_if_arch;
architecture stck\u if\u stck\u的拱门
信号KINU 2:标准逻辑矢量(8*N-1向下至0);
信号din_2:std_逻辑_向量(8*N-1向下至0);
信号encdec_2:标准逻辑;
信号触发wr:标准逻辑;
开始
过程1:过程(时钟、rst)
变量高:无符号(9到0);
变量bid:从0到N-1的整数范围;
变量左、右:整数范围0到8*N-1;
开始
如果rst='1',则

Encdecu_2我的想法与U.Martinez-Corral的想法相同,但有点扭曲:

architecture foo of stck_if is
    type N_array is array (0 to K - 1) of std_logic_vector(N - 1 downto 0);
    signal kin_2: N_array;
    signal din_2: N_array;
    signal encdec_2: std_logic;
    signal trig_wr: std_logic := '1'; -- ;  -- FOR TESTING without FORCE
begin

proc1: 
    process(clk,rst)
        variable high: unsigned(9 downto 0);
        variable Kidx: integer range 0 to K-1;
    begin
        if rst = '1' then
            encdec_2 <= '0';  
            kin_2 <= (others => (others => '0'));
            din_2 <= (others => (others => '0'));
        elsif rising_edge(clk) then
            if trig_wr = '1' then
                high := unsigned(bus_a (15 downto 6));
                Kidx := to_integer(unsigned(bus_a(3 downto 1)));
                if bus_a = "0000000000001100" then
                    encdec_2 <= bus_di(0);
                elsif bus_a(0) = '0' then
                    if high = 4 then
                        kin_2(kidx) <= bus_di;
                    elsif high = 5 then
                        din_2(kidx) <= bus_di;
                    end if;
                end if;
            end if;
        end if;
    end process;

UNION:
    if K = 8 generate
        kin <= kin_2(0) & kin_2(1) & kin_2(2) & kin_2(3) & 
               kin_2(4) & kin_2(5) & kin_2(6) & kin_2(7);
        din <= din_2(0) & din_2(1) & din_2(2) & din_2(3) & 
               din_2(4) & din_2(5) & din_2(6) & din_2(7);
    end generate;  -- GENERATE statement for every usable K value

end architecture foo;
stck\U的架构foo如果是 N_型数组是标准_逻辑_向量(N-1到0)的数组(0到K-1); 信号kinu 2:N_阵列; 信号din_2:N_阵列; 信号encdec_2:标准逻辑; 信号触发波形:标准逻辑:='1';-->用于无力测试 开始 程序1: 过程(时钟、rst) 变量高:无符号(9到0); 变量Kidx:从0到K-1的整数范围; 开始 如果rst='1',则 encdec_2'0'); din_2(其他=>“0”); elsif上升沿(clk)则 如果trig_wr='1',则 高:=无符号(总线a(15至6)); Kidx:=to_整数(无符号(总线a(3到1)); 如果总线a=“0000000000001100”,则
Encdecu_2我的想法与U.Martinez-Corral的想法相同,但有点扭曲:

architecture foo of stck_if is
    type N_array is array (0 to K - 1) of std_logic_vector(N - 1 downto 0);
    signal kin_2: N_array;
    signal din_2: N_array;
    signal encdec_2: std_logic;
    signal trig_wr: std_logic := '1'; -- ;  -- FOR TESTING without FORCE
begin

proc1: 
    process(clk,rst)
        variable high: unsigned(9 downto 0);
        variable Kidx: integer range 0 to K-1;
    begin
        if rst = '1' then
            encdec_2 <= '0';  
            kin_2 <= (others => (others => '0'));
            din_2 <= (others => (others => '0'));
        elsif rising_edge(clk) then
            if trig_wr = '1' then
                high := unsigned(bus_a (15 downto 6));
                Kidx := to_integer(unsigned(bus_a(3 downto 1)));
                if bus_a = "0000000000001100" then
                    encdec_2 <= bus_di(0);
                elsif bus_a(0) = '0' then
                    if high = 4 then
                        kin_2(kidx) <= bus_di;
                    elsif high = 5 then
                        din_2(kidx) <= bus_di;
                    end if;
                end if;
            end if;
        end if;
    end process;

UNION:
    if K = 8 generate
        kin <= kin_2(0) & kin_2(1) & kin_2(2) & kin_2(3) & 
               kin_2(4) & kin_2(5) & kin_2(6) & kin_2(7);
        din <= din_2(0) & din_2(1) & din_2(2) & din_2(3) & 
               din_2(4) & din_2(5) & din_2(6) & din_2(7);
    end generate;  -- GENERATE statement for every usable K value

end architecture foo;
stck\U的架构foo如果是 N_型数组是标准_逻辑_向量(N-1到0)的数组(0到K-1); 信号kinu 2:N_阵列; 信号din_2:N_阵列; 信号encdec_2:标准逻辑; 信号触发波形:标准逻辑:='1';-->用于无力测试 开始 程序1: 过程(时钟、rst) 变量高:无符号(9到0); 变量Kidx:从0到K-1的整数范围; 开始 如果rst='1',则 encdec_2'0'); din_2(其他=>“0”); elsif上升沿(clk)则 如果trig_wr='1',则 高:=无符号(总线a(15至6)); Kidx:=to_整数(无符号(总线a(3到1)); 如果总线a=“0000000000001100”,则
请注意,范围
n-1到n
是一个空范围:用作向量内的子范围,它描述了一个没有元素的向量。但这本身并不是致命的错误。有关于宽度不匹配的信息吗?@BrianDrummond你说的范围是对的!我在错误消息的开头再次检查,出现的第一个错误(蓝色?!)说:致命:(vsim-3420)数组长度不匹配。左边是0(127到128(空数组))。右边是16(15到0)。我通过在第二个“int_add”处添加“+2”来修复它。现在命令如下:kinu 2((8*(N-int\u add)-1)down to 8*(N-(int\u add+2)))注意,范围
N-1 down to N
是一个空范围:用作向量内的子范围,它描述了一个没有元素的向量。但这本身并不是致命的错误。有关于宽度不匹配的信息吗?@BrianDrummond你说的范围是对的!我在错误消息的开头再次检查,出现的第一个错误(蓝色?!)说:致命:(vsim-3420)数组长度不匹配。左边是0(127到128(空数组))。右边是16(15到0)。我通过在第二个“int_add”处添加“+2”来修复它。现在命令如下:kinu 2((8*(N-int-u-add)-1)下到8*(N-(int-u-add+2)),我想您可以使用
UNION: 
    for x in K - 1 downto 0 generate 
        kin(N * (x + 1) - 1 downto N * x) <= kin_2(K - 1 - x); 
        din(N * (x + 1) - 1 downto N * x) <= din_2(K - 1 - x); 
    end generate;