我使用vhdl实现了一个设计,该设计基于时钟触发,该时钟根据sel输入将一个输入信号发送到8个输出通道中的一个,同时还发送另一个2位输入。详细的设计显示了很多嵌套,因为有很多if- The语句。因此,我很好奇是否有一种方法可以减轻使用case语句或其他方法的嵌套。我不熟悉用case语句来做这件事,因为我有两个决定输出通道的输入。下面显示了我目前拥有的代码。
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语句生成一个简化的设计,如下所示
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个错误,它没有产生详细的设计,所有这些都是这样。
[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]发布于 2021-06-02 09:05:25
就我个人而言,我不介意你的如果-否则的结构。我认为大多数情况下都存在可读性问题,存在大量冗余(在本例中,每种情况下对DB_Select的检查)和不一致的缩进。
这就是我如何改进process内部的代码
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结构,但这只是一个优先考虑的问题。
https://stackoverflow.com/questions/67797442
复制相似问题