首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何通过消除嵌套if-else语句简化顺序逻辑设计

如何通过消除嵌套if-else语句简化顺序逻辑设计
EN

Stack Overflow用户
提问于 2021-06-02 00:17:04
回答 1查看 132关注 0票数 0

我使用vhdl实现了一个设计,该设计基于时钟触发,该时钟根据sel输入将一个输入信号发送到8个输出通道中的一个,同时还发送另一个2位输入。详细的设计显示了很多嵌套,因为有很多if- The语句。因此,我很好奇是否有一种方法可以减轻使用case语句或其他方法的嵌套。我不熟悉用case语句来做这件事,因为我有两个决定输出通道的输入。下面显示了我目前拥有的代码。

代码语言:javascript
复制
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;


--Inputs and outputs to entity 
entity DSA_Worker is
    Port ( DB_Select : in STD_LOGIC;
           Atten : in STD_LOGIC_VECTOR ( 7 downto 0);
           enable : in STD_LOGIC;
           clk: in STD_LOGIC;
           reset: in STD_LOGIC;
           chip_select : in STD_LOGIC_VECTOR (1 downto 0);
           DBA_TX1_DSA : out STD_LOGIC_VECTOR (7 downto 0);
           DBA_TX2_DSA : out STD_LOGIC_VECTOR (7 downto 0);
           DBA_RX1_DSA : out STD_LOGIC_VECTOR (7 downto 0);
           DBA_RX2_DSA : out STD_LOGIC_VECTOR (7 downto 0);
           DBB_TX1_DSA : out STD_LOGIC_VECTOR (7 downto 0);
           DBB_TX2_DSA : out STD_LOGIC_VECTOR (7 downto 0);
           DBB_RX1_DSA : out STD_LOGIC_VECTOR (7 downto 0);
           DBB_RX2_DSA : out STD_LOGIC_VECTOR (7 downto 0));
end DSA_Worker;

architecture Behavioral of DSA_Worker is

begin
process(clk)
begin
  if rising_edge(clk) then
  --if reset is high, all outputs go to 0
     if reset = '1'then
       DBA_TX1_DSA <= (others =>'0');
       DBA_TX2_DSA <= (others =>'0');
       DBA_RX1_DSA <= (others =>'0');
       DBA_RX2_DSA <= (others =>'0');
       DBB_TX1_DSA <= (others =>'0');
       DBB_TX2_DSA <= (others =>'0');
       DBB_RX1_DSA <= (others =>'0');
       DBB_RX2_DSA <= (others =>'0');
        
          
      -- attenuation values sent to channels based on DB_select value(0/1) and chip select value
       --DB_select - 0 is for DB-A and 1 for DB- B and chip_select determines the channel 
       elsif enable = '1'then
             if(DB_Select='0' and chip_select = "00") then -- attenuation value sent to first channel
             DBA_TX1_DSA(0) <= Atten(0);
             DBA_TX1_DSA(1) <= Atten(1);
             DBA_TX1_DSA(2) <= Atten(2);
             DBA_TX1_DSA(3) <= Atten(3);
             DBA_TX1_DSA(4) <= Atten(4);
             DBA_TX1_DSA(5) <= Atten(5);

             elsif (DB_Select='0' and chip_select = "01") then 
             DBA_TX2_DSA(0) <= Atten(0);
             DBA_TX2_DSA(1) <= Atten(1);
             DBA_TX2_DSA(2) <= Atten(2);
             DBA_TX2_DSA(3) <= Atten(3);
             DBA_TX2_DSA(4) <= Atten(4);
             DBA_TX2_DSA(5) <= Atten(5);
        
             elsif (DB_Select='0' and chip_select = "10") then
             DBA_RX1_DSA(0) <= Atten(0);
             DBA_RX1_DSA(1) <= Atten(1);
             DBA_RX1_DSA(2) <= Atten(2);
             DBA_RX1_DSA(3) <= Atten(3);
             DBA_RX1_DSA(4) <= Atten(4);
             DBA_RX1_DSA(5) <= Atten(5);
  
            elsif (DB_Select='0' and chip_select = "11") then
            DBA_RX2_DSA(0) <= Atten(0);
            DBA_RX2_DSA(1) <= Atten(1);
            DBA_RX2_DSA(2) <= Atten(2);
            DBA_RX2_DSA(3) <= Atten(3);
            DBA_RX2_DSA(4) <= Atten(4);
            DBA_RX2_DSA(5) <= Atten(5);
      
            -- Attenuation values being set for DB-B
            elsif (DB_Select='1' and chip_select = "00") then 
            DBB_TX1_DSA(0) <= Atten(0);
            DBB_TX1_DSA(1) <= Atten(1);
            DBB_TX1_DSA(2) <= Atten(2);
            DBB_TX1_DSA(3) <= Atten(3);
            DBB_TX1_DSA(4) <= Atten(4);
            DBB_TX1_DSA(5) <= Atten(5);
       
            elsif (DB_Select='1' and chip_select = "01") then 
            DBB_TX2_DSA(0) <= Atten(0);
            DBB_TX2_DSA(1) <= Atten(1);
            DBB_TX2_DSA(2) <= Atten(2);
            DBB_TX2_DSA(3) <= Atten(3);
            DBB_TX2_DSA(4) <= Atten(4);
            DBB_TX2_DSA(5) <= Atten(5);
 
            elsif (DB_Select='1' and chip_select = "10") then 
            DBB_RX1_DSA(0) <= Atten(0);
            DBB_RX1_DSA(1) <= Atten(1);
            DBB_RX1_DSA(2) <= Atten(2);
            DBB_RX1_DSA(3) <= Atten(3);
            DBB_RX1_DSA(4) <= Atten(4);
            DBB_RX1_DSA(5) <= Atten(5);
       
         else 
         DBB_RX2_DSA(0) <= Atten(0);
         DBB_RX2_DSA(1) <= Atten(1);
         DBB_RX2_DSA(2) <= Atten(2);
         DBB_RX2_DSA(3) <= Atten(3);
         DBB_RX2_DSA(4) <= Atten(4);
         DBB_RX2_DSA(5) <= Atten(5);
            
            end if; 
        end if;
     end if;

