【问题标题】:Design of a VHDL LUT ModuleVHDL LUT 模块的设计
【发布时间】:2014-03-25 11:10:28
【问题描述】:

说明: 我正在尝试将 vhdl 模块编写为具有 4 个输入和 3 个输出的 LUT(查找表)。我希望我的 3 位输出是一个二进制数,等于输入中 1 的个数。

我的真值表:

ABCD|XYZ
0000|000
0001|001
0010|001
0011|010
0100|011
0101|010
0110|010
0111|011
1000|001
1001|010
1010|010
1011|011
1100|010
1101|011
1110|011
1111|100

我的 VHDL 代码:

library IEEE;
use IEEE.STD_LOGIC_1164.all;

entity lut is
Port (
a : in STD_LOGIC; 
b : in STD_LOGIC; 
c : in STD_LOGIC; 
d : in STD_LOGIC; 
x : out STD_LOGIC; 
y : out STD_LOGIC; 
z : out STD_LOGIC);  

end lut;   

architecture Behavioral of lut is  
signal s0: STD_LOGIC;
signal s1: STD_LOGIC;
signal s2: STD_LOGIC;  
signal s3: STD_LOGIC;
signal s4: STD_LOGIC;
signal s5: STD_LOGIC;
signal s6: STD_LOGIC;
signal s7: STD_LOGIC; 
signal s8: STD_LOGIC;
signal s9: STD_LOGIC;
signal s10: STD_LOGIC;
signal s11: STD_LOGIC;
signal s12: STD_LOGIC;
signal s13: STD_LOGIC;

begin 
----------MUX1----------- 
process(a,b) 
begin
if a='0' 
then s0<=a;
else
s0<=b;
end if; 
end process; 

--------MUX2---------- 
process(a,b) 
begin
if a='0' 
then s1<=a;
else
s1<=b; 
end if;
end process;

---------MUX3-----------
process(a,b) 
begin
if a='0' 
then s2<=a;
else
s2<=b;
end if; 
end process;
---------MUX4-----------
process(a,b) 
begin
if a='0' 
then s3<=a;
else
s3<=b;
end if; 
end process;
---------MUX5-----------
process(c,d,a) 
begin
if a='0' 
then s4<=c;
else
s4<=d;
end if; 
end process;
---------MUX6-----------
process(c,d,a) 
begin
if a='0' 
then s5<=c;
else
s5<=d;
end if; 
end process;
---------MUX7-----------
process(c,d,a) 
begin
if a='0' 
then s6<=c;
else
s6<=d;
end if; 
end process;
---------MUX8-----------
process(c,d,a) 
begin
if a='0' 
then s7<=c;
else
s7<=d;
end if; 
end process;
---------MUX9-----------
process(s0,s1,b) 
begin
if b='0' 
then s8<=s0;
else
s8<=s1;
end if; 
end process;
---------MUX10-----------
process(s2,s3,b) 
begin
if b='0' 
then s9<=s2;
else
s9<=s3;
end if; 
end process;
---------MUX11-----------
process(s4,s5,b) 
begin
if b='0' 
then s10<=s4;
else
s10<=s5;
end if; 
end process;
---------MUX12-----------
process(s6,s7,b) 
begin
if b='0' 
then s11<=s6;
else
s11<=s7;
end if; 
end process;
---------MUX13-----------
process(s8,s9,c) 
begin
if c='0' 
then s12<=s8;
x<= s8;
else
s12<=s9;
x<= s9;
end if; 
end process;
---------MUX14-----------
process(s10,s11,c) 
begin
if c='0' 
then s13<=s10;
z<=s10;
else
s13<=s11; 
z<=s11
end if; 
end process; 
---------MUX15-----------
process(s12,s13,d) 
begin
if d='0' 
then y<=s12;
else
y<=s13;
end if; 
end process;
end Behavioral;

假设: 我总共需要 15 个多路复用器来模拟我需要的东西。它们将级联到一个输出。 如上所示,我总共有 15 个进程。

问题:
1.) 我对多路复用器 ABCD 的选择是什么?
2.)我是否以正确的方式建模?我能从给定的信息中实现我想要的吗?
3.)如果有更好的方法或者你有不同的想法,你能提供一个例子吗?
4.) 我没有得到我的 xyz 输出,它关闭了,但我做错了什么?

我已尝试提供尽可能多的研究。有什么问题我会第一时间回复的

【问题讨论】:

  • 你的真值表有 ABCD 和 XYZ。为什么您的 VHDL 代码没有 X、Y 或 Z,而是有 S1、F、G 和 H?另外,为什么您认为需要在 LUT 实现中使用任何 inout 端口?
  • 你的权利我没有改变,因为我在玩选择。反正我现在改了。我不需要输入输出端口。那么我正在努力做的事情是要工作还是我做错了?

标签: vhdl lookup-tables


【解决方案1】:

作为另一个“信任工具”的答案,如果您想计算工具,就这样做。你的代码会更清晰,合成器会做得非常好:

