【问题标题】:VHDL - Systolic Array: Single cells in an array of cells behave differently in simulationVHDL - 脉动阵列:单元阵列中的单个单元在模拟中表现不同
【发布时间】:2020-08-21 13:44:27
【问题描述】:

我目前正在尝试用 VHDL 编写一个基本的脉动数组来乘以 2 个 3x3 矩阵,因此是 AxB。我开始编写一个计算结果 = a0 * b0 + a1 * b1 + a2 * b2 的单元格。这个效果很好。单个单元格的 VHDL 代码如下所示:

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.numeric_std.ALL;


entity sys_cell is
    port 
    (   
        clk, reset : in std_ulogic; --active low
        a_in, b_in  : in    integer;
        a_out, b_out : out integer;
        
        result : out integer
    );
end sys_cell;


architecture sys_cell_behave of sys_cell is
                    
    signal counter : unsigned(3 downto 0) := "0000";
    signal sign_a_out, sign_b_out, sign_result : integer := 0;
begin

    result <= sign_result;

    counter_process : process (clk, reset)
    begin
        if (reset = '0') then
            counter <= "0000";
        elsif (rising_edge(clk)) then
            counter <= counter + 1;
        else
            NULL;
        end if;
    end process counter_process;
    
    result_process : process (counter)
    begin
        case(counter) is
            when "0000" =>
                sign_result <= 0;
            when others =>
                sign_result <= sign_result + (a_in * b_in);
        end case;
    end process result_process;
    
    output_process : process (counter)
    begin
        case(counter) is
            when "0000" =>
                a_out <= 0;
                b_out <= 0;
            when "0001" =>
                sign_a_out <= a_in;
                sign_b_out <= b_in;
            when others =>
                a_out <= sign_a_out;
                b_out <= sign_b_out;
                sign_a_out <= a_in;
                sign_b_out <= b_in;
        end case;
    end process output_process;
    
end sys_cell_behave;

Simulation of one cell

下一步,我将 9 个单元格放在一个数组中。 3x3 数组的代码如下所示:

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.numeric_std.ALL;


entity sys_array is
    port 
    (
        a0, a1, a2  :   in integer;
        b0, b1, b2  :   in integer;
        
        c00, c01, c02, c10, c11, c12, c20, c21, c22 :   out integer;
        
        reset, clk  :   in std_ulogic
    );
end sys_array;


architecture sys_array_behave of sys_array is
                    
    component sys_cell is
        port 
        (
            clk, reset : in std_ulogic; --active low
            a_in, b_in  : in    integer;
            a_out, b_out : out integer;
            
            result : out integer            
        );
    end component sys_cell;
    
    signal a_out_00, a_out_01, a_out_02, a_out_10, a_out_11, a_out_12, a_out_20, a_out_21, a_out_22 :   integer := 0;   
    signal b_out_00, b_out_01, b_out_02, b_out_10, b_out_11, b_out_12, b_out_20, b_out_21, b_out_22 :   integer := 0;
    
begin
    -- oben links
    sys_cell_00 : sys_cell
    port map
    (
        clk,
        reset,
        a0,
        b0,
        a_out_00,
        b_out_00,
        c00 
    );
    
    -- oben mitte
    sys_cell_01 : sys_cell
    port map
    (
        clk,
        reset,
        a_out_00,
        b1,
        a_out_01,
        b_out_01,
        c01
    );
    
    -- oben rechts
    sys_cell_02 : sys_cell
    port map
    (
        clk,
        reset,
        a_out_01,
        b2,
        open,
        b_out_02,
        c02
    );
    
    -- mitte links
    sys_cell_10 : sys_cell
    port map
    (
        clk,
        reset,
        a1,
        b_out_00,
        a_out_10,
        b_out_10,
        c10
    );
    
    -- mitte mitte
    sys_cell_11 : sys_cell
    port map
    (
        clk,
        reset,
        a_out_10,
        b_out_01,
        a_out_11,
        b_out_11,
        c11
    );
    
    -- mitte rechts
    sys_cell_12 : sys_cell
    port map
    (
        clk,
        reset,
        a_out_11,
        b_out_02,
        open,
        b_out_12,
        c12     
    );
    
    -- unten links
    sys_cell_20 : sys_cell
    port map
    (
        clk,
        reset,
        a2,
        b_out_10,
        a_out_20,
        open,
        c20
    );
    
    -- unten mitte
    sys_cell_21 : sys_cell
    port map
    (
        clk,
        reset,
        a_out_20,
        b_out_11,
        a_out_21,
        open,
        c21
    );
    
    -- unten rechts
    sys_cell_22 : sys_cell
    port map
    (
        clk,
        reset,
        a_out_21,
        b_out_12,
        open,
        open,
        c22
    );
            
    
end sys_array_behave;

模拟中出现的问题是每个单元格的计算结果都是错误的,除了第一个。我添加了模拟的图片。红线将 sys_cell_00 和 sys_cell_01 的信号分开。蓝色箭头表示这两个细胞的不同行为。为什么 sys_cell_00 计算结果而 sys_cell_01 不计算?唯一不同的信号是计数器值。但是“result_process”中的 vhdl 代码应该使它们的行为相同。 Simulation of the cell array

【问题讨论】:

  • 您的 sys_cell 组件的敏感度列表中缺少许多信号。具体来说,result_process 缺少 sign_result a_in 和 b_in 。 Output_process 缺少 a_in b_in 和 sign_a/b_out。修复此问题后,您将在 sign_result 上有一个逻辑循环,因为它会在异步进程中自我更新。

标签: arrays vhdl digital


【解决方案1】:

我已经重写了我的代码,它现在可以工作了。作为一个基本的开始,我现在有以下代码:

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.numeric_std.ALL;


entity sys_cell is
    port 
    (   
        clk, reset : in std_ulogic; --active low
        a_in, b_in  : in    integer;
        a_out, b_out : out integer;
        
        result : out integer
    );
end sys_cell;


architecture sys_cell_behave of sys_cell is
                    
    signal sign_result : integer := 0;

begin
    process(clk)
    begin
        if(reset = '1') then
            if (rising_edge(clk)) then
                sign_result <= sign_result + a_in * b_in;
                a_out <= a_in;
                b_out <= b_in;
            else 
                NULL;
            end if;
        else
            a_out <= 0;
            b_out <= 0;
            result <= 0;
            sign_result <= 0;
        end if;
        result <= sign_result;
    end process;
    
end sys_cell_behave;

3x3数组的代码没有改变

【讨论】:

  • 一些风格点。 1.您的复位名称暗示为高电平有效,但您在非高电平状态下复位。此外,通常,使用 if..else 样式时,reset 位于 if 分支中。 2. 用时钟空选择是没有意义的。 3.如果分支,结果分配应该在时钟内。
  • 关于您的顶级的另一个风格点。你应该看看generate for 语句,它们可以用来非常优雅地实例化你的 MxN 单元。
猜你喜欢
  • 2016-04-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-07-22
  • 1970-01-01
  • 1970-01-01
  • 2014-06-13
相关资源
最近更新 更多