end process;

end Behavioral;

我确实尝试过使用case语句生成一个简化的设计,如下所示

代码语言:javascript
复制
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;

-- Uncomment the following library declaration if using
-- arithmetic functions with Signed or Unsigned values
--use IEEE.NUMERIC_STD.ALL;

-- Uncomment the following library declaration if instantiating
-- any Xilinx leaf cells in this code.
--library UNISIM;
--use UNISIM.VComponents.all;

entity dsa_case is
   Port ( 
           DB_Select : in STD_LOGIC;
           Atten : in STD_LOGIC_VECTOR ( 7 downto 0);
           enable : in STD_LOGIC;
           clk: in STD_LOGIC;
           reset: in STD_LOGIC;
           chip_select : in STD_LOGIC_VECTOR (1 downto 0);
           DBA_TX1_DSA : out STD_LOGIC_VECTOR (7 downto 0);
           DBA_TX2_DSA : out STD_LOGIC_VECTOR (7 downto 0);
           DBA_RX1_DSA : out STD_LOGIC_VECTOR (7 downto 0);
           DBA_RX2_DSA : out STD_LOGIC_VECTOR (7 downto 0);
           DBB_TX1_DSA : out STD_LOGIC_VECTOR (7 downto 0);
           DBB_TX2_DSA : out STD_LOGIC_VECTOR (7 downto 0);
           DBB_RX1_DSA : out STD_LOGIC_VECTOR (7 downto 0);
           DBB_RX2_DSA : out STD_LOGIC_VECTOR (7 downto 0));
end dsa_case;

architecture Behavioral of dsa_case is

begin