process(clk)
  variable count : unsigned(xyz'range)
begin
  if rising_edge(clk) then
     count := (others => '0');
     for i in abcd'range loop
        if abcd(i) = '1' then
           count := count + 1;
        end if;
     end loop;
     xyz <= count;
   end if;
end process;

我没有编译或模拟这个,但它应该给你的想法......当然,为了完整的代码清晰度,你可以将 count/loop 方面封装在一个名为 @987654324 的函数中@ 并从进程中调用它。

【讨论】:

  • +1 简洁明了。除非您发现这些工具正在可怕地综合您的设计,否则功能/行为方法几乎总是更容易维护。
  • 使用这种直接算法风格的另一个原因是原始帖子的真值表中的这个条目:0100|011。 2 年多来似乎没有人注意到这个错误!
【解决方案2】:

除非你只是为了好玩或学习而玩弄 VHDL,如果你想要 LUT,直接写成 LUT。可能没有理由将其展开为低级门和多路复用器。相反,只需描述您想要的行为,让 VHDL 为您完成工作:

例如,这里是您描述的组合逻辑 LUT 的简单 VHDL:

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

entity Number_of_Ones is
    port (
        --- mapped 3=a, 2=b, 1=c, 0=d
        abcd : in std_ulogic_vector(3 downto 0);
        -- mapped x=2, y=1, z=0
        xyz  : out std_ulogic_vector(2 downto 0);
    );
end entity;

architecture any of Number_of_Ones is
begin

    process (abcd) is
    begin
        case abcd is      
        --abcd|xyz
        when "0000" => xyz <= "000";
        when "0001" => xyz <= "001";
        when "0010" => xyz <= "001";
        when "0011" => xyz <= "010";
        when "0100" => xyz <= "011";
        when "0101" => xyz <= "010";
        when "0110" => xyz <= "010";
        when "0111" => xyz <= "011";
        when "1000" => xyz <= "001";
        when "1001" => xyz <= "010";
        when "1010" => xyz <= "010";
        when "1011" => xyz <= "011";
        when "1100" => xyz <= "010";
        when "1101" => xyz <= "011";
        when "1110" => xyz <= "011";
        when "1111" => xyz <= "100";
        end case;
    end process;
end architecture; 

如您所见,这正是您复制的真值表,并经过修改以适合 VHDL 语法。您当然可以用几种不同的方式编写它,并且您可能希望以不同的方式映射端口等,但这应该会让您走上正确的轨道。

【讨论】:

  • 我非常喜欢你上面的例子。我只是在学习 vhdl,我认为我必须将其解包为较低级别的东西,但我明白你的意思。谢谢
【解决方案3】:

我将在这里冒险并告诉您让您的合成器对其进行优化。除此之外,您可以在桌子上使用最小化器(例如 espresso),然后用 VHDL 编码结果。

我猜这应该是你在瞄准 FPGA 时应该做的:

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

entity bit_count is
    port (
        a,b,c,d:   in  std_logic;
        x,y,z:     out std_logic    
    );
end entity;

architecture lut of bit_count is
    subtype lutin is std_logic_vector (3 downto 0);
    subtype lutout is std_logic_vector (2 downto 0);
    type lut is array (natural range 0 to 15) of lutout;
    constant bitcount:   lut := (
        "000", "001", "001", "010", 
        "011", "010", "010", "011", 
        "001", "010", "010", "011",
        "010", "011", "011", "100"
        );

    signal temp:    std_logic_vector (2 downto 0);

begin

    temp <= bitcount( TO_INTEGER ( unsigned (lutin'(a&b&c&d) ) ) );

    (x, y, z) <= lutout'(temp(2), temp(1), temp(0));

end architecture;

如果我认为手动将其优化为 ROM 可能会在门数方面接近:

--  0000   0001   0010   0011
--  "000", "001", "001", "010", 
--  0100   0101   0110   0111
--  "011", "010", "010", "011", 
--  1000   1001   1010   1011
--  "001", "010", "010", "011",
--  1100   1101   1110   1111
--  "010", "011", "011", "100"

-- output         Input
-----------------------
-- bit 0  is true 0001 0010 0100 0111 1000 1011 1101 1111
-- bit 1          0011 0100 0101 0110 0111 1001 1010 1011 1100 1101 1110
-- bit 2          1111

architecture rom of bit_count is

    signal t0,t1,t2:    std_logic;
    signal t4,t7,t8:    std_logic;
    signal t11,t13,t14: std_logic;
    signal t15:         std_logic;

begin
-- terms
    t0  <= not a and not b and not c and not d;
    t1  <=     a and not b and not c and not d;
    t2  <= not a and     b and not c and not d;
--  t3  <=     a and     b and not c and not d;
    t4  <= not a and not b and     c and not d;
--  t5  <=     a and not b and     c and not d;
--  t6  <= not a and     b and     c and not d;
    t7  <=     a and     b and     c and not d;
    t8  <= not a and not b and not c and     d;
--  t9  <=     a and not b and not c and     d;
--  t10 <= not a and     b and not c and     d;
    t11 <=     a and     b and not c and     d;
--  t12 <= not a and not b and     c and     d;
    t13 <=     a and not b and     c and     d;
    t14 <= not a and     b and     c and     d;
    t15 <=     a and     b and     c and     d;

-- outputs

    x <= t15;

    y <= not ( t0 or t1 or t2 or t8 or t15 );

    Z <= t1 or t2 or t4 or t7 or t8 or t11 or t13 or t14;

end architecture;

它应该比链式多路复用器的门更少,并且更平坦(更快)。

这两种架构已经过分析但没有模拟。手工门级编码很容易出错。

【讨论】:

  • 我喜欢上面的代码,我不确定我是否遵循所有这些。我会更多地研究它以揭示正在发生的事情。谢谢
猜你喜欢
  • 1970-01-01
  • 2022-01-15
  • 2011-07-05
  • 1970-01-01
  • 1970-01-01
  • 2017-01-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多