process(clk)
begin

    if rising_edge(clk) then
       if reset = '1' then
        DBA_TX1_DSA <= (others =>'0');
        DBA_TX2_DSA <= (others =>'0');
        DBA_RX1_DSA <= (others =>'0');
        DBA_RX2_DSA <= (others =>'0');
        DBB_TX1_DSA <= (others =>'0');
        DBB_TX2_DSA <= (others =>'0');
        DBB_RX1_DSA <= (others =>'0');
        DBB_RX2_DSA <= (others =>'0');
       
       
     elsif enable = '1'then
        --    DB_Select <='0';
            case chip_select is
             when "00"=>   -- attenuation value sent to first channel
             DBA_TX1_DSA(0) <= Atten(0);
             DBA_TX1_DSA(1) <= Atten(1);
             DBA_TX1_DSA(2) <= Atten(2);
             DBA_TX1_DSA(3) <= Atten(3);
             DBA_TX1_DSA(4) <= Atten(4);
             DBA_TX1_DSA(5) <= Atten(5);

             when "01"=>
             DBA_TX2_DSA(0) <= Atten(0);
             DBA_TX2_DSA(1) <= Atten(1);
             DBA_TX2_DSA(2) <= Atten(2);
             DBA_TX2_DSA(3) <= Atten(3);
             DBA_TX2_DSA(4) <= Atten(4);
             DBA_TX2_DSA(5) <= Atten(5);
        
            when "10"=>
             DBA_RX1_DSA(0) <= Atten(0);
             DBA_RX1_DSA(1) <= Atten(1);
             DBA_RX1_DSA(2) <= Atten(2);
             DBA_RX1_DSA(3) <= Atten(3);
             DBA_RX1_DSA(4) <= Atten(4);
             DBA_RX1_DSA(5) <= Atten(5);
  
            when "11"=>
            DBA_RX2_DSA(0) <= Atten(0);
            DBA_RX2_DSA(1) <= Atten(1);
            DBA_RX2_DSA(2) <= Atten(2);
            DBA_RX2_DSA(3) <= Atten(3);
            DBA_RX2_DSA(4) <= Atten(4);
            DBA_RX2_DSA(5) <= Atten(5);
      
            -- Attenuation values being set for DB-B
      --      DB_Select <= '1';
            when "00"=>
            DBB_TX1_DSA(0) <= Atten(0);
            DBB_TX1_DSA(1) <= Atten(1);
            DBB_TX1_DSA(2) <= Atten(2);
            DBB_TX1_DSA(3) <= Atten(3);
            DBB_TX1_DSA(4) <= Atten(4);
            DBB_TX1_DSA(5) <= Atten(5);
       
      --      DB_Select <= '1';
            when "01" =>
            DBB_TX2_DSA(0) <= Atten(0);
            DBB_TX2_DSA(1) <= Atten(1);
            DBB_TX2_DSA(2) <= Atten(2);
            DBB_TX2_DSA(3) <= Atten(3);
            DBB_TX2_DSA(4) <= Atten(4);
            DBB_TX2_DSA(5) <= Atten(5);
 
     --       DB_Select <= '1';
            when "10"=> 
            DBB_RX1_DSA(0) <= Atten(0);
            DBB_RX1_DSA(1) <= Atten(1);
            DBB_RX1_DSA(2) <= Atten(2);
            DBB_RX1_DSA(3) <= Atten(3);
            DBB_RX1_DSA(4) <= Atten(4);
            DBB_RX1_DSA(5) <= Atten(5);
       
         when others=>
         DBB_RX2_DSA(0) <= Atten(0);
         DBB_RX2_DSA(1) <= Atten(1);
         DBB_RX2_DSA(2) <= Atten(2);
         DBB_RX2_DSA(3) <= Atten(3);
         DBB_RX2_DSA(4) <= Atten(4);
         DBB_RX2_DSA(5) <= Atten(5);
         
        end case;
        
      end if;
    end if; 
 end process;


end Behavioral;

然而,由于5个错误,它没有产生详细的设计,所有这些都是这样。

代码语言:javascript
复制
[Synth 8-517] overlapping choice 2'b00 in case statement ["/home/n310-osp/case_statement_design/case_statement_design.srcs/sources_1/new/dsa_case.vhd":108]
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-06-02 09:05:25

就我个人而言,我不介意你的如果-否则的结构。我认为大多数情况下都存在可读性问题,存在大量冗余(在本例中,每种情况下对DB_Select的检查)和不一致的缩进。

这就是我如何改进process内部的代码

代码语言:javascript
复制
process(clk)
begin
  if rising_edge(clk) then
    --if reset is high, all outputs go to 0
    if reset = '1' then
      DBA_TX1_DSA <= (others=>'0');
      DBA_TX2_DSA <= (others=>'0');
      DBA_RX1_DSA <= (others=>'0');
      DBA_RX2_DSA <= (others=>'0');
      DBB_TX1_DSA <= (others=>'0');
      DBB_TX2_DSA <= (others=>'0');
      DBB_RX1_DSA <= (others=>'0');
      DBB_RX2_DSA <= (others=>'0');
         
    -- attenuation values sent to channels based on DB_select value(0/1) and chip select value
    -- DB_select - 0 is for DB-A and 1 for DB- B and chip_select determines the channel 
    elsif enable = '1'then
      if DB_Select = '0' then
        if chip_select = "00" then -- attenuation value sent to first channel
          DBA_TX1_DSA(5 downto 0) <= Atten(5 downto 0);
        elsif chip_select = "01" then 
          DBA_TX2_DSA(5 downto 0) <= Atten(5 downto 0);
        elsif chip_select = "10" then
          DBA_RX1_DSA(5 downto 0) <= Atten(5 downto 0);
        else
          DBA_RX2_DSA(5 downto 0) <= Atten(5 downto 0);
        end if;
      else -- Attenuation values being set for DB-B
        if chip_select = "00" then 
          DBB_TX1_DSA(5 downto 0) <= Atten(5 downto 0);
        elsif chip_select = "01" then 
          DBB_TX2_DSA(5 downto 0) <= Atten(5 downto 0);
        elsif chip_select = "10" then 
          DBB_RX1_DSA(5 downto 0) <= Atten(5 downto 0);
        else 
          DBB_RX2_DSA(5 downto 0) <= Atten(5 downto 0);
        end if;
      end if;
    end if;
  end if;
end process;

end Behavioral;

你可以用时间替代if-else结构,但这只是一个优先考虑的问题。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/67797442

